Compare commits
1 Commits
cd262da8b1
...
develop
Author | SHA1 | Date | |
---|---|---|---|
|
21c2c3a2ef |
4
.gitignore
vendored
@@ -5,3 +5,7 @@
|
||||
.project
|
||||
.factorypath
|
||||
.settings/
|
||||
/frontend/src/.umi
|
||||
/frontend/src/.umi-production
|
||||
/frontend/src/node_modules
|
||||
/frontend/dist
|
16
frontend/.editorconfig
Normal file
@@ -0,0 +1,16 @@
|
||||
# http://editorconfig.org
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
8
frontend/.eslintignore
Normal file
@@ -0,0 +1,8 @@
|
||||
/lambda/
|
||||
/scripts
|
||||
/config
|
||||
.history
|
||||
public
|
||||
dist
|
||||
.umi
|
||||
mock
|
8
frontend/.eslintrc.js
Normal file
@@ -0,0 +1,8 @@
|
||||
module.exports = {
|
||||
extends: [require.resolve('@umijs/fabric/dist/eslint')],
|
||||
globals: {
|
||||
ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: true,
|
||||
page: true,
|
||||
REACT_APP_ENV: true,
|
||||
},
|
||||
};
|
23
frontend/.gitignore
vendored
@@ -1,23 +0,0 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
23
frontend/.prettierignore
Normal file
@@ -0,0 +1,23 @@
|
||||
**/*.svg
|
||||
package.json
|
||||
.umi
|
||||
.umi-production
|
||||
/dist
|
||||
.dockerignore
|
||||
.DS_Store
|
||||
.eslintignore
|
||||
*.png
|
||||
*.toml
|
||||
docker
|
||||
.editorconfig
|
||||
Dockerfile*
|
||||
.gitignore
|
||||
.prettierignore
|
||||
LICENSE
|
||||
.eslintcache
|
||||
*.lock
|
||||
yarn-error.log
|
||||
.history
|
||||
CNAME
|
||||
/build
|
||||
/public
|
5
frontend/.prettierrc.js
Normal file
@@ -0,0 +1,5 @@
|
||||
const fabric = require('@umijs/fabric');
|
||||
|
||||
module.exports = {
|
||||
...fabric.prettier,
|
||||
};
|
5
frontend/.stylelintrc.js
Normal file
@@ -0,0 +1,5 @@
|
||||
const fabric = require('@umijs/fabric');
|
||||
|
||||
module.exports = {
|
||||
...fabric.stylelint,
|
||||
};
|
57
frontend/README.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Ant Design Pro
|
||||
|
||||
This project is initialized with [Ant Design Pro](https://pro.ant.design). Follow is the quick guide for how to use.
|
||||
|
||||
## Environment Prepare
|
||||
|
||||
Install `node_modules`:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```bash
|
||||
yarn
|
||||
```
|
||||
|
||||
## Provided Scripts
|
||||
|
||||
Ant Design Pro provides some useful script to help you quick start and build with web project, code style check and test.
|
||||
|
||||
Scripts provided in `package.json`. It's safe to modify or add additional script:
|
||||
|
||||
### Start project
|
||||
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
||||
### Build project
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Check code style
|
||||
|
||||
```bash
|
||||
npm run lint
|
||||
```
|
||||
|
||||
You can also use script to auto fix some lint error:
|
||||
|
||||
```bash
|
||||
npm run lint:fix
|
||||
```
|
||||
|
||||
### Test code
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
## More
|
||||
|
||||
You can view full document on our [official website](https://pro.ant.design). And welcome any feedback in our [github](https://github.com/ant-design/ant-design-pro).
|
14
frontend/config/config.dev.js
Normal file
@@ -0,0 +1,14 @@
|
||||
// https://umijs.org/config/
|
||||
import { defineConfig } from 'umi';
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
// https://github.com/zthxxx/react-dev-inspector
|
||||
'react-dev-inspector/plugins/umi/react-inspector',
|
||||
],
|
||||
// https://github.com/zthxxx/react-dev-inspector#inspector-loader-props
|
||||
inspectorConfig: {
|
||||
exclude: [],
|
||||
babelPlugins: [],
|
||||
babelOptions: {},
|
||||
},
|
||||
});
|
353
frontend/config/config.js
Normal file
@@ -0,0 +1,353 @@
|
||||
// https://umijs.org/config/
|
||||
import { defineConfig } from 'umi';
|
||||
import { join } from 'path';
|
||||
import defaultSettings from './defaultSettings';
|
||||
import proxy from './proxy';
|
||||
const { REACT_APP_ENV } = process.env;
|
||||
export default defineConfig({
|
||||
hash: true,
|
||||
antd: {},
|
||||
dva: {
|
||||
hmr: true,
|
||||
},
|
||||
layout: {
|
||||
// https://umijs.org/zh-CN/plugins/plugin-layout
|
||||
locale: true,
|
||||
siderWidth: 208,
|
||||
...defaultSettings,
|
||||
},
|
||||
// https://umijs.org/zh-CN/plugins/plugin-locale
|
||||
locale: {
|
||||
// default zh-CN
|
||||
default: 'zh-CN',
|
||||
antd: true,
|
||||
// default true, when it is true, will use `navigator.language` overwrite default
|
||||
baseNavigator: true,
|
||||
},
|
||||
dynamicImport: {
|
||||
loading: '@ant-design/pro-layout/es/PageLoading',
|
||||
},
|
||||
targets: {
|
||||
ie: 11,
|
||||
},
|
||||
// umi routes: https://umijs.org/docs/routing
|
||||
routes: [
|
||||
// {
|
||||
// path: '/user',
|
||||
// layout: false,
|
||||
// routes: [
|
||||
// // {
|
||||
// // path: '/user/login',
|
||||
// // layout: false,
|
||||
// // name: 'login',
|
||||
// // component: './user/Login',
|
||||
// // },
|
||||
// // {
|
||||
// // path: '/user',
|
||||
// // redirect: '/user/login',
|
||||
// // },
|
||||
// {
|
||||
// name: 'register-result',
|
||||
// icon: 'smile',
|
||||
// path: '/user/register-result',
|
||||
// component: './user/register-result',
|
||||
// },
|
||||
// {
|
||||
// name: 'register',
|
||||
// icon: 'smile',
|
||||
// path: '/user/register',
|
||||
// component: './user/register',
|
||||
// },
|
||||
// {
|
||||
// component: '404',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
{
|
||||
path: '/dashboard',
|
||||
name: 'dashboard',
|
||||
icon: 'dashboard',
|
||||
routes: [
|
||||
{
|
||||
path: '/dashboard',
|
||||
redirect: '/dashboard/analysis',
|
||||
},
|
||||
{
|
||||
name: 'analysis',
|
||||
icon: 'smile',
|
||||
path: '/dashboard/analysis',
|
||||
component: './dashboard/analysis',
|
||||
},
|
||||
// {
|
||||
// name: 'monitor',
|
||||
// icon: 'smile',
|
||||
// path: '/dashboard/monitor',
|
||||
// component: './dashboard/monitor',
|
||||
// },
|
||||
// {
|
||||
// name: 'workplace',
|
||||
// icon: 'smile',
|
||||
// path: '/dashboard/workplace',
|
||||
// component: './dashboard/workplace',
|
||||
// },
|
||||
],
|
||||
},
|
||||
// {
|
||||
// path: '/form',
|
||||
// icon: 'form',
|
||||
// name: 'form',
|
||||
// routes: [
|
||||
// {
|
||||
// path: '/form',
|
||||
// redirect: '/form/basic-form',
|
||||
// },
|
||||
// {
|
||||
// name: 'basic-form',
|
||||
// icon: 'smile',
|
||||
// path: '/form/basic-form',
|
||||
// component: './form/basic-form',
|
||||
// },
|
||||
// {
|
||||
// name: 'step-form',
|
||||
// icon: 'smile',
|
||||
// path: '/form/step-form',
|
||||
// component: './form/step-form',
|
||||
// },
|
||||
// {
|
||||
// name: 'advanced-form',
|
||||
// icon: 'smile',
|
||||
// path: '/form/advanced-form',
|
||||
// component: './form/advanced-form',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
{
|
||||
path: '/list',
|
||||
icon: 'table',
|
||||
name: 'list',
|
||||
routes: [
|
||||
// {
|
||||
// path: '/list/search',
|
||||
// name: 'search-list',
|
||||
// component: './list/search',
|
||||
// routes: [
|
||||
// {
|
||||
// path: '/list/search',
|
||||
// redirect: '/list/search/articles',
|
||||
// },
|
||||
// {
|
||||
// name: 'articles',
|
||||
// icon: 'smile',
|
||||
// path: '/list/search/articles',
|
||||
// component: './list/search/articles',
|
||||
// },
|
||||
// {
|
||||
// name: 'projects',
|
||||
// icon: 'smile',
|
||||
// path: '/list/search/projects',
|
||||
// component: './list/search/projects',
|
||||
// },
|
||||
// {
|
||||
// name: 'applications',
|
||||
// icon: 'smile',
|
||||
// path: '/list/search/applications',
|
||||
// component: './list/search/applications',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
|
||||
// path: '/list',
|
||||
// redirect: '/list/table-list',
|
||||
// },
|
||||
{
|
||||
name: 'cluster',
|
||||
icon: 'smile',
|
||||
path: '/list/table-list',
|
||||
component: './list/table-list',
|
||||
},
|
||||
// {
|
||||
// name: 'basic-list',
|
||||
// icon: 'smile',
|
||||
// path: '/list/basic-list',
|
||||
// component: './list/basic-list',
|
||||
// },
|
||||
// {
|
||||
// name: 'card-list',
|
||||
// icon: 'smile',
|
||||
// path: '/list/card-list',
|
||||
// component: './list/card-list',
|
||||
// },
|
||||
],
|
||||
},
|
||||
// {
|
||||
// path: '/profile',
|
||||
// name: 'profile',
|
||||
// icon: 'profile',
|
||||
// routes: [
|
||||
// {
|
||||
// path: '/profile',
|
||||
// redirect: '/profile/basic',
|
||||
// },
|
||||
// {
|
||||
// name: 'basic',
|
||||
// icon: 'smile',
|
||||
// path: '/profile/basic',
|
||||
// component: './profile/basic',
|
||||
// },
|
||||
// {
|
||||
// name: 'advanced',
|
||||
// icon: 'smile',
|
||||
// path: '/profile/advanced',
|
||||
// component: './profile/advanced',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// name: 'result',
|
||||
// icon: 'CheckCircleOutlined',
|
||||
// path: '/result',
|
||||
// routes: [
|
||||
// {
|
||||
// path: '/result',
|
||||
// redirect: '/result/success',
|
||||
// },
|
||||
// {
|
||||
// name: 'success',
|
||||
// icon: 'smile',
|
||||
// path: '/result/success',
|
||||
// component: './result/success',
|
||||
// },
|
||||
// {
|
||||
// name: 'fail',
|
||||
// icon: 'smile',
|
||||
// path: '/result/fail',
|
||||
// component: './result/fail',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// name: 'exception',
|
||||
// icon: 'warning',
|
||||
// path: '/exception',
|
||||
// routes: [
|
||||
// {
|
||||
// path: '/exception',
|
||||
// redirect: '/exception/403',
|
||||
// },
|
||||
// {
|
||||
// name: '403',
|
||||
// icon: 'smile',
|
||||
// path: '/exception/403',
|
||||
// component: './exception/403',
|
||||
// },
|
||||
// {
|
||||
// name: '404',
|
||||
// icon: 'smile',
|
||||
// path: '/exception/404',
|
||||
// component: './exception/404',
|
||||
// },
|
||||
// {
|
||||
// name: '500',
|
||||
// icon: 'smile',
|
||||
// path: '/exception/500',
|
||||
// component: './exception/500',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// name: 'account',
|
||||
// icon: 'user',
|
||||
// path: '/account',
|
||||
// routes: [
|
||||
// {
|
||||
// path: '/account',
|
||||
// redirect: '/account/center',
|
||||
// },
|
||||
// {
|
||||
// name: 'center',
|
||||
// icon: 'smile',
|
||||
// path: '/account/center',
|
||||
// component: './account/center',
|
||||
// },
|
||||
// {
|
||||
// name: 'settings',
|
||||
// icon: 'smile',
|
||||
// path: '/account/settings',
|
||||
// component: './account/settings',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
// {
|
||||
// name: 'editor',
|
||||
// icon: 'highlight',
|
||||
// path: '/editor',
|
||||
// routes: [
|
||||
// {
|
||||
// path: '/editor',
|
||||
// redirect: '/editor/flow',
|
||||
// },
|
||||
// {
|
||||
// name: 'flow',
|
||||
// icon: 'smile',
|
||||
// path: '/editor/flow',
|
||||
// component: './editor/flow',
|
||||
// },
|
||||
// {
|
||||
// name: 'mind',
|
||||
// icon: 'smile',
|
||||
// path: '/editor/mind',
|
||||
// component: './editor/mind',
|
||||
// },
|
||||
// {
|
||||
// name: 'koni',
|
||||
// icon: 'smile',
|
||||
// path: '/editor/koni',
|
||||
// component: './editor/koni',
|
||||
// },
|
||||
// ],
|
||||
// },
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/dashboard/analysis',
|
||||
},
|
||||
{
|
||||
component: '404',
|
||||
},
|
||||
],
|
||||
// Theme for antd: https://ant.design/docs/react/customize-theme-cn
|
||||
theme: {
|
||||
'primary-color': defaultSettings.primaryColor,
|
||||
},
|
||||
// esbuild is father build tools
|
||||
// https://umijs.org/plugins/plugin-esbuild
|
||||
esbuild: {},
|
||||
title: false,
|
||||
ignoreMomentLocale: true,
|
||||
proxy: proxy[REACT_APP_ENV || 'dev'],
|
||||
manifest: {
|
||||
basePath: '/',
|
||||
},
|
||||
// Fast Refresh 热更新
|
||||
fastRefresh: {},
|
||||
openAPI: [
|
||||
{
|
||||
requestLibPath: "import { request } from 'umi'",
|
||||
// 或者使用在线的版本
|
||||
// schemaPath: "https://gw.alipayobjects.com/os/antfincdn/M%24jrzTTYJN/oneapi.json"
|
||||
schemaPath: join(__dirname, 'oneapi.json'),
|
||||
mock: false,
|
||||
},
|
||||
{
|
||||
requestLibPath: "import { request } from 'umi'",
|
||||
schemaPath: 'https://gw.alipayobjects.com/os/antfincdn/CA1dOm%2631B/openapi.json',
|
||||
projectName: 'swagger',
|
||||
},
|
||||
],
|
||||
nodeModulesTransform: {
|
||||
type: 'none',
|
||||
},
|
||||
mfsu: {},
|
||||
webpack5: {},
|
||||
exportStatic: {},
|
||||
});
|
15
frontend/config/defaultSettings.js
Normal file
@@ -0,0 +1,15 @@
|
||||
const Settings = {
|
||||
navTheme: 'light',
|
||||
// 拂晓蓝
|
||||
primaryColor: '#1890ff',
|
||||
layout: 'mix',
|
||||
contentWidth: 'Fluid',
|
||||
fixedHeader: false,
|
||||
fixSiderbar: true,
|
||||
colorWeak: false,
|
||||
title: 'RocketMQ-Dashboard',
|
||||
pwa: false,
|
||||
// logo: 'https://gw.alipayobjects.com/zos/rmsportal/KDpgvguMpGfqaHPjicRK.svg',
|
||||
iconfontUrl: '',
|
||||
};
|
||||
export default Settings;
|
593
frontend/config/oneapi.json
Normal file
@@ -0,0 +1,593 @@
|
||||
{
|
||||
"openapi": "3.0.1",
|
||||
"info": {
|
||||
"title": "Ant Design Pro",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
"url": "http://localhost:8000/"
|
||||
},
|
||||
{
|
||||
"url": "https://localhost:8000/"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"/api/currentUser": {
|
||||
"get": {
|
||||
"tags": ["api"],
|
||||
"description": "获取当前的用户",
|
||||
"operationId": "currentUser",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/CurrentUser"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-swagger-router-controller": "api"
|
||||
},
|
||||
"/api/login/captcha": {
|
||||
"post": {
|
||||
"description": "发送验证码",
|
||||
"operationId": "getFakeCaptcha",
|
||||
"tags": ["login"],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "phone",
|
||||
"in": "query",
|
||||
"description": "手机号",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/FakeCaptcha"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/login/outLogin": {
|
||||
"post": {
|
||||
"description": "登录接口",
|
||||
"operationId": "outLogin",
|
||||
"tags": ["login"],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-swagger-router-controller": "api"
|
||||
},
|
||||
"/api/login/account": {
|
||||
"post": {
|
||||
"tags": ["login"],
|
||||
"description": "登录接口",
|
||||
"operationId": "login",
|
||||
"requestBody": {
|
||||
"description": "登录系统",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/LoginParams"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/LoginResult"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-codegen-request-body-name": "body"
|
||||
},
|
||||
"x-swagger-router-controller": "api"
|
||||
},
|
||||
"/api/notices": {
|
||||
"summary": "getNotices",
|
||||
"description": "NoticeIconItem",
|
||||
"get": {
|
||||
"tags": ["api"],
|
||||
"operationId": "getNotices",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/NoticeIconList"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/rule": {
|
||||
"get": {
|
||||
"tags": ["rule"],
|
||||
"description": "获取规则列表",
|
||||
"operationId": "rule",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "current",
|
||||
"in": "query",
|
||||
"description": "当前的页码",
|
||||
"schema": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "pageSize",
|
||||
"in": "query",
|
||||
"description": "页面的容量",
|
||||
"schema": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/RuleList"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"tags": ["rule"],
|
||||
"description": "新建规则",
|
||||
"operationId": "addRule",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/RuleListItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"tags": ["rule"],
|
||||
"description": "新建规则",
|
||||
"operationId": "updateRule",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/RuleListItem"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"delete": {
|
||||
"tags": ["rule"],
|
||||
"description": "删除规则",
|
||||
"operationId": "removeRule",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Success",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Error",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/ErrorResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-swagger-router-controller": "api"
|
||||
},
|
||||
"/swagger": {
|
||||
"x-swagger-pipe": "swagger_raw"
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"CurrentUser": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"avatar": {
|
||||
"type": "string"
|
||||
},
|
||||
"userid": {
|
||||
"type": "string"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"signature": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"group": {
|
||||
"type": "string"
|
||||
},
|
||||
"tags": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "string"
|
||||
},
|
||||
"label": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"notifyCount": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"unreadCount": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"country": {
|
||||
"type": "string"
|
||||
},
|
||||
"access": {
|
||||
"type": "string"
|
||||
},
|
||||
"geographic": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"province": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"key": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"city": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"label": {
|
||||
"type": "string"
|
||||
},
|
||||
"key": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"address": {
|
||||
"type": "string"
|
||||
},
|
||||
"phone": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"LoginResult": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
},
|
||||
"currentAuthority": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"PageParams": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"current": {
|
||||
"type": "number"
|
||||
},
|
||||
"pageSize": {
|
||||
"type": "number"
|
||||
}
|
||||
}
|
||||
},
|
||||
"RuleListItem": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"key": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"disabled": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"href": {
|
||||
"type": "string"
|
||||
},
|
||||
"avatar": {
|
||||
"type": "string"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"owner": {
|
||||
"type": "string"
|
||||
},
|
||||
"desc": {
|
||||
"type": "string"
|
||||
},
|
||||
"callNo": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"status": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"updatedAt": {
|
||||
"type": "string",
|
||||
"format": "datetime"
|
||||
},
|
||||
"createdAt": {
|
||||
"type": "string",
|
||||
"format": "datetime"
|
||||
},
|
||||
"progress": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
}
|
||||
}
|
||||
},
|
||||
"RuleList": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/RuleListItem"
|
||||
}
|
||||
},
|
||||
"total": {
|
||||
"type": "integer",
|
||||
"description": "列表的内容总数",
|
||||
"format": "int32"
|
||||
},
|
||||
"success": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"FakeCaptcha": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"code": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"LoginParams": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"username": {
|
||||
"type": "string"
|
||||
},
|
||||
"password": {
|
||||
"type": "string"
|
||||
},
|
||||
"autoLogin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"type": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ErrorResponse": {
|
||||
"required": ["errorCode"],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"errorCode": {
|
||||
"type": "string",
|
||||
"description": "业务约定的错误码"
|
||||
},
|
||||
"errorMessage": {
|
||||
"type": "string",
|
||||
"description": "业务上的错误信息"
|
||||
},
|
||||
"success": {
|
||||
"type": "boolean",
|
||||
"description": "业务上的请求是否成功"
|
||||
}
|
||||
}
|
||||
},
|
||||
"NoticeIconList": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/NoticeIconItem"
|
||||
}
|
||||
},
|
||||
"total": {
|
||||
"type": "integer",
|
||||
"description": "列表的内容总数",
|
||||
"format": "int32"
|
||||
},
|
||||
"success": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
},
|
||||
"NoticeIconItemType": {
|
||||
"title": "NoticeIconItemType",
|
||||
"description": "已读未读列表的枚举",
|
||||
"type": "string",
|
||||
"properties": {},
|
||||
"enum": ["notification", "message", "event"]
|
||||
},
|
||||
"NoticeIconItem": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"extra": {
|
||||
"type": "string",
|
||||
"format": "any"
|
||||
},
|
||||
"key": { "type": "string" },
|
||||
"read": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"avatar": {
|
||||
"type": "string"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"type": "string"
|
||||
},
|
||||
"datetime": {
|
||||
"type": "string",
|
||||
"format": "date"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"extensions": {
|
||||
"x-is-enum": true
|
||||
},
|
||||
"$ref": "#/components/schemas/NoticeIconItemType"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
37
frontend/config/proxy.js
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* 在生产环境 代理是无法生效的,所以这里没有生产环境的配置
|
||||
* -------------------------------
|
||||
* The agent cannot take effect in the production environment
|
||||
* so there is no configuration of the production environment
|
||||
* For details, please see
|
||||
* https://pro.ant.design/docs/deploy
|
||||
*/
|
||||
export default {
|
||||
dev: {
|
||||
'/api/': {
|
||||
target: 'http://101.201.65.66:8080/',
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
'/api': '',
|
||||
},
|
||||
},
|
||||
},
|
||||
test: {
|
||||
'/api/': {
|
||||
target: 'https://preview.pro.ant.design',
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
'^': '',
|
||||
},
|
||||
},
|
||||
},
|
||||
pre: {
|
||||
'/api/': {
|
||||
target: 'your pre url',
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
'^': '',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
58
frontend/config/routes.js
Normal file
@@ -0,0 +1,58 @@
|
||||
export default [
|
||||
{
|
||||
path: '/user',
|
||||
layout: false,
|
||||
routes: [
|
||||
{
|
||||
path: '/user',
|
||||
routes: [
|
||||
{
|
||||
name: 'login',
|
||||
path: '/user/login',
|
||||
component: './user/Login',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
component: './404',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/welcome',
|
||||
name: 'welcome',
|
||||
icon: 'smile',
|
||||
component: './Welcome',
|
||||
},
|
||||
{
|
||||
path: '/admin',
|
||||
name: 'admin',
|
||||
icon: 'crown',
|
||||
access: 'canAdmin',
|
||||
component: './Admin',
|
||||
routes: [
|
||||
{
|
||||
path: '/admin/sub-page',
|
||||
name: 'sub-page',
|
||||
icon: 'smile',
|
||||
component: './Welcome',
|
||||
},
|
||||
{
|
||||
component: './404',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'list.table-list',
|
||||
icon: 'table',
|
||||
path: '/list',
|
||||
component: './TableList',
|
||||
},
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/welcome',
|
||||
},
|
||||
{
|
||||
component: './404',
|
||||
},
|
||||
];
|
10
frontend/jest.config.js
Normal file
@@ -0,0 +1,10 @@
|
||||
module.exports = {
|
||||
testURL: 'http://localhost:8000',
|
||||
testEnvironment: './tests/PuppeteerEnvironment',
|
||||
verbose: false,
|
||||
extraSetupFiles: ['./tests/setupTests.js'],
|
||||
globals: {
|
||||
ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION: false,
|
||||
localStorage: null,
|
||||
},
|
||||
};
|
10
frontend/jsconfig.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
}
|
||||
}
|
178
frontend/mock/listTableList.js
Normal file
@@ -0,0 +1,178 @@
|
||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
||||
import moment from 'moment';
|
||||
import { parse } from 'url'; // mock tableListDataSource
|
||||
|
||||
const genList = (current, pageSize) => {
|
||||
const tableListDataSource = [];
|
||||
|
||||
for (let i = 0; i < pageSize; i += 1) {
|
||||
const index = (current - 1) * 10 + i;
|
||||
tableListDataSource.push({
|
||||
key: index,
|
||||
disabled: i % 6 === 0,
|
||||
href: 'https://ant.design',
|
||||
avatar: [
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
|
||||
][i % 2],
|
||||
name: `TradeCode ${index}`,
|
||||
owner: '曲丽丽',
|
||||
desc: '这是一段描述',
|
||||
callNo: Math.floor(Math.random() * 1000),
|
||||
status: Math.floor(Math.random() * 10) % 4,
|
||||
updatedAt: moment().format('YYYY-MM-DD'),
|
||||
createdAt: moment().format('YYYY-MM-DD'),
|
||||
progress: Math.ceil(Math.random() * 100),
|
||||
});
|
||||
}
|
||||
|
||||
tableListDataSource.reverse();
|
||||
return tableListDataSource;
|
||||
};
|
||||
|
||||
let tableListDataSource = genList(1, 100);
|
||||
|
||||
function getRule(req, res, u) {
|
||||
let realUrl = u;
|
||||
|
||||
if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') {
|
||||
realUrl = req.url;
|
||||
}
|
||||
|
||||
const { current = 1, pageSize = 10 } = req.query;
|
||||
const params = parse(realUrl, true).query;
|
||||
let dataSource = [...tableListDataSource].slice((current - 1) * pageSize, current * pageSize);
|
||||
|
||||
if (params.sorter) {
|
||||
const sorter = JSON.parse(params.sorter);
|
||||
dataSource = dataSource.sort((prev, next) => {
|
||||
let sortNumber = 0;
|
||||
Object.keys(sorter).forEach((key) => {
|
||||
if (sorter[key] === 'descend') {
|
||||
if (prev[key] - next[key] > 0) {
|
||||
sortNumber += -1;
|
||||
} else {
|
||||
sortNumber += 1;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (prev[key] - next[key] > 0) {
|
||||
sortNumber += 1;
|
||||
} else {
|
||||
sortNumber += -1;
|
||||
}
|
||||
});
|
||||
return sortNumber;
|
||||
});
|
||||
}
|
||||
|
||||
if (params.filter) {
|
||||
const filter = JSON.parse(params.filter);
|
||||
|
||||
if (Object.keys(filter).length > 0) {
|
||||
dataSource = dataSource.filter((item) => {
|
||||
return Object.keys(filter).some((key) => {
|
||||
if (!filter[key]) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (filter[key].includes(`${item[key]}`)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (params.name) {
|
||||
dataSource = dataSource.filter((data) => data?.name?.includes(params.name || ''));
|
||||
}
|
||||
|
||||
const result = {
|
||||
data: dataSource,
|
||||
total: tableListDataSource.length,
|
||||
success: true,
|
||||
pageSize,
|
||||
current: parseInt(`${params.current}`, 10) || 1,
|
||||
};
|
||||
return res.json(result);
|
||||
}
|
||||
|
||||
function postRule(req, res, u, b) {
|
||||
let realUrl = u;
|
||||
|
||||
if (!realUrl || Object.prototype.toString.call(realUrl) !== '[object String]') {
|
||||
realUrl = req.url;
|
||||
}
|
||||
|
||||
const body = (b && b.body) || req.body;
|
||||
const { method, name, desc, key } = body;
|
||||
|
||||
switch (method) {
|
||||
/* eslint no-case-declarations:0 */
|
||||
case 'delete':
|
||||
tableListDataSource = tableListDataSource.filter((item) => key.indexOf(item.key) === -1);
|
||||
break;
|
||||
|
||||
case 'post':
|
||||
(() => {
|
||||
const i = Math.ceil(Math.random() * 10000);
|
||||
const newRule = {
|
||||
key: tableListDataSource.length,
|
||||
href: 'https://ant.design',
|
||||
avatar: [
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/eeHMaZBwmTvLdIwMfBpg.png',
|
||||
'https://gw.alipayobjects.com/zos/rmsportal/udxAbMEhpwthVVcjLXik.png',
|
||||
][i % 2],
|
||||
name,
|
||||
owner: '曲丽丽',
|
||||
desc,
|
||||
callNo: Math.floor(Math.random() * 1000),
|
||||
status: Math.floor(Math.random() * 10) % 2,
|
||||
updatedAt: moment().format('YYYY-MM-DD'),
|
||||
createdAt: moment().format('YYYY-MM-DD'),
|
||||
progress: Math.ceil(Math.random() * 100),
|
||||
};
|
||||
tableListDataSource.unshift(newRule);
|
||||
return res.json(newRule);
|
||||
})();
|
||||
|
||||
return;
|
||||
|
||||
case 'update':
|
||||
(() => {
|
||||
let newRule = {};
|
||||
tableListDataSource = tableListDataSource.map((item) => {
|
||||
if (item.key === key) {
|
||||
newRule = { ...item, desc, name };
|
||||
return { ...item, desc, name };
|
||||
}
|
||||
|
||||
return item;
|
||||
});
|
||||
return res.json(newRule);
|
||||
})();
|
||||
|
||||
return;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const result = {
|
||||
list: tableListDataSource,
|
||||
pagination: {
|
||||
total: tableListDataSource.length,
|
||||
},
|
||||
};
|
||||
res.json(result);
|
||||
}
|
||||
|
||||
export default {
|
||||
'GET /api/rule': getRule,
|
||||
'POST /api/rule': postRule,
|
||||
};
|
105
frontend/mock/notices.js
Normal file
@@ -0,0 +1,105 @@
|
||||
const getNotices = (req, res) => {
|
||||
res.json({
|
||||
data: [
|
||||
{
|
||||
id: '000000001',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
|
||||
title: '你收到了 14 份新周报',
|
||||
datetime: '2017-08-09',
|
||||
type: 'notification',
|
||||
},
|
||||
{
|
||||
id: '000000002',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png',
|
||||
title: '你推荐的 曲妮妮 已通过第三轮面试',
|
||||
datetime: '2017-08-08',
|
||||
type: 'notification',
|
||||
},
|
||||
{
|
||||
id: '000000003',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png',
|
||||
title: '这种模板可以区分多种通知类型',
|
||||
datetime: '2017-08-07',
|
||||
read: true,
|
||||
type: 'notification',
|
||||
},
|
||||
{
|
||||
id: '000000004',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/GvqBnKhFgObvnSGkDsje.png',
|
||||
title: '左侧图标用于区分不同的类型',
|
||||
datetime: '2017-08-07',
|
||||
type: 'notification',
|
||||
},
|
||||
{
|
||||
id: '000000005',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
|
||||
title: '内容不要超过两行字,超出时自动截断',
|
||||
datetime: '2017-08-07',
|
||||
type: 'notification',
|
||||
},
|
||||
{
|
||||
id: '000000006',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg',
|
||||
title: '曲丽丽 评论了你',
|
||||
description: '描述信息描述信息描述信息',
|
||||
datetime: '2017-08-07',
|
||||
type: 'message',
|
||||
clickClose: true,
|
||||
},
|
||||
{
|
||||
id: '000000007',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg',
|
||||
title: '朱偏右 回复了你',
|
||||
description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像',
|
||||
datetime: '2017-08-07',
|
||||
type: 'message',
|
||||
clickClose: true,
|
||||
},
|
||||
{
|
||||
id: '000000008',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/fcHMVNCjPOsbUGdEduuv.jpeg',
|
||||
title: '标题',
|
||||
description: '这种模板用于提醒谁与你发生了互动,左侧放『谁』的头像',
|
||||
datetime: '2017-08-07',
|
||||
type: 'message',
|
||||
clickClose: true,
|
||||
},
|
||||
{
|
||||
id: '000000009',
|
||||
title: '任务名称',
|
||||
description: '任务需要在 2017-01-12 20:00 前启动',
|
||||
extra: '未开始',
|
||||
status: 'todo',
|
||||
type: 'event',
|
||||
},
|
||||
{
|
||||
id: '000000010',
|
||||
title: '第三方紧急代码变更',
|
||||
description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务',
|
||||
extra: '马上到期',
|
||||
status: 'urgent',
|
||||
type: 'event',
|
||||
},
|
||||
{
|
||||
id: '000000011',
|
||||
title: '信息安全考试',
|
||||
description: '指派竹尔于 2017-01-09 前完成更新并发布',
|
||||
extra: '已耗时 8 天',
|
||||
status: 'doing',
|
||||
type: 'event',
|
||||
},
|
||||
{
|
||||
id: '000000012',
|
||||
title: 'ABCD 版本发布',
|
||||
description: '冠霖提交于 2017-01-06,需在 2017-01-07 前完成代码变更任务',
|
||||
extra: '进行中',
|
||||
status: 'processing',
|
||||
type: 'event',
|
||||
},
|
||||
],
|
||||
});
|
||||
};
|
||||
|
||||
export default {
|
||||
'GET /api/notices': getNotices,
|
||||
};
|
7
frontend/mock/route.js
Normal file
@@ -0,0 +1,7 @@
|
||||
export default {
|
||||
'/api/auth_routes': {
|
||||
'/form/advanced-form': {
|
||||
authority: ['admin', 'user'],
|
||||
},
|
||||
},
|
||||
};
|
210
frontend/mock/user.js
Normal file
@@ -0,0 +1,210 @@
|
||||
const waitTime = (time = 100) => {
|
||||
return new Promise((resolve) => {
|
||||
setTimeout(() => {
|
||||
resolve(true);
|
||||
}, time);
|
||||
});
|
||||
};
|
||||
|
||||
async function getFakeCaptcha(req, res) {
|
||||
await waitTime(2000);
|
||||
return res.json('captcha-xxx');
|
||||
}
|
||||
|
||||
const { ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION } = process.env;
|
||||
/**
|
||||
* 当前用户的权限,如果为空代表没登录
|
||||
* current user access, if is '', user need login
|
||||
* 如果是 pro 的预览,默认是有权限的
|
||||
*/
|
||||
|
||||
let access = ANT_DESIGN_PRO_ONLY_DO_NOT_USE_IN_YOUR_PRODUCTION === 'site' ? 'admin' : '';
|
||||
|
||||
const getAccess = () => {
|
||||
return access;
|
||||
}; // 代码中会兼容本地 service mock 以及部署站点的静态数据
|
||||
|
||||
export default {
|
||||
// 支持值为 Object 和 Array
|
||||
'GET /api/currentUser': (req, res) => {
|
||||
if (!getAccess()) {
|
||||
res.status(401).send({
|
||||
data: {
|
||||
isLogin: false,
|
||||
},
|
||||
errorCode: '401',
|
||||
errorMessage: '请先登录!',
|
||||
success: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
res.send({
|
||||
success: true,
|
||||
data: {
|
||||
name: 'Serati Ma',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/antfincdn/XAosXuNZyF/BiazfanxmamNRoxxVxka.png',
|
||||
userid: '00000001',
|
||||
email: 'antdesign@alipay.com',
|
||||
signature: '海纳百川,有容乃大',
|
||||
title: '交互专家',
|
||||
group: '蚂蚁金服-某某某事业群-某某平台部-某某技术部-UED',
|
||||
tags: [
|
||||
{
|
||||
key: '0',
|
||||
label: '很有想法的',
|
||||
},
|
||||
{
|
||||
key: '1',
|
||||
label: '专注设计',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
label: '辣~',
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
label: '大长腿',
|
||||
},
|
||||
{
|
||||
key: '4',
|
||||
label: '川妹子',
|
||||
},
|
||||
{
|
||||
key: '5',
|
||||
label: '海纳百川',
|
||||
},
|
||||
],
|
||||
notifyCount: 12,
|
||||
unreadCount: 11,
|
||||
country: 'China',
|
||||
access: getAccess(),
|
||||
geographic: {
|
||||
province: {
|
||||
label: '浙江省',
|
||||
key: '330000',
|
||||
},
|
||||
city: {
|
||||
label: '杭州市',
|
||||
key: '330100',
|
||||
},
|
||||
},
|
||||
address: '西湖区工专路 77 号',
|
||||
phone: '0752-268888888',
|
||||
},
|
||||
});
|
||||
},
|
||||
// GET POST 可省略
|
||||
'GET /api/users': [
|
||||
{
|
||||
key: '1',
|
||||
name: 'John Brown',
|
||||
age: 32,
|
||||
address: 'New York No. 1 Lake Park',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
name: 'Jim Green',
|
||||
age: 42,
|
||||
address: 'London No. 1 Lake Park',
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
name: 'Joe Black',
|
||||
age: 32,
|
||||
address: 'Sidney No. 1 Lake Park',
|
||||
},
|
||||
],
|
||||
'POST /api/login/account': async (req, res) => {
|
||||
const { password, username, type } = req.body;
|
||||
await waitTime(2000);
|
||||
|
||||
if (password === 'ant.design' && username === 'admin') {
|
||||
res.send({
|
||||
status: 'ok',
|
||||
type,
|
||||
currentAuthority: 'admin',
|
||||
});
|
||||
access = 'admin';
|
||||
return;
|
||||
}
|
||||
|
||||
if (password === 'ant.design' && username === 'user') {
|
||||
res.send({
|
||||
status: 'ok',
|
||||
type,
|
||||
currentAuthority: 'user',
|
||||
});
|
||||
access = 'user';
|
||||
return;
|
||||
}
|
||||
|
||||
if (type === 'mobile') {
|
||||
res.send({
|
||||
status: 'ok',
|
||||
type,
|
||||
currentAuthority: 'admin',
|
||||
});
|
||||
access = 'admin';
|
||||
return;
|
||||
}
|
||||
|
||||
res.send({
|
||||
status: 'error',
|
||||
type,
|
||||
currentAuthority: 'guest',
|
||||
});
|
||||
access = 'guest';
|
||||
},
|
||||
'POST /api/login/outLogin': (req, res) => {
|
||||
access = '';
|
||||
res.send({
|
||||
data: {},
|
||||
success: true,
|
||||
});
|
||||
},
|
||||
'POST /api/register': (req, res) => {
|
||||
res.send({
|
||||
status: 'ok',
|
||||
currentAuthority: 'user',
|
||||
success: true,
|
||||
});
|
||||
},
|
||||
'GET /api/500': (req, res) => {
|
||||
res.status(500).send({
|
||||
timestamp: 1513932555104,
|
||||
status: 500,
|
||||
error: 'error',
|
||||
message: 'error',
|
||||
path: '/base/category/list',
|
||||
});
|
||||
},
|
||||
'GET /api/404': (req, res) => {
|
||||
res.status(404).send({
|
||||
timestamp: 1513932643431,
|
||||
status: 404,
|
||||
error: 'Not Found',
|
||||
message: 'No message available',
|
||||
path: '/base/category/list/2121212',
|
||||
});
|
||||
},
|
||||
'GET /api/403': (req, res) => {
|
||||
res.status(403).send({
|
||||
timestamp: 1513932555104,
|
||||
status: 403,
|
||||
error: 'Forbidden',
|
||||
message: 'Forbidden',
|
||||
path: '/base/category/list',
|
||||
});
|
||||
},
|
||||
'GET /api/401': (req, res) => {
|
||||
res.status(401).send({
|
||||
timestamp: 1513932555104,
|
||||
status: 401,
|
||||
error: 'Unauthorized',
|
||||
message: 'Unauthorized',
|
||||
path: '/base/category/list',
|
||||
});
|
||||
},
|
||||
'GET /api/login/captcha': getFakeCaptcha,
|
||||
};
|
16464
frontend/package-lock.json
generated
@@ -1,40 +1,112 @@
|
||||
{
|
||||
"name": "frontend",
|
||||
"version": "0.1.0",
|
||||
"name": "ant-design-pro",
|
||||
"version": "5.0.0",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@testing-library/jest-dom": "^5.11.4",
|
||||
"@testing-library/react": "^11.1.0",
|
||||
"@testing-library/user-event": "^12.1.10",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-json-view": "^1.21.3",
|
||||
"react-scripts": "4.0.3",
|
||||
"web-vitals": "^1.0.1"
|
||||
},
|
||||
"proxy": "http://localhost:8080",
|
||||
"description": "An out-of-box UI solution for enterprise applications",
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
"analyze": "cross-env ANALYZE=1 umi build",
|
||||
"build": "umi build",
|
||||
"deploy": "npm run build && npm run gh-pages",
|
||||
"dev": "npm run start:dev",
|
||||
"gh-pages": "gh-pages -d dist",
|
||||
"i18n-remove": "pro i18n-remove --locale=zh-CN --write",
|
||||
"postinstall": "umi g tmp",
|
||||
"lint": "umi g tmp && npm run lint:js && npm run lint:style && npm run lint:prettier && npm run tsc",
|
||||
"lint-staged": "lint-staged",
|
||||
"lint-staged:js": "eslint --ext .js,.jsx,.ts,.tsx ",
|
||||
"lint:fix": "eslint --fix --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src && npm run lint:style",
|
||||
"lint:js": "eslint --cache --ext .js,.jsx,.ts,.tsx --format=pretty ./src",
|
||||
"lint:prettier": "prettier -c --write \"src/**/*\" --end-of-line auto",
|
||||
"lint:style": "stylelint --fix \"src/**/*.less\" --syntax less",
|
||||
"openapi": "umi openapi",
|
||||
"precommit": "lint-staged",
|
||||
"prettier": "prettier -c --write \"src/**/*\"",
|
||||
"serve": "umi-serve",
|
||||
"start": "cross-env UMI_ENV=dev umi dev",
|
||||
"start:dev": "cross-env REACT_APP_ENV=dev MOCK=none UMI_ENV=dev umi dev",
|
||||
"start:no-mock": "cross-env MOCK=none UMI_ENV=dev umi dev",
|
||||
"start:no-ui": "cross-env UMI_UI=none UMI_ENV=dev umi dev",
|
||||
"start:pre": "cross-env REACT_APP_ENV=pre UMI_ENV=dev umi dev",
|
||||
"start:test": "cross-env REACT_APP_ENV=test MOCK=none UMI_ENV=dev umi dev",
|
||||
"pretest": "node ./tests/beforeTest",
|
||||
"test": "umi test",
|
||||
"test:all": "node ./tests/run-tests.js",
|
||||
"test:component": "umi test ./src/components",
|
||||
"tsc": "tsc --noEmit"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
"lint-staged": {
|
||||
"**/*.less": "stylelint --syntax less",
|
||||
"**/*.{js,jsx,ts,tsx}": "npm run lint-staged:js",
|
||||
"**/*.{js,jsx,tsx,ts,less,md,json}": ["prettier --write"]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
"browserslist": ["> 1%", "last 2 versions", "not ie <= 10"],
|
||||
"dependencies": {
|
||||
"@ant-design/charts": "^0.9.4",
|
||||
"@ant-design/icons": "^4.5.0",
|
||||
"@ant-design/pro-descriptions": "^1.6.8",
|
||||
"@ant-design/pro-form": "^1.18.3",
|
||||
"@ant-design/pro-layout": "^6.15.3",
|
||||
"@ant-design/pro-table": "^2.30.8",
|
||||
"@antv/data-set": "^0.11.0",
|
||||
"@antv/l7": "^2.3.7",
|
||||
"@antv/l7-maps": "^2.3.7",
|
||||
"@antv/l7-react": "^2.1.9",
|
||||
"@umijs/route-utils": "^1.0.36",
|
||||
"ahooks": "^2.0.0",
|
||||
"antd": "^4.14.0",
|
||||
"bizcharts": "^3.5.3-beta.0",
|
||||
"bizcharts-plugin-slider": "^2.1.1-beta.1",
|
||||
"classnames": "^2.2.6",
|
||||
"gg-editor": "^2.0.2",
|
||||
"lodash": "^4.17.11",
|
||||
"lodash-decorators": "^6.0.0",
|
||||
"moment": "^2.25.3",
|
||||
"numeral": "^2.0.6",
|
||||
"nzh": "^1.0.3",
|
||||
"omit.js": "^2.0.2",
|
||||
"react": "^17.0.0",
|
||||
"react-dev-inspector": "^1.1.1",
|
||||
"react-dom": "^17.0.0",
|
||||
"react-fittext": "^1.0.0",
|
||||
"react-helmet-async": "^1.0.4",
|
||||
"react-router": "^4.3.1",
|
||||
"umi": "^3.5.0",
|
||||
"umi-serve": "^1.9.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ant-design/pro-cli": "^2.0.2",
|
||||
"@types/express": "^4.17.0",
|
||||
"@types/history": "^4.7.2",
|
||||
"@types/jest": "^26.0.0",
|
||||
"@types/lodash": "^4.14.144",
|
||||
"@types/react": "^17.0.0",
|
||||
"@types/react-dom": "^17.0.0",
|
||||
"@types/react-helmet": "^6.1.0",
|
||||
"@umijs/fabric": "^2.6.2",
|
||||
"@umijs/openapi": "^1.1.14",
|
||||
"@umijs/plugin-blocks": "^2.0.5",
|
||||
"@umijs/plugin-esbuild": "^1.0.1",
|
||||
"@umijs/plugin-openapi": "^1.2.0",
|
||||
"@umijs/preset-ant-design-pro": "^1.2.0",
|
||||
"@umijs/preset-dumi": "^1.1.7",
|
||||
"@umijs/preset-react": "^1.8.17",
|
||||
"@umijs/yorkie": "^2.0.3",
|
||||
"carlo": "^0.9.46",
|
||||
"cross-env": "^7.0.0",
|
||||
"cross-port-killer": "^1.1.1",
|
||||
"detect-installer": "^1.0.1",
|
||||
"enzyme": "^3.11.0",
|
||||
"eslint": "^7.1.0",
|
||||
"express": "^4.17.1",
|
||||
"gh-pages": "^3.0.0",
|
||||
"jsdom-global": "^3.0.2",
|
||||
"lint-staged": "^10.0.0",
|
||||
"mockjs": "^1.0.1-beta3",
|
||||
"prettier": "^2.3.2",
|
||||
"puppeteer-core": "^8.0.0",
|
||||
"stylelint": "^13.0.0",
|
||||
"typescript": "^4.2.2"
|
||||
},
|
||||
"engines": { "node": ">=10.0.0" },
|
||||
"gitHooks": { "commit-msg": "fabric verify-commit" }
|
||||
}
|
||||
|
1
frontend/public/CNAME
Normal file
@@ -0,0 +1 @@
|
||||
preview.pro.ant.design
|
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 4.2 KiB |
BIN
frontend/public/icons/icon-128x128.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
frontend/public/icons/icon-192x192.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
frontend/public/icons/icon-512x512.png
Normal file
After Width: | Height: | Size: 5.0 KiB |
@@ -1,59 +0,0 @@
|
||||
<!--
|
||||
~ Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
~ contributor license agreements. See the NOTICE file distributed with
|
||||
~ this work for additional information regarding copyright ownership.
|
||||
~ The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
~ (the "License"); you may not use this file except in compliance with
|
||||
~ the License. You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
</body>
|
||||
</html>
|
1
frontend/public/logo.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200" version="1.1" viewBox="0 0 200 200"><title>Group 28 Copy 5</title><desc>Created with Sketch.</desc><defs><linearGradient id="linearGradient-1" x1="62.102%" x2="108.197%" y1="0%" y2="37.864%"><stop offset="0%" stop-color="#4285EB"/><stop offset="100%" stop-color="#2EC7FF"/></linearGradient><linearGradient id="linearGradient-2" x1="69.644%" x2="54.043%" y1="0%" y2="108.457%"><stop offset="0%" stop-color="#29CDFF"/><stop offset="37.86%" stop-color="#148EFF"/><stop offset="100%" stop-color="#0A60FF"/></linearGradient><linearGradient id="linearGradient-3" x1="69.691%" x2="16.723%" y1="-12.974%" y2="117.391%"><stop offset="0%" stop-color="#FA816E"/><stop offset="41.473%" stop-color="#F74A5C"/><stop offset="100%" stop-color="#F51D2C"/></linearGradient><linearGradient id="linearGradient-4" x1="68.128%" x2="30.44%" y1="-35.691%" y2="114.943%"><stop offset="0%" stop-color="#FA8E7D"/><stop offset="51.264%" stop-color="#F74A5C"/><stop offset="100%" stop-color="#F51D2C"/></linearGradient></defs><g id="Page-1" fill="none" fill-rule="evenodd" stroke="none" stroke-width="1"><g id="logo" transform="translate(-20.000000, -20.000000)"><g id="Group-28-Copy-5" transform="translate(20.000000, 20.000000)"><g id="Group-27-Copy-3"><g id="Group-25" fill-rule="nonzero"><g id="2"><path id="Shape" fill="url(#linearGradient-1)" d="M91.5880863,4.17652823 L4.17996544,91.5127728 C-0.519240605,96.2081146 -0.519240605,103.791885 4.17996544,108.487227 L91.5880863,195.823472 C96.2872923,200.518814 103.877304,200.518814 108.57651,195.823472 L145.225487,159.204632 C149.433969,154.999611 149.433969,148.181924 145.225487,143.976903 C141.017005,139.771881 134.193707,139.771881 129.985225,143.976903 L102.20193,171.737352 C101.032305,172.906015 99.2571609,172.906015 98.0875359,171.737352 L28.285908,101.993122 C27.1162831,100.824459 27.1162831,99.050775 28.285908,97.8821118 L98.0875359,28.1378823 C99.2571609,26.9692191 101.032305,26.9692191 102.20193,28.1378823 L129.985225,55.8983314 C134.193707,60.1033528 141.017005,60.1033528 145.225487,55.8983314 C149.433969,51.69331 149.433969,44.8756232 145.225487,40.6706018 L108.58055,4.05574592 C103.862049,-0.537986846 96.2692618,-0.500797906 91.5880863,4.17652823 Z"/><path id="Shape" fill="url(#linearGradient-2)" d="M91.5880863,4.17652823 L4.17996544,91.5127728 C-0.519240605,96.2081146 -0.519240605,103.791885 4.17996544,108.487227 L91.5880863,195.823472 C96.2872923,200.518814 103.877304,200.518814 108.57651,195.823472 L145.225487,159.204632 C149.433969,154.999611 149.433969,148.181924 145.225487,143.976903 C141.017005,139.771881 134.193707,139.771881 129.985225,143.976903 L102.20193,171.737352 C101.032305,172.906015 99.2571609,172.906015 98.0875359,171.737352 L28.285908,101.993122 C27.1162831,100.824459 27.1162831,99.050775 28.285908,97.8821118 L98.0875359,28.1378823 C100.999864,25.6271836 105.751642,20.541824 112.729652,19.3524487 C117.915585,18.4685261 123.585219,20.4140239 129.738554,25.1889424 C125.624663,21.0784292 118.571995,14.0340304 108.58055,4.05574592 C103.862049,-0.537986846 96.2692618,-0.500797906 91.5880863,4.17652823 Z"/></g><path id="Shape" fill="url(#linearGradient-3)" d="M153.685633,135.854579 C157.894115,140.0596 164.717412,140.0596 168.925894,135.854579 L195.959977,108.842726 C200.659183,104.147384 200.659183,96.5636133 195.960527,91.8688194 L168.690777,64.7181159 C164.472332,60.5180858 157.646868,60.5241425 153.435895,64.7316526 C149.227413,68.936674 149.227413,75.7543607 153.435895,79.9593821 L171.854035,98.3623765 C173.02366,99.5310396 173.02366,101.304724 171.854035,102.473387 L153.685633,120.626849 C149.47715,124.83187 149.47715,131.649557 153.685633,135.854579 Z"/></g><ellipse id="Combined-Shape" cx="100.519" cy="100.437" fill="url(#linearGradient-4)" rx="23.6" ry="23.581"/></g></g></g></g></svg>
|
After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 9.4 KiB |
@@ -1,25 +0,0 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
5
frontend/public/pro_icon.svg
Normal file
@@ -0,0 +1,5 @@
|
||||
<svg width="42" height="42" xmlns="http://www.w3.org/2000/svg">
|
||||
<g>
|
||||
<path fill="#070707" d="m6.717392,13.773912l5.6,0c2.8,0 4.7,1.9 4.7,4.7c0,2.8 -2,4.7 -4.9,4.7l-2.5,0l0,4.3l-2.9,0l0,-13.7zm2.9,2.2l0,4.9l1.9,0c1.6,0 2.6,-0.9 2.6,-2.4c0,-1.6 -0.9,-2.4 -2.6,-2.4l-1.9,0l0,-0.1zm8.9,11.5l2.7,0l0,-5.7c0,-1.4 0.8,-2.3 2.2,-2.3c0.4,0 0.8,0.1 1,0.2l0,-2.4c-0.2,-0.1 -0.5,-0.1 -0.8,-0.1c-1.2,0 -2.1,0.7 -2.4,2l-0.1,0l0,-1.9l-2.7,0l0,10.2l0.1,0zm11.7,0.1c-3.1,0 -5,-2 -5,-5.3c0,-3.3 2,-5.3 5,-5.3s5,2 5,5.3c0,3.4 -1.9,5.3 -5,5.3zm0,-2.1c1.4,0 2.2,-1.1 2.2,-3.2c0,-2 -0.8,-3.2 -2.2,-3.2c-1.4,0 -2.2,1.2 -2.2,3.2c0,2.1 0.8,3.2 2.2,3.2z" class="st0" id="Ant-Design-Pro"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 677 B |
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
.App {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.App-logo {
|
||||
height: 40vmin;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
.App-logo {
|
||||
animation: App-logo-spin infinite 20s linear;
|
||||
}
|
||||
}
|
||||
|
||||
.App-header {
|
||||
background-color: #282c34;
|
||||
min-height: 40vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: calc(10px + 2vmin);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.App-link {
|
||||
color: #61dafb;
|
||||
}
|
||||
|
||||
@keyframes App-logo-spin {
|
||||
from {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React, {useState, useEffect} from 'react';
|
||||
import logo from './logo.svg';
|
||||
import './App.css';
|
||||
|
||||
function App() {
|
||||
const [message, setMessage] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
fetch('cluster/list.query')
|
||||
.then(response => response.text())
|
||||
.then(message => {
|
||||
setMessage(message);
|
||||
});
|
||||
}, [])
|
||||
|
||||
|
||||
return (
|
||||
<div className="App">
|
||||
<header className="App-header">
|
||||
<img src={logo} className="App-logo" alt="logo" height="60"/>
|
||||
<p>
|
||||
Edit <code>src/App.js</code> and save to reload.
|
||||
</p>
|
||||
</header>
|
||||
<h1>ClusterInfo</h1>
|
||||
<p>
|
||||
{message}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import App from './App';
|
||||
|
||||
test('renders learn react link', () => {
|
||||
render(<App />);
|
||||
const linkElement = screen.getByText(/learn react/i);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
});
|
9
frontend/src/access.js
Normal file
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* @see https://umijs.org/zh-CN/plugins/plugin-access
|
||||
* */
|
||||
export default function access(initialState) {
|
||||
const { currentUser } = initialState || {};
|
||||
return {
|
||||
canAdmin: currentUser && currentUser.access === 'admin',
|
||||
};
|
||||
}
|
77
frontend/src/app.jsx
Normal file
@@ -0,0 +1,77 @@
|
||||
import { PageLoading } from '@ant-design/pro-layout';
|
||||
import { history, Link } from 'umi';
|
||||
import RightContent from '@/components/RightContent';
|
||||
import Footer from '@/components/Footer';
|
||||
import { currentUser as queryCurrentUser } from './services/ant-design-pro/api';
|
||||
import { BookOutlined, LinkOutlined } from '@ant-design/icons';
|
||||
const isDev = process.env.NODE_ENV === 'development';
|
||||
const loginPath = '/user/login';
|
||||
/** 获取用户信息比较慢的时候会展示一个 loading */
|
||||
|
||||
export const initialStateConfig = {
|
||||
loading: <PageLoading />,
|
||||
};
|
||||
/**
|
||||
* @see https://umijs.org/zh-CN/plugins/plugin-initial-state
|
||||
* */
|
||||
|
||||
export async function getInitialState() {
|
||||
// const fetchUserInfo = async () => {
|
||||
// try {
|
||||
// const msg = await queryCurrentUser();
|
||||
// return msg.data;
|
||||
// } catch (error) {
|
||||
// history.push(loginPath);
|
||||
// }
|
||||
|
||||
// return undefined;
|
||||
// }; // 如果是登录页面,不执行
|
||||
|
||||
if (history.location.pathname !== loginPath) {
|
||||
// const currentUser = await fetchUserInfo();
|
||||
return {
|
||||
// fetchUserInfo,
|
||||
currentUser: {},
|
||||
settings: {},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
// fetchUserInfo,
|
||||
settings: {},
|
||||
};
|
||||
} // ProLayout 支持的api https://procomponents.ant.design/components/layout
|
||||
|
||||
export const layout = ({ initialState }) => {
|
||||
return {
|
||||
rightContentRender: () => <RightContent />,
|
||||
disableContentMargin: false,
|
||||
waterMarkProps: {
|
||||
content: initialState?.currentUser?.name,
|
||||
},
|
||||
footerRender: () => <Footer />,
|
||||
onPageChange: () => {
|
||||
const { location } = history; // 如果没有登录,重定向到 login
|
||||
|
||||
if (!initialState?.currentUser && location.pathname !== loginPath) {
|
||||
history.push(loginPath);
|
||||
}
|
||||
},
|
||||
links: isDev
|
||||
? [
|
||||
// <Link to="/umi/plugin/openapi" target="_blank">
|
||||
// <LinkOutlined />
|
||||
// <span>OpenAPI 文档</span>
|
||||
// </Link>,
|
||||
// <Link to="/~docs">
|
||||
// <BookOutlined />
|
||||
// <span>业务组件文档</span>
|
||||
// </Link>,
|
||||
]
|
||||
: [],
|
||||
menuHeaderRender: undefined,
|
||||
// 自定义 403 页面
|
||||
// unAccessible: <div>unAccessible</div>,
|
||||
...initialState?.settings,
|
||||
};
|
||||
};
|
24
frontend/src/components/Footer/index.jsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import { useIntl } from 'umi';
|
||||
import { GithubOutlined } from '@ant-design/icons';
|
||||
import { DefaultFooter } from '@ant-design/pro-layout';
|
||||
export default () => {
|
||||
const intl = useIntl();
|
||||
const defaultMessage = intl.formatMessage({
|
||||
id: 'app.copyright.produced',
|
||||
defaultMessage: 'RocketMQ',
|
||||
});
|
||||
const currentYear = new Date().getFullYear();
|
||||
return (
|
||||
<DefaultFooter
|
||||
copyright={`${currentYear} ${defaultMessage}`}
|
||||
links={[
|
||||
{
|
||||
key: 'github',
|
||||
title: <GithubOutlined />,
|
||||
href: 'https://github.com/apache/rocketmq-dashboard',
|
||||
blankTarget: true,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
);
|
||||
};
|
10
frontend/src/components/HeaderDropdown/index.jsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { Dropdown } from 'antd';
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import styles from './index.less';
|
||||
|
||||
const HeaderDropdown = ({ overlayClassName: cls, ...restProps }) => (
|
||||
<Dropdown overlayClassName={classNames(styles.container, cls)} {...restProps} />
|
||||
);
|
||||
|
||||
export default HeaderDropdown;
|
16
frontend/src/components/HeaderDropdown/index.less
Normal file
@@ -0,0 +1,16 @@
|
||||
@import '~antd/es/style/themes/default.less';
|
||||
|
||||
.container > * {
|
||||
background-color: @popover-bg;
|
||||
border-radius: 4px;
|
||||
box-shadow: @shadow-1-down;
|
||||
}
|
||||
|
||||
@media screen and (max-width: @screen-xs) {
|
||||
.container {
|
||||
width: 100% !important;
|
||||
}
|
||||
.container > * {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
}
|
83
frontend/src/components/HeaderSearch/index.jsx
Normal file
@@ -0,0 +1,83 @@
|
||||
import { SearchOutlined } from '@ant-design/icons';
|
||||
import { AutoComplete, Input } from 'antd';
|
||||
import useMergedState from 'rc-util/es/hooks/useMergedState';
|
||||
import React, { useRef } from 'react';
|
||||
import classNames from 'classnames';
|
||||
import styles from './index.less';
|
||||
|
||||
const HeaderSearch = (props) => {
|
||||
const {
|
||||
className,
|
||||
defaultValue,
|
||||
onVisibleChange,
|
||||
placeholder,
|
||||
visible,
|
||||
defaultVisible,
|
||||
...restProps
|
||||
} = props;
|
||||
const inputRef = useRef(null);
|
||||
const [value, setValue] = useMergedState(defaultValue, {
|
||||
value: props.value,
|
||||
onChange: props.onChange,
|
||||
});
|
||||
const [searchMode, setSearchMode] = useMergedState(defaultVisible ?? false, {
|
||||
value: props.visible,
|
||||
onChange: onVisibleChange,
|
||||
});
|
||||
const inputClass = classNames(styles.input, {
|
||||
[styles.show]: searchMode,
|
||||
});
|
||||
return (
|
||||
<div
|
||||
className={classNames(className, styles.headerSearch)}
|
||||
onClick={() => {
|
||||
setSearchMode(true);
|
||||
|
||||
if (searchMode && inputRef.current) {
|
||||
inputRef.current.focus();
|
||||
}
|
||||
}}
|
||||
onTransitionEnd={({ propertyName }) => {
|
||||
if (propertyName === 'width' && !searchMode) {
|
||||
if (onVisibleChange) {
|
||||
onVisibleChange(searchMode);
|
||||
}
|
||||
}
|
||||
}}
|
||||
>
|
||||
<SearchOutlined
|
||||
key="Icon"
|
||||
style={{
|
||||
cursor: 'pointer',
|
||||
}}
|
||||
/>
|
||||
<AutoComplete
|
||||
key="AutoComplete"
|
||||
className={inputClass}
|
||||
value={value}
|
||||
options={restProps.options}
|
||||
onChange={setValue}
|
||||
>
|
||||
<Input
|
||||
size="small"
|
||||
ref={inputRef}
|
||||
defaultValue={defaultValue}
|
||||
aria-label={placeholder}
|
||||
placeholder={placeholder}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
if (restProps.onSearch) {
|
||||
restProps.onSearch(value);
|
||||
}
|
||||
}
|
||||
}}
|
||||
onBlur={() => {
|
||||
setSearchMode(false);
|
||||
}}
|
||||
/>
|
||||
</AutoComplete>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default HeaderSearch;
|
25
frontend/src/components/HeaderSearch/index.less
Normal file
@@ -0,0 +1,25 @@
|
||||
@import '~antd/es/style/themes/default.less';
|
||||
|
||||
.headerSearch {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
.input {
|
||||
width: 0;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
background: transparent;
|
||||
border-radius: 0;
|
||||
transition: width 0.3s, margin-left 0.3s;
|
||||
:global(.ant-select-selection) {
|
||||
background: transparent;
|
||||
}
|
||||
input {
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
&.show {
|
||||
width: 210px;
|
||||
margin-left: 8px;
|
||||
}
|
||||
}
|
||||
}
|
114
frontend/src/components/NoticeIcon/NoticeIcon.jsx
Normal file
@@ -0,0 +1,114 @@
|
||||
import { BellOutlined } from '@ant-design/icons';
|
||||
import { Badge, Spin, Tabs } from 'antd';
|
||||
import useMergedState from 'rc-util/es/hooks/useMergedState';
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import NoticeList from './NoticeList';
|
||||
import HeaderDropdown from '../HeaderDropdown';
|
||||
import styles from './index.less';
|
||||
const { TabPane } = Tabs;
|
||||
|
||||
const NoticeIcon = (props) => {
|
||||
const getNotificationBox = () => {
|
||||
const {
|
||||
children,
|
||||
loading,
|
||||
onClear,
|
||||
onTabChange,
|
||||
onItemClick,
|
||||
onViewMore,
|
||||
clearText,
|
||||
viewMoreText,
|
||||
} = props;
|
||||
|
||||
if (!children) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const panes = [];
|
||||
React.Children.forEach(children, (child) => {
|
||||
if (!child) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { list, title, count, tabKey, showClear, showViewMore } = child.props;
|
||||
const len = list && list.length ? list.length : 0;
|
||||
const msgCount = count || count === 0 ? count : len;
|
||||
const tabTitle = msgCount > 0 ? `${title} (${msgCount})` : title;
|
||||
panes.push(
|
||||
<TabPane tab={tabTitle} key={tabKey}>
|
||||
<NoticeList
|
||||
clearText={clearText}
|
||||
viewMoreText={viewMoreText}
|
||||
list={list}
|
||||
tabKey={tabKey}
|
||||
onClear={() => onClear && onClear(title, tabKey)}
|
||||
onClick={(item) => onItemClick && onItemClick(item, child.props)}
|
||||
onViewMore={(event) => onViewMore && onViewMore(child.props, event)}
|
||||
showClear={showClear}
|
||||
showViewMore={showViewMore}
|
||||
title={title}
|
||||
/>
|
||||
</TabPane>,
|
||||
);
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<Spin spinning={loading} delay={300}>
|
||||
<Tabs className={styles.tabs} onChange={onTabChange}>
|
||||
{panes}
|
||||
</Tabs>
|
||||
</Spin>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
const { className, count, bell } = props;
|
||||
const [visible, setVisible] = useMergedState(false, {
|
||||
value: props.popupVisible,
|
||||
onChange: props.onPopupVisibleChange,
|
||||
});
|
||||
const noticeButtonClass = classNames(className, styles.noticeButton);
|
||||
const notificationBox = getNotificationBox();
|
||||
const NoticeBellIcon = bell || <BellOutlined className={styles.icon} />;
|
||||
const trigger = (
|
||||
<span
|
||||
className={classNames(noticeButtonClass, {
|
||||
opened: visible,
|
||||
})}
|
||||
>
|
||||
<Badge
|
||||
count={count}
|
||||
style={{
|
||||
boxShadow: 'none',
|
||||
}}
|
||||
className={styles.badge}
|
||||
>
|
||||
{NoticeBellIcon}
|
||||
</Badge>
|
||||
</span>
|
||||
);
|
||||
|
||||
if (!notificationBox) {
|
||||
return trigger;
|
||||
}
|
||||
|
||||
return (
|
||||
<HeaderDropdown
|
||||
placement="bottomRight"
|
||||
overlay={notificationBox}
|
||||
overlayClassName={styles.popover}
|
||||
trigger={['click']}
|
||||
visible={visible}
|
||||
onVisibleChange={setVisible}
|
||||
>
|
||||
{trigger}
|
||||
</HeaderDropdown>
|
||||
);
|
||||
};
|
||||
|
||||
NoticeIcon.defaultProps = {
|
||||
emptyImage: 'https://gw.alipayobjects.com/zos/rmsportal/wAhyIChODzsoKIOBHcBk.svg',
|
||||
};
|
||||
NoticeIcon.Tab = NoticeList;
|
||||
export default NoticeIcon;
|
97
frontend/src/components/NoticeIcon/NoticeList.jsx
Normal file
@@ -0,0 +1,97 @@
|
||||
import { Avatar, List } from 'antd';
|
||||
import React from 'react';
|
||||
import classNames from 'classnames';
|
||||
import styles from './NoticeList.less';
|
||||
|
||||
const NoticeList = ({
|
||||
list = [],
|
||||
onClick,
|
||||
onClear,
|
||||
title,
|
||||
onViewMore,
|
||||
emptyText,
|
||||
showClear = true,
|
||||
clearText,
|
||||
viewMoreText,
|
||||
showViewMore = false,
|
||||
}) => {
|
||||
if (!list || list.length === 0) {
|
||||
return (
|
||||
<div className={styles.notFound}>
|
||||
<img
|
||||
src="https://gw.alipayobjects.com/zos/rmsportal/sAuJeJzSKbUmHfBQRzmZ.svg"
|
||||
alt="not found"
|
||||
/>
|
||||
<div>{emptyText}</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<List
|
||||
className={styles.list}
|
||||
dataSource={list}
|
||||
renderItem={(item, i) => {
|
||||
const itemCls = classNames(styles.item, {
|
||||
[styles.read]: item.read,
|
||||
}); // eslint-disable-next-line no-nested-ternary
|
||||
|
||||
const leftIcon = item.avatar ? (
|
||||
typeof item.avatar === 'string' ? (
|
||||
<Avatar className={styles.avatar} src={item.avatar} />
|
||||
) : (
|
||||
<span className={styles.iconElement}>{item.avatar}</span>
|
||||
)
|
||||
) : null;
|
||||
return (
|
||||
<List.Item
|
||||
className={itemCls}
|
||||
key={item.key || i}
|
||||
onClick={() => {
|
||||
onClick?.(item);
|
||||
}}
|
||||
>
|
||||
<List.Item.Meta
|
||||
className={styles.meta}
|
||||
avatar={leftIcon}
|
||||
title={
|
||||
<div className={styles.title}>
|
||||
{item.title}
|
||||
<div className={styles.extra}>{item.extra}</div>
|
||||
</div>
|
||||
}
|
||||
description={
|
||||
<div>
|
||||
<div className={styles.description}>{item.description}</div>
|
||||
<div className={styles.datetime}>{item.datetime}</div>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</List.Item>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
<div className={styles.bottomBar}>
|
||||
{showClear ? (
|
||||
<div onClick={onClear}>
|
||||
{clearText} {title}
|
||||
</div>
|
||||
) : null}
|
||||
{showViewMore ? (
|
||||
<div
|
||||
onClick={(e) => {
|
||||
if (onViewMore) {
|
||||
onViewMore(e);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{viewMoreText}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default NoticeList;
|
103
frontend/src/components/NoticeIcon/NoticeList.less
Executable file
@@ -0,0 +1,103 @@
|
||||
@import '~antd/es/style/themes/default.less';
|
||||
|
||||
.list {
|
||||
max-height: 400px;
|
||||
overflow: auto;
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
.item {
|
||||
padding-right: 24px;
|
||||
padding-left: 24px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
.meta {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
margin-top: 4px;
|
||||
background: @component-background;
|
||||
}
|
||||
.iconElement {
|
||||
font-size: 32px;
|
||||
}
|
||||
|
||||
&.read {
|
||||
opacity: 0.4;
|
||||
}
|
||||
&:last-child {
|
||||
border-bottom: 0;
|
||||
}
|
||||
&:hover {
|
||||
background: @primary-1;
|
||||
}
|
||||
.title {
|
||||
margin-bottom: 8px;
|
||||
font-weight: normal;
|
||||
}
|
||||
.description {
|
||||
font-size: 12px;
|
||||
line-height: @line-height-base;
|
||||
}
|
||||
.datetime {
|
||||
margin-top: 4px;
|
||||
font-size: 12px;
|
||||
line-height: @line-height-base;
|
||||
}
|
||||
.extra {
|
||||
float: right;
|
||||
margin-top: -1.5px;
|
||||
margin-right: 0;
|
||||
color: @text-color-secondary;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
.loadMore {
|
||||
padding: 8px 0;
|
||||
color: @primary-6;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
&.loadedAll {
|
||||
color: rgba(0, 0, 0, 0.25);
|
||||
cursor: unset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.notFound {
|
||||
padding: 73px 0 88px;
|
||||
color: @text-color-secondary;
|
||||
text-align: center;
|
||||
img {
|
||||
display: inline-block;
|
||||
height: 76px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.bottomBar {
|
||||
height: 46px;
|
||||
color: @text-color;
|
||||
line-height: 46px;
|
||||
text-align: center;
|
||||
border-top: 1px solid @border-color-split;
|
||||
border-radius: 0 0 @border-radius-base @border-radius-base;
|
||||
transition: all 0.3s;
|
||||
div {
|
||||
display: inline-block;
|
||||
width: 50%;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
user-select: none;
|
||||
|
||||
&:only-child {
|
||||
width: 100%;
|
||||
}
|
||||
&:not(:only-child):last-child {
|
||||
border-left: 1px solid @border-color-split;
|
||||
}
|
||||
}
|
||||
}
|
148
frontend/src/components/NoticeIcon/index.jsx
Normal file
@@ -0,0 +1,148 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Tag, message } from 'antd';
|
||||
import { groupBy } from 'lodash';
|
||||
import moment from 'moment';
|
||||
import { useModel, useRequest } from 'umi';
|
||||
import { getNotices } from '@/services/ant-design-pro/api';
|
||||
import NoticeIcon from './NoticeIcon';
|
||||
import styles from './index.less';
|
||||
|
||||
const getNoticeData = (notices) => {
|
||||
if (!notices || notices.length === 0 || !Array.isArray(notices)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const newNotices = notices.map((notice) => {
|
||||
const newNotice = { ...notice };
|
||||
|
||||
if (newNotice.datetime) {
|
||||
newNotice.datetime = moment(notice.datetime).fromNow();
|
||||
}
|
||||
|
||||
if (newNotice.id) {
|
||||
newNotice.key = newNotice.id;
|
||||
}
|
||||
|
||||
if (newNotice.extra && newNotice.status) {
|
||||
const color = {
|
||||
todo: '',
|
||||
processing: 'blue',
|
||||
urgent: 'red',
|
||||
doing: 'gold',
|
||||
}[newNotice.status];
|
||||
newNotice.extra = (
|
||||
<Tag
|
||||
color={color}
|
||||
style={{
|
||||
marginRight: 0,
|
||||
}}
|
||||
>
|
||||
{newNotice.extra}
|
||||
</Tag>
|
||||
);
|
||||
}
|
||||
|
||||
return newNotice;
|
||||
});
|
||||
return groupBy(newNotices, 'type');
|
||||
};
|
||||
|
||||
const getUnreadData = (noticeData) => {
|
||||
const unreadMsg = {};
|
||||
Object.keys(noticeData).forEach((key) => {
|
||||
const value = noticeData[key];
|
||||
|
||||
if (!unreadMsg[key]) {
|
||||
unreadMsg[key] = 0;
|
||||
}
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
unreadMsg[key] = value.filter((item) => !item.read).length;
|
||||
}
|
||||
});
|
||||
return unreadMsg;
|
||||
};
|
||||
|
||||
const NoticeIconView = () => {
|
||||
const { initialState } = useModel('@@initialState');
|
||||
const { currentUser } = initialState || {};
|
||||
const [notices, setNotices] = useState([]);
|
||||
const { data } = useRequest(getNotices);
|
||||
useEffect(() => {
|
||||
setNotices(data || []);
|
||||
}, [data]);
|
||||
const noticeData = getNoticeData(notices);
|
||||
const unreadMsg = getUnreadData(noticeData || {});
|
||||
|
||||
const changeReadState = (id) => {
|
||||
setNotices(
|
||||
notices.map((item) => {
|
||||
const notice = { ...item };
|
||||
|
||||
if (notice.id === id) {
|
||||
notice.read = true;
|
||||
}
|
||||
|
||||
return notice;
|
||||
}),
|
||||
);
|
||||
};
|
||||
|
||||
const clearReadState = (title, key) => {
|
||||
setNotices(
|
||||
notices.map((item) => {
|
||||
const notice = { ...item };
|
||||
|
||||
if (notice.type === key) {
|
||||
notice.read = true;
|
||||
}
|
||||
|
||||
return notice;
|
||||
}),
|
||||
);
|
||||
message.success(`${'清空了'} ${title}`);
|
||||
};
|
||||
|
||||
return (
|
||||
<NoticeIcon
|
||||
className={styles.action}
|
||||
count={currentUser && currentUser.unreadCount}
|
||||
onItemClick={(item) => {
|
||||
changeReadState(item.id);
|
||||
}}
|
||||
onClear={(title, key) => clearReadState(title, key)}
|
||||
loading={false}
|
||||
clearText="清空"
|
||||
viewMoreText="查看更多"
|
||||
onViewMore={() => message.info('Click on view more')}
|
||||
clearClose
|
||||
>
|
||||
<NoticeIcon.Tab
|
||||
tabKey="notification"
|
||||
count={unreadMsg.notification}
|
||||
list={noticeData.notification}
|
||||
title="通知"
|
||||
emptyText="你已查看所有通知"
|
||||
showViewMore
|
||||
/>
|
||||
<NoticeIcon.Tab
|
||||
tabKey="message"
|
||||
count={unreadMsg.message}
|
||||
list={noticeData.message}
|
||||
title="消息"
|
||||
emptyText="您已读完所有消息"
|
||||
showViewMore
|
||||
/>
|
||||
<NoticeIcon.Tab
|
||||
tabKey="event"
|
||||
title="待办"
|
||||
emptyText="你已完成所有待办"
|
||||
count={unreadMsg.event}
|
||||
list={noticeData.event}
|
||||
showViewMore
|
||||
/>
|
||||
</NoticeIcon>
|
||||
);
|
||||
};
|
||||
|
||||
export default NoticeIconView;
|
35
frontend/src/components/NoticeIcon/index.less
Normal file
@@ -0,0 +1,35 @@
|
||||
@import '~antd/es/style/themes/default.less';
|
||||
|
||||
.popover {
|
||||
position: relative;
|
||||
width: 336px;
|
||||
}
|
||||
|
||||
.noticeButton {
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
.icon {
|
||||
padding: 4px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.badge {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
:global {
|
||||
.ant-tabs-nav-list {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.ant-tabs-nav-scroll {
|
||||
text-align: center;
|
||||
}
|
||||
.ant-tabs-bar {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
98
frontend/src/components/RightContent/AvatarDropdown.jsx
Normal file
@@ -0,0 +1,98 @@
|
||||
import React, { useCallback } from 'react';
|
||||
import { LogoutOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons';
|
||||
import { Avatar, Menu, Spin } from 'antd';
|
||||
import { history, useModel } from 'umi';
|
||||
import { stringify } from 'querystring';
|
||||
import HeaderDropdown from '../HeaderDropdown';
|
||||
import styles from './index.less';
|
||||
import { outLogin } from '@/services/ant-design-pro/api';
|
||||
|
||||
/**
|
||||
* 退出登录,并且将当前的 url 保存
|
||||
*/
|
||||
const loginOut = async () => {
|
||||
await outLogin();
|
||||
const { query = {}, pathname } = history.location;
|
||||
const { redirect } = query; // Note: There may be security issues, please note
|
||||
|
||||
if (window.location.pathname !== '/user/login' && !redirect) {
|
||||
history.replace({
|
||||
pathname: '/user/login',
|
||||
search: stringify({
|
||||
redirect: pathname,
|
||||
}),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const AvatarDropdown = ({ menu }) => {
|
||||
const { initialState, setInitialState } = useModel('@@initialState');
|
||||
const onMenuClick = useCallback(
|
||||
(event) => {
|
||||
const { key } = event;
|
||||
|
||||
if (key === 'logout') {
|
||||
setInitialState((s) => ({ ...s, currentUser: undefined }));
|
||||
loginOut();
|
||||
return;
|
||||
}
|
||||
|
||||
history.push(`/account/${key}`);
|
||||
},
|
||||
[setInitialState],
|
||||
);
|
||||
const loading = (
|
||||
<span className={`${styles.action} ${styles.account}`}>
|
||||
<Spin
|
||||
size="small"
|
||||
style={{
|
||||
marginLeft: 8,
|
||||
marginRight: 8,
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
);
|
||||
|
||||
if (!initialState) {
|
||||
return loading;
|
||||
}
|
||||
|
||||
const { currentUser } = initialState;
|
||||
|
||||
if (!currentUser || !currentUser.name) {
|
||||
return loading;
|
||||
}
|
||||
|
||||
const menuHeaderDropdown = (
|
||||
<Menu className={styles.menu} selectedKeys={[]} onClick={onMenuClick}>
|
||||
{menu && (
|
||||
<Menu.Item key="center">
|
||||
<UserOutlined />
|
||||
个人中心
|
||||
</Menu.Item>
|
||||
)}
|
||||
{menu && (
|
||||
<Menu.Item key="settings">
|
||||
<SettingOutlined />
|
||||
个人设置
|
||||
</Menu.Item>
|
||||
)}
|
||||
{menu && <Menu.Divider />}
|
||||
|
||||
<Menu.Item key="logout">
|
||||
<LogoutOutlined />
|
||||
退出登录
|
||||
</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
return (
|
||||
<HeaderDropdown overlay={menuHeaderDropdown}>
|
||||
<span className={`${styles.action} ${styles.account}`}>
|
||||
<Avatar size="small" className={styles.avatar} src={currentUser.avatar} alt="avatar" />
|
||||
<span className={`${styles.name} anticon`}>{currentUser.name}</span>
|
||||
</span>
|
||||
</HeaderDropdown>
|
||||
);
|
||||
};
|
||||
|
||||
export default AvatarDropdown;
|
66
frontend/src/components/RightContent/index.jsx
Normal file
@@ -0,0 +1,66 @@
|
||||
import { Space } from 'antd';
|
||||
import { QuestionCircleOutlined } from '@ant-design/icons';
|
||||
import React from 'react';
|
||||
import { useModel, SelectLang } from 'umi';
|
||||
import Avatar from './AvatarDropdown';
|
||||
import HeaderSearch from '../HeaderSearch';
|
||||
import styles from './index.less';
|
||||
import NoticeIconView from '../NoticeIcon';
|
||||
|
||||
const GlobalHeaderRight = () => {
|
||||
const { initialState } = useModel('@@initialState');
|
||||
|
||||
if (!initialState || !initialState.settings) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { navTheme, layout } = initialState.settings;
|
||||
let className = styles.right;
|
||||
|
||||
if ((navTheme === 'dark' && layout === 'top') || layout === 'mix') {
|
||||
className = `${styles.right} ${styles.dark}`;
|
||||
}
|
||||
|
||||
return (
|
||||
<Space className={className}>
|
||||
{/* <HeaderSearch
|
||||
className={`${styles.action} ${styles.search}`}
|
||||
placeholder="站内搜索"
|
||||
defaultValue="umi ui"
|
||||
options={[
|
||||
{
|
||||
label: <a href="https://umijs.org/zh/guide/umi-ui.html">umi ui</a>,
|
||||
value: 'umi ui',
|
||||
},
|
||||
{
|
||||
label: <a href="next.ant.design">Ant Design</a>,
|
||||
value: 'Ant Design',
|
||||
},
|
||||
{
|
||||
label: <a href="https://protable.ant.design/">Pro Table</a>,
|
||||
value: 'Pro Table',
|
||||
},
|
||||
{
|
||||
label: <a href="https://prolayout.ant.design/">Pro Layout</a>,
|
||||
value: 'Pro Layout',
|
||||
},
|
||||
]} // onSearch={value => {
|
||||
// console.log('input', value);
|
||||
// }}
|
||||
/> */}
|
||||
<span
|
||||
className={styles.action}
|
||||
onClick={() => {
|
||||
window.open('https://github.com/apache/rocketmq-dashboard');
|
||||
}}
|
||||
>
|
||||
<QuestionCircleOutlined />
|
||||
</span>
|
||||
{/* <NoticeIconView /> */}
|
||||
{/* <Avatar menu /> */}
|
||||
{/* <SelectLang className={styles.action} /> */}
|
||||
</Space>
|
||||
);
|
||||
};
|
||||
|
||||
export default GlobalHeaderRight;
|
84
frontend/src/components/RightContent/index.less
Normal file
@@ -0,0 +1,84 @@
|
||||
@import '~antd/es/style/themes/default.less';
|
||||
|
||||
@pro-header-hover-bg: rgba(0, 0, 0, 0.025);
|
||||
|
||||
.menu {
|
||||
:global(.anticon) {
|
||||
margin-right: 8px;
|
||||
}
|
||||
:global(.ant-dropdown-menu-item) {
|
||||
min-width: 160px;
|
||||
}
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
float: right;
|
||||
height: 48px;
|
||||
margin-left: auto;
|
||||
overflow: hidden;
|
||||
.action {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 48px;
|
||||
padding: 0 12px;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
> span {
|
||||
vertical-align: middle;
|
||||
}
|
||||
&:hover {
|
||||
background: @pro-header-hover-bg;
|
||||
}
|
||||
&:global(.opened) {
|
||||
background: @pro-header-hover-bg;
|
||||
}
|
||||
}
|
||||
.search {
|
||||
padding: 0 12px;
|
||||
&:hover {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
.account {
|
||||
.avatar {
|
||||
margin-right: 8px;
|
||||
color: @primary-color;
|
||||
vertical-align: top;
|
||||
background: rgba(255, 255, 255, 0.85);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.dark {
|
||||
.action {
|
||||
&:hover {
|
||||
background: #252a3d;
|
||||
}
|
||||
&:global(.opened) {
|
||||
background: #252a3d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (max-width: @screen-md) {
|
||||
:global(.ant-divider-vertical) {
|
||||
vertical-align: unset;
|
||||
}
|
||||
.name {
|
||||
display: none;
|
||||
}
|
||||
.right {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 12px;
|
||||
.account {
|
||||
.avatar {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
.search {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
272
frontend/src/components/index.md
Normal file
@@ -0,0 +1,272 @@
|
||||
---
|
||||
title: 业务组件
|
||||
sidemenu: false
|
||||
---
|
||||
|
||||
> 此功能由[dumi](https://d.umijs.org/zh-CN/guide/advanced#umi-%E9%A1%B9%E7%9B%AE%E9%9B%86%E6%88%90%E6%A8%A1%E5%BC%8F)提供,dumi 是一个 📖 为组件开发场景而生的文档工具,用过的都说好。
|
||||
|
||||
# 业务组件
|
||||
|
||||
这里列举了 Pro 中所有用到的组件,这些组件不适合作为组件库,但是在业务中却真实需要。所以我们准备了这个文档,来指导大家是否需要使用这个组件。
|
||||
|
||||
## Footer 页脚组件
|
||||
|
||||
这个组件自带了一些 Pro 的配置,你一般都需要改掉它的信息。
|
||||
|
||||
```tsx
|
||||
/**
|
||||
* background: '#f0f2f5'
|
||||
*/
|
||||
import React from 'react';
|
||||
import Footer from '@/components/Footer';
|
||||
|
||||
export default () => <Footer />;
|
||||
```
|
||||
|
||||
## HeaderDropdown 头部下拉列表
|
||||
|
||||
HeaderDropdown 是 antd Dropdown 的封装,但是增加了移动端的特殊处理,用法也是相同的。
|
||||
|
||||
```tsx
|
||||
/**
|
||||
* background: '#f0f2f5'
|
||||
*/
|
||||
import { Button, Menu } from 'antd';
|
||||
import React from 'react';
|
||||
import HeaderDropdown from '@/components/HeaderDropdown';
|
||||
|
||||
export default () => {
|
||||
const menuHeaderDropdown = (
|
||||
<Menu selectedKeys={[]}>
|
||||
<Menu.Item key="center">个人中心</Menu.Item>
|
||||
<Menu.Item key="settings">个人设置</Menu.Item>
|
||||
<Menu.Divider />
|
||||
<Menu.Item key="logout">退出登录</Menu.Item>
|
||||
</Menu>
|
||||
);
|
||||
return (
|
||||
<HeaderDropdown overlay={menuHeaderDropdown}>
|
||||
<Button>hover 展示菜单</Button>
|
||||
</HeaderDropdown>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
## HeaderSearch 头部搜索框
|
||||
|
||||
一个带补全数据的输入框,支持收起和展开 Input
|
||||
|
||||
```tsx
|
||||
/**
|
||||
* background: '#f0f2f5'
|
||||
*/
|
||||
import { Button, Menu } from 'antd';
|
||||
import React from 'react';
|
||||
import HeaderSearch from '@/components/HeaderSearch';
|
||||
|
||||
export default () => {
|
||||
return (
|
||||
<HeaderSearch
|
||||
placeholder="站内搜索"
|
||||
defaultValue="umi ui"
|
||||
options={[
|
||||
{ label: 'RocketMQ-Dashboard', value: 'RocketMQ-Dashboard' },
|
||||
{
|
||||
label: 'Ant Design',
|
||||
value: 'Ant Design',
|
||||
},
|
||||
{
|
||||
label: 'Pro Table',
|
||||
value: 'Pro Table',
|
||||
},
|
||||
{
|
||||
label: 'Pro Layout',
|
||||
value: 'Pro Layout',
|
||||
},
|
||||
]}
|
||||
onSearch={(value) => {
|
||||
console.log('input', value);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
### API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --------------- | ---------------------------------- | ---------------------------- | ------ |
|
||||
| value | 输入框的值 | `string` | - |
|
||||
| onChange | 值修改后触发 | `(value?: string) => void` | - |
|
||||
| onSearch | 查询后触发 | `(value?: string) => void` | - |
|
||||
| options | 选项菜单的的列表 | `{label,value}[]` | - |
|
||||
| defaultVisible | 输入框默认是否显示,只有第一次生效 | `boolean` | - |
|
||||
| visible | 输入框是否显示 | `boolean` | - |
|
||||
| onVisibleChange | 输入框显示隐藏的回调函数 | `(visible: boolean) => void` | - |
|
||||
|
||||
## NoticeIcon 通知工具
|
||||
|
||||
通知工具提供一个展示多种通知信息的界面。
|
||||
|
||||
```tsx
|
||||
/**
|
||||
* background: '#f0f2f5'
|
||||
*/
|
||||
import { message } from 'antd';
|
||||
import React from 'react';
|
||||
import NoticeIcon from '@/components/NoticeIcon/NoticeIcon';
|
||||
|
||||
export default () => {
|
||||
const list = [
|
||||
{
|
||||
id: '000000001',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png',
|
||||
title: '你收到了 14 份新周报',
|
||||
datetime: '2017-08-09',
|
||||
type: 'notification',
|
||||
},
|
||||
{
|
||||
id: '000000002',
|
||||
avatar: 'https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png',
|
||||
title: '你推荐的 曲妮妮 已通过第三轮面试',
|
||||
datetime: '2017-08-08',
|
||||
type: 'notification',
|
||||
},
|
||||
];
|
||||
return (
|
||||
<NoticeIcon
|
||||
count={10}
|
||||
onItemClick={(item) => {
|
||||
message.info(`${item.title} 被点击了`);
|
||||
}}
|
||||
onClear={(title: string, key: string) => message.info('点击了清空更多')}
|
||||
loading={false}
|
||||
clearText="清空"
|
||||
viewMoreText="查看更多"
|
||||
onViewMore={() => message.info('点击了查看更多')}
|
||||
clearClose
|
||||
>
|
||||
<NoticeIcon.Tab
|
||||
tabKey="notification"
|
||||
count={2}
|
||||
list={list}
|
||||
title="通知"
|
||||
emptyText="你已查看所有通知"
|
||||
showViewMore
|
||||
/>
|
||||
<NoticeIcon.Tab
|
||||
tabKey="message"
|
||||
count={2}
|
||||
list={list}
|
||||
title="消息"
|
||||
emptyText="您已读完所有消息"
|
||||
showViewMore
|
||||
/>
|
||||
<NoticeIcon.Tab
|
||||
tabKey="event"
|
||||
title="待办"
|
||||
emptyText="你已完成所有待办"
|
||||
count={2}
|
||||
list={list}
|
||||
showViewMore
|
||||
/>
|
||||
</NoticeIcon>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
### NoticeIcon API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| --- | --- | --- | --- |
|
||||
| count | 有多少未读通知 | `number` | - |
|
||||
| bell | 铃铛的图表 | `ReactNode` | - |
|
||||
| onClear | 点击清空数据按钮 | `(tabName: string, tabKey: string) => void` | - |
|
||||
| onItemClick | 未读消息列被点击 | `(item: API.NoticeIconData, tabProps: NoticeIconTabProps) => void` | - |
|
||||
| onViewMore | 查看更多的按钮点击 | `(tabProps: NoticeIconTabProps, e: MouseEvent) => void` | - |
|
||||
| onTabChange | 通知 Tab 的切换 | `(tabTile: string) => void;` | - |
|
||||
| popupVisible | 通知显示是否展示 | `boolean` | - |
|
||||
| onPopupVisibleChange | 通知信息显示隐藏的回调函数 | `(visible: boolean) => void` | - |
|
||||
| clearText | 清空按钮的文字 | `string` | - |
|
||||
| viewMoreText | 查看更多的按钮文字 | `string` | - |
|
||||
| clearClose | 展示清空按钮 | `boolean` | - |
|
||||
| emptyImage | 列表为空时的兜底展示 | `ReactNode` | - |
|
||||
|
||||
### NoticeIcon.Tab API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| ------------ | ------------------ | ------------------------------------ | ------ |
|
||||
| count | 有多少未读通知 | `number` | - |
|
||||
| title | 通知 Tab 的标题 | `ReactNode` | - |
|
||||
| showClear | 展示清除按钮 | `boolean` | `true` |
|
||||
| showViewMore | 展示加载更 | `boolean` | `true` |
|
||||
| tabKey | Tab 的唯一 key | `string` | - |
|
||||
| onClick | 子项的单击事件 | `(item: API.NoticeIconData) => void` | - |
|
||||
| onClear | 清楚按钮的点击 | `()=>void` | - |
|
||||
| emptyText | 为空的时候测试 | `()=>void` | - |
|
||||
| viewMoreText | 查看更多的按钮文字 | `string` | - |
|
||||
| onViewMore | 查看更多的按钮点击 | `( e: MouseEvent) => void` | - |
|
||||
| list | 通知信息的列表 | `API.NoticeIconData` | - |
|
||||
|
||||
### NoticeIconData
|
||||
|
||||
```tsx | pure
|
||||
export interface NoticeIconData {
|
||||
id: string;
|
||||
key: string;
|
||||
avatar: string;
|
||||
title: string;
|
||||
datetime: string;
|
||||
type: string;
|
||||
read?: boolean;
|
||||
description: string;
|
||||
clickClose?: boolean;
|
||||
extra: any;
|
||||
status: string;
|
||||
}
|
||||
```
|
||||
|
||||
## RightContent
|
||||
|
||||
RightContent 是以上几个组件的组合,同时新增了 plugins 的 `SelectLang` 插件。
|
||||
|
||||
```tsx | pure
|
||||
<Space>
|
||||
<HeaderSearch
|
||||
placeholder="站内搜索"
|
||||
defaultValue="umi ui"
|
||||
options={[
|
||||
{ label: <a href="https://umijs.org/zh/guide/umi-ui.html">umi ui</a>, value: 'umi ui' },
|
||||
{
|
||||
label: <a href="next.ant.design">Ant Design</a>,
|
||||
value: 'Ant Design',
|
||||
},
|
||||
{
|
||||
label: <a href="https://protable.ant.design/">Pro Table</a>,
|
||||
value: 'Pro Table',
|
||||
},
|
||||
{
|
||||
label: <a href="https://prolayout.ant.design/">Pro Layout</a>,
|
||||
value: 'Pro Layout',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Tooltip title="使用文档">
|
||||
<span
|
||||
className={styles.action}
|
||||
onClick={() => {
|
||||
window.location.href = 'https://pro.ant.design/docs/getting-started';
|
||||
}}
|
||||
>
|
||||
<QuestionCircleOutlined />
|
||||
</span>
|
||||
</Tooltip>
|
||||
<Avatar />
|
||||
{REACT_APP_ENV && (
|
||||
<span>
|
||||
<Tag color={ENVTagColor[REACT_APP_ENV]}>{REACT_APP_ENV}</Tag>
|
||||
</span>
|
||||
)}
|
||||
<SelectLang className={styles.action} />
|
||||
</Space>
|
||||
```
|
61
frontend/src/e2e/baseLayout.e2e.js
Normal file
@@ -0,0 +1,61 @@
|
||||
const { uniq } = require('lodash');
|
||||
const RouterConfig = require('../../config/config').default.routes;
|
||||
|
||||
const BASE_URL = `http://localhost:${process.env.PORT || 8001}`;
|
||||
|
||||
function formatter(routes, parentPath = '') {
|
||||
const fixedParentPath = parentPath.replace(/\/{1,}/g, '/');
|
||||
let result = [];
|
||||
routes.forEach((item) => {
|
||||
if (item.path && !item.path.startsWith('/')) {
|
||||
result.push(`${fixedParentPath}/${item.path}`.replace(/\/{1,}/g, '/'));
|
||||
}
|
||||
if (item.path && item.path.startsWith('/')) {
|
||||
result.push(`${item.path}`.replace(/\/{1,}/g, '/'));
|
||||
}
|
||||
if (item.routes) {
|
||||
result = result.concat(
|
||||
formatter(item.routes, item.path ? `${fixedParentPath}/${item.path}` : parentPath),
|
||||
);
|
||||
}
|
||||
});
|
||||
return uniq(result.filter((item) => !!item));
|
||||
}
|
||||
|
||||
beforeEach(async () => {
|
||||
await page.goto(`${BASE_URL}`);
|
||||
await page.evaluate(() => {
|
||||
localStorage.setItem('antd-pro-authority', '["admin"]');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Ant Design Pro E2E test', () => {
|
||||
const testPage = (path) => async () => {
|
||||
await page.goto(`${BASE_URL}${path}`);
|
||||
await page.waitForSelector('footer', {
|
||||
timeout: 2000,
|
||||
});
|
||||
const haveFooter = await page.evaluate(
|
||||
() => document.getElementsByTagName('footer').length > 0,
|
||||
);
|
||||
expect(haveFooter).toBeTruthy();
|
||||
};
|
||||
|
||||
const routers = formatter(RouterConfig);
|
||||
routers.forEach((route) => {
|
||||
it(`test pages ${route}`, testPage(route));
|
||||
});
|
||||
|
||||
it('topmenu should have footer', async () => {
|
||||
const params = '?navTheme=light&layout=topmenu';
|
||||
await page.goto(`${BASE_URL}${params}`);
|
||||
await page.waitForSelector('footer', {
|
||||
timeout: 2000,
|
||||
});
|
||||
|
||||
const haveFooter = await page.evaluate(
|
||||
() => document.getElementsByTagName('footer').length > 0,
|
||||
);
|
||||
expect(haveFooter).toBeTruthy();
|
||||
});
|
||||
});
|
108
frontend/src/global.jsx
Normal file
@@ -0,0 +1,108 @@
|
||||
import { Button, message, notification } from 'antd';
|
||||
import { useIntl } from 'umi';
|
||||
import defaultSettings from '../config/defaultSettings';
|
||||
const { pwa } = defaultSettings;
|
||||
const isHttps = document.location.protocol === 'https:';
|
||||
|
||||
const clearCache = () => {
|
||||
// remove all caches
|
||||
if (window.caches) {
|
||||
caches
|
||||
.keys()
|
||||
.then((keys) => {
|
||||
keys.forEach((key) => {
|
||||
caches.delete(key);
|
||||
});
|
||||
})
|
||||
.catch((e) => console.log(e));
|
||||
}
|
||||
}; // if pwa is true
|
||||
|
||||
if (pwa) {
|
||||
// Notify user if offline now
|
||||
window.addEventListener('sw.offline', () => {
|
||||
message.warning(
|
||||
useIntl().formatMessage({
|
||||
id: 'app.pwa.offline',
|
||||
}),
|
||||
);
|
||||
}); // Pop up a prompt on the page asking the user if they want to use the latest version
|
||||
|
||||
window.addEventListener('sw.updated', (event) => {
|
||||
const e = event;
|
||||
|
||||
const reloadSW = async () => {
|
||||
// Check if there is sw whose state is waiting in ServiceWorkerRegistration
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration
|
||||
const worker = e.detail && e.detail.waiting;
|
||||
|
||||
if (!worker) {
|
||||
return true;
|
||||
} // Send skip-waiting event to waiting SW with MessageChannel
|
||||
|
||||
await new Promise((resolve, reject) => {
|
||||
const channel = new MessageChannel();
|
||||
|
||||
channel.port1.onmessage = (msgEvent) => {
|
||||
if (msgEvent.data.error) {
|
||||
reject(msgEvent.data.error);
|
||||
} else {
|
||||
resolve(msgEvent.data);
|
||||
}
|
||||
};
|
||||
|
||||
worker.postMessage(
|
||||
{
|
||||
type: 'skip-waiting',
|
||||
},
|
||||
[channel.port2],
|
||||
);
|
||||
});
|
||||
clearCache();
|
||||
window.location.reload();
|
||||
return true;
|
||||
};
|
||||
|
||||
const key = `open${Date.now()}`;
|
||||
const btn = (
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => {
|
||||
notification.close(key);
|
||||
reloadSW();
|
||||
}}
|
||||
>
|
||||
{useIntl().formatMessage({
|
||||
id: 'app.pwa.serviceworker.updated.ok',
|
||||
})}
|
||||
</Button>
|
||||
);
|
||||
notification.open({
|
||||
message: useIntl().formatMessage({
|
||||
id: 'app.pwa.serviceworker.updated',
|
||||
}),
|
||||
description: useIntl().formatMessage({
|
||||
id: 'app.pwa.serviceworker.updated.hint',
|
||||
}),
|
||||
btn,
|
||||
key,
|
||||
onClose: async () => null,
|
||||
});
|
||||
});
|
||||
} else if ('serviceWorker' in navigator && isHttps) {
|
||||
// unregister service worker
|
||||
const { serviceWorker } = navigator;
|
||||
|
||||
if (serviceWorker.getRegistrations) {
|
||||
serviceWorker.getRegistrations().then((sws) => {
|
||||
sws.forEach((sw) => {
|
||||
sw.unregister();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
serviceWorker.getRegistration().then((sw) => {
|
||||
if (sw) sw.unregister();
|
||||
});
|
||||
clearCache();
|
||||
}
|
57
frontend/src/global.less
Normal file
@@ -0,0 +1,57 @@
|
||||
@import '~antd/es/style/themes/default.less';
|
||||
|
||||
html,
|
||||
body,
|
||||
#root {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.colorWeak {
|
||||
filter: invert(80%);
|
||||
}
|
||||
|
||||
.ant-layout {
|
||||
min-height: 100vh;
|
||||
}
|
||||
.ant-pro-sider.ant-layout-sider.ant-pro-sider-fixed {
|
||||
left: unset;
|
||||
}
|
||||
|
||||
canvas {
|
||||
display: block;
|
||||
}
|
||||
|
||||
body {
|
||||
text-rendering: optimizeLegibility;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
ul,
|
||||
ol {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
@media (max-width: @screen-xs) {
|
||||
.ant-table {
|
||||
width: 100%;
|
||||
overflow-x: auto;
|
||||
&-thead > tr,
|
||||
&-tbody > tr {
|
||||
> th,
|
||||
> td {
|
||||
white-space: pre;
|
||||
> span {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Compatible with IE11
|
||||
@media screen and(-ms-high-contrast: active), (-ms-high-contrast: none) {
|
||||
body .ant-design-pro > .ant-layout {
|
||||
min-height: 100vh;
|
||||
}
|
||||
}
|
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
@@ -1,33 +0,0 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import './index.css';
|
||||
import App from './App';
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
|
||||
ReactDOM.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>,
|
||||
document.getElementById('root')
|
||||
);
|
||||
|
||||
// If you want to start measuring performance in your app, pass a function
|
||||
// to log results (for example: reportWebVitals(console.log))
|
||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||
reportWebVitals();
|
25
frontend/src/locales/bn-BD.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import component from './bn-BD/component';
|
||||
import globalHeader from './bn-BD/globalHeader';
|
||||
import menu from './bn-BD/menu';
|
||||
import pages from './bn-BD/pages';
|
||||
import pwa from './bn-BD/pwa';
|
||||
import settingDrawer from './bn-BD/settingDrawer';
|
||||
import settings from './bn-BD/settings';
|
||||
export default {
|
||||
'navBar.lang': 'ভাষা',
|
||||
'layout.user.link.help': 'সহায়তা',
|
||||
'layout.user.link.privacy': 'গোপনীয়তা',
|
||||
'layout.user.link.terms': 'শর্তাদি',
|
||||
'app.copyright.produced': 'প্রযোজনা করেছেন অ্যান্ট ফিনান্সিয়াল এক্সপেরিয়েন্স ডিপার্টমেন্ট',
|
||||
'app.preview.down.block': 'আপনার স্থানীয় প্রকল্পে এই পৃষ্ঠাটি ডাউনলোড করুন',
|
||||
'app.welcome.link.fetch-blocks': 'সমস্ত ব্লক পান',
|
||||
'app.welcome.link.block-list':
|
||||
'`block` ডেভেলপমেন্ট এর উপর ভিত্তি করে দ্রুত স্ট্যান্ডার্ড, পৃষ্ঠাসমূহ তৈরি করুন।',
|
||||
...globalHeader,
|
||||
...menu,
|
||||
...settingDrawer,
|
||||
...settings,
|
||||
...pwa,
|
||||
...component,
|
||||
...pages,
|
||||
};
|
5
frontend/src/locales/bn-BD/component.js
Normal file
@@ -0,0 +1,5 @@
|
||||
export default {
|
||||
'component.tagSelect.expand': 'বিস্তৃত',
|
||||
'component.tagSelect.collapse': 'সঙ্কুচিত',
|
||||
'component.tagSelect.all': 'সব',
|
||||
};
|
17
frontend/src/locales/bn-BD/globalHeader.js
Normal file
@@ -0,0 +1,17 @@
|
||||
export default {
|
||||
'component.globalHeader.search': 'অনুসন্ধান করুন',
|
||||
'component.globalHeader.search.example1': 'অনুসন্ধান উদাহরণ ১',
|
||||
'component.globalHeader.search.example2': 'অনুসন্ধান উদাহরণ ২',
|
||||
'component.globalHeader.search.example3': 'অনুসন্ধান উদাহরণ ৩',
|
||||
'component.globalHeader.help': 'সহায়তা',
|
||||
'component.globalHeader.notification': 'বিজ্ঞপ্তি',
|
||||
'component.globalHeader.notification.empty': 'আপনি সমস্ত বিজ্ঞপ্তি দেখেছেন।',
|
||||
'component.globalHeader.message': 'বার্তা',
|
||||
'component.globalHeader.message.empty': 'আপনি সমস্ত বার্তা দেখেছেন।',
|
||||
'component.globalHeader.event': 'ঘটনা',
|
||||
'component.globalHeader.event.empty': 'আপনি সমস্ত ইভেন্ট দেখেছেন।',
|
||||
'component.noticeIcon.clear': 'সাফ',
|
||||
'component.noticeIcon.cleared': 'সাফ করা হয়েছে',
|
||||
'component.noticeIcon.empty': 'বিজ্ঞপ্তি নেই',
|
||||
'component.noticeIcon.view-more': 'আরো দেখুন',
|
||||
};
|
52
frontend/src/locales/bn-BD/menu.js
Normal file
@@ -0,0 +1,52 @@
|
||||
export default {
|
||||
'menu.welcome': 'স্বাগতম',
|
||||
'menu.more-blocks': 'আরও ব্লক',
|
||||
'menu.home': 'নীড়',
|
||||
'menu.admin': 'অ্যাডমিন',
|
||||
'menu.admin.sub-page': 'উপ-পৃষ্ঠা',
|
||||
'menu.login': 'প্রবেশ',
|
||||
'menu.register': 'নিবন্ধন',
|
||||
'menu.register-result': 'নিবন্ধনে ফলাফল',
|
||||
'menu.dashboard': 'ড্যাশবোর্ড',
|
||||
'menu.dashboard.analysis': 'বিশ্লেষণ',
|
||||
'menu.dashboard.monitor': 'নিরীক্ষণ',
|
||||
'menu.dashboard.workplace': 'কর্মক্ষেত্র',
|
||||
'menu.exception.403': '403',
|
||||
'menu.exception.404': '404',
|
||||
'menu.exception.500': '500',
|
||||
'menu.form': 'ফর্ম',
|
||||
'menu.form.basic-form': 'বেসিক ফর্ম',
|
||||
'menu.form.step-form': 'পদক্ষেপ ফর্ম',
|
||||
'menu.form.step-form.info': 'পদক্ষেপ ফর্ম (স্থানান্তর তথ্য লিখুন)',
|
||||
'menu.form.step-form.confirm': 'পদক্ষেপ ফর্ম (স্থানান্তর তথ্য নিশ্চিত করুন)',
|
||||
'menu.form.step-form.result': 'পদক্ষেপ ফর্ম (সমাপ্ত)',
|
||||
'menu.form.advanced-form': 'উন্নত ফর্ম',
|
||||
'menu.list': 'তালিকা',
|
||||
'menu.list.table-list': 'অনুসন্ধানের টেবিল',
|
||||
'menu.list.basic-list': 'বেসিক তালিকা',
|
||||
'menu.list.card-list': 'কার্ডের তালিকা',
|
||||
'menu.list.search-list': 'অনুসন্ধানের তালিকা',
|
||||
'menu.list.search-list.articles': 'অনুসন্ধানের তালিকা (নিবন্ধসমূহ)',
|
||||
'menu.list.search-list.projects': 'অনুসন্ধানের তালিকা (প্রকল্পগুলি)',
|
||||
'menu.list.search-list.applications': 'অনুসন্ধানের তালিকা (অ্যাপ্লিকেশন)',
|
||||
'menu.profile': 'প্রোফাইল',
|
||||
'menu.profile.basic': 'বেসিক প্রোফাইল',
|
||||
'menu.profile.advanced': 'উন্নত প্রোফাইল',
|
||||
'menu.result': 'ফলাফল',
|
||||
'menu.result.success': 'সাফল্য',
|
||||
'menu.result.fail': 'ব্যর্থ',
|
||||
'menu.exception': 'ব্যতিক্রম',
|
||||
'menu.exception.not-permission': '403',
|
||||
'menu.exception.not-find': '404',
|
||||
'menu.exception.server-error': '500',
|
||||
'menu.exception.trigger': 'ট্রিগার',
|
||||
'menu.account': 'হিসাব',
|
||||
'menu.account.center': 'অ্যাকাউন্ট কেন্দ্র',
|
||||
'menu.account.settings': 'অ্যাকাউন্ট সেটিংস',
|
||||
'menu.account.trigger': 'ট্রিগার ত্রুটি',
|
||||
'menu.account.logout': 'প্রস্থান',
|
||||
'menu.editor': 'গ্রাফিক সম্পাদক',
|
||||
'menu.editor.flow': 'ফ্লো এডিটর',
|
||||
'menu.editor.mind': 'মাইন্ড এডিটর',
|
||||
'menu.editor.koni': 'কোনি সম্পাদক',
|
||||
};
|
70
frontend/src/locales/bn-BD/pages.js
Normal file
@@ -0,0 +1,70 @@
|
||||
export default {
|
||||
'pages.layouts.userLayout.title':
|
||||
'পিঁপড়া ডিজাইন হচ্ছে সিহু জেলার সবচেয়ে প্রভাবশালী ওয়েব ডিজাইনের স্পেসিফিকেশন',
|
||||
'pages.login.accountLogin.tab': 'অ্যাকাউন্টে লগইন',
|
||||
'pages.login.accountLogin.errorMessage': 'ভুল ব্যবহারকারীর নাম/পাসওয়ার্ড(admin/ant.design)',
|
||||
'pages.login.failure': 'লগইন ব্যর্থ হয়েছে। আবার চেষ্টা করুন!',
|
||||
'pages.login.success': 'সফল লগইন!',
|
||||
'pages.login.username.placeholder': 'ব্যবহারকারীর নাম: admin or user',
|
||||
'pages.login.username.required': 'আপনার ব্যবহারকারীর নাম ইনপুট করুন!',
|
||||
'pages.login.password.placeholder': 'পাসওয়ার্ড: ant.design',
|
||||
'pages.login.password.required': 'আপনার পাসওয়ার্ড ইনপুট করুন!',
|
||||
'pages.login.phoneLogin.tab': 'ফোন লগইন',
|
||||
'pages.login.phoneLogin.errorMessage': 'যাচাইকরণ কোড ত্রুটি',
|
||||
'pages.login.phoneNumber.placeholder': 'ফোন নম্বর',
|
||||
'pages.login.phoneNumber.required': 'আপনার ফোন নম্বর ইনপুট করুন!',
|
||||
'pages.login.phoneNumber.invalid': 'ফোন নম্বরটি সঠিক নয়!',
|
||||
'pages.login.captcha.placeholder': 'যাচাইকরণের কোড',
|
||||
'pages.login.captcha.required': 'দয়া করে ভেরিফিকেশন কোডটি ইনপুট করুন!',
|
||||
'pages.login.phoneLogin.getVerificationCode': 'কোড পান',
|
||||
'pages.getCaptchaSecondText': 'সেকেন্ড',
|
||||
'pages.login.rememberMe': 'আমাকে মনে রাখুন',
|
||||
'pages.login.forgotPassword': 'পাসওয়ার্ড ভুলে গেছেন?',
|
||||
'pages.login.submit': 'প্রবেশ করুন',
|
||||
'pages.login.loginWith': 'লগইন করতে পারেন:',
|
||||
'pages.login.registerAccount': 'অ্যাকাউন্ট নিবন্ধন করুন',
|
||||
'pages.welcome.advancedComponent': 'অ্যাডভান্সড কম্পোনেন্ট',
|
||||
'pages.welcome.link': 'স্বাগতম',
|
||||
'pages.welcome.advancedLayout': 'অ্যাডভান্সড লেআউট',
|
||||
'pages.welcome.alertMessage': 'দ্রুত এবং শক্তিশালী ভারী শুল্ক উপাদান প্রকাশ করা হয়েছে।',
|
||||
'pages.admin.subPage.title': 'এই পৃষ্ঠাটি কেবল অ্যাডমিন দ্বারা দেখা যাবে',
|
||||
'pages.admin.subPage.alertMessage':
|
||||
'UMI UI এখন প্রকাশিত হয়েছে, অভিজ্ঞতা শুরু করতে npm run ui ব্যবহার করতে স্বাগতম।',
|
||||
'pages.searchTable.createForm.newRule': 'নতুন বিধি',
|
||||
'pages.searchTable.updateForm.ruleConfig': 'বিধি কনফিগারেশন',
|
||||
'pages.searchTable.updateForm.basicConfig': 'মৌলিক তথ্য',
|
||||
'pages.searchTable.updateForm.ruleName.nameLabel': 'বিধি নাম',
|
||||
'pages.searchTable.updateForm.ruleName.nameRules': 'বিধির নাম লিখুন!',
|
||||
'pages.searchTable.updateForm.ruleDesc.descLabel': 'বিধির বিবরণ',
|
||||
'pages.searchTable.updateForm.ruleDesc.descPlaceholder': 'কমপক্ষে পাঁচটি অক্ষর লিখুন',
|
||||
'pages.searchTable.updateForm.ruleDesc.descRules':
|
||||
'কমপক্ষে পাঁচটি অক্ষরের একটি বিধান বিবরণ লিখুন!',
|
||||
'pages.searchTable.updateForm.ruleProps.title': 'বৈশিষ্ট্য কনফিগার করুন',
|
||||
'pages.searchTable.updateForm.object': 'নিরীক্ষণ অবজেক্ট',
|
||||
'pages.searchTable.updateForm.ruleProps.templateLabel': 'বিধি টেম্পলেট',
|
||||
'pages.searchTable.updateForm.ruleProps.typeLabel': 'বিধি প্রকার',
|
||||
'pages.searchTable.updateForm.schedulingPeriod.title': 'সময়সূচী নির্ধারণ করুন',
|
||||
'pages.searchTable.updateForm.schedulingPeriod.timeLabel': 'শুরুর সময়',
|
||||
'pages.searchTable.updateForm.schedulingPeriod.timeRules': 'একটি শুরুর সময় চয়ন করুন!',
|
||||
'pages.searchTable.titleDesc': 'বর্ণনা',
|
||||
'pages.searchTable.ruleName': 'বিধি নাম প্রয়োজন',
|
||||
'pages.searchTable.titleCallNo': 'পরিষেবা কল সংখ্যা',
|
||||
'pages.searchTable.titleStatus': 'অবস্থা',
|
||||
'pages.searchTable.nameStatus.default': 'ডিফল্ট',
|
||||
'pages.searchTable.nameStatus.running': 'চলমান',
|
||||
'pages.searchTable.nameStatus.online': 'অনলাইন',
|
||||
'pages.searchTable.nameStatus.abnormal': 'অস্বাভাবিক',
|
||||
'pages.searchTable.titleUpdatedAt': 'সর্বশেষ নির্ধারিত',
|
||||
'pages.searchTable.exception': 'ব্যতিক্রম জন্য কারণ লিখুন!',
|
||||
'pages.searchTable.titleOption': 'অপশন',
|
||||
'pages.searchTable.config': 'কনফিগারেশন',
|
||||
'pages.searchTable.subscribeAlert': 'সতর্কতা সাবস্ক্রাইব করুন',
|
||||
'pages.searchTable.title': 'ইনকয়েরি ফরম',
|
||||
'pages.searchTable.new': 'নতুন',
|
||||
'pages.searchTable.chosen': 'নির্বাচিত',
|
||||
'pages.searchTable.item': 'আইটেম',
|
||||
'pages.searchTable.totalServiceCalls': 'পরিষেবা কলগুলির মোট সংখ্যা',
|
||||
'pages.searchTable.tenThousand': '000',
|
||||
'pages.searchTable.batchDeletion': 'একসাখে ডিলিট',
|
||||
'pages.searchTable.batchApproval': 'একসাখে অনুমোদন',
|
||||
};
|
7
frontend/src/locales/bn-BD/pwa.js
Normal file
@@ -0,0 +1,7 @@
|
||||
export default {
|
||||
'app.pwa.offline': 'আপনি এখন অফলাইন',
|
||||
'app.pwa.serviceworker.updated': 'নতুন সামগ্রী উপলব্ধ',
|
||||
'app.pwa.serviceworker.updated.hint':
|
||||
'বর্তমান পৃষ্ঠাটি পুনরায় লোড করতে দয়া করে "রিফ্রেশ" বোতাম টিপুন',
|
||||
'app.pwa.serviceworker.updated.ok': 'রিফ্রেশ',
|
||||
};
|
31
frontend/src/locales/bn-BD/settingDrawer.js
Normal file
@@ -0,0 +1,31 @@
|
||||
export default {
|
||||
'app.setting.pagestyle': 'পৃষ্ঠা স্টাইল সেটিং',
|
||||
'app.setting.pagestyle.dark': 'ডার্ক স্টাইল',
|
||||
'app.setting.pagestyle.light': 'লাইট স্টাইল',
|
||||
'app.setting.content-width': 'সামগ্রীর প্রস্থ',
|
||||
'app.setting.content-width.fixed': 'স্থির',
|
||||
'app.setting.content-width.fluid': 'প্রবাহী',
|
||||
'app.setting.themecolor': 'থিম রঙ',
|
||||
'app.setting.themecolor.dust': 'ডাস্ট রেড',
|
||||
'app.setting.themecolor.volcano': 'আগ্নেয়গিরি',
|
||||
'app.setting.themecolor.sunset': 'সানসেট কমলা',
|
||||
'app.setting.themecolor.cyan': 'সবুজাভ নীল',
|
||||
'app.setting.themecolor.green': 'পোলার সবুজ',
|
||||
'app.setting.themecolor.daybreak': 'দিবস ব্রেক ব্লু (ডিফল্ট)',
|
||||
'app.setting.themecolor.geekblue': 'গিক আঠালো',
|
||||
'app.setting.themecolor.purple': 'গোল্ডেন বেগুনি',
|
||||
'app.setting.navigationmode': 'নেভিগেশন মোড',
|
||||
'app.setting.sidemenu': 'সাইড মেনু লেআউট',
|
||||
'app.setting.topmenu': 'টপ মেনু লেআউট',
|
||||
'app.setting.fixedheader': 'স্থির হেডার',
|
||||
'app.setting.fixedsidebar': 'স্থির সাইডবার',
|
||||
'app.setting.fixedsidebar.hint': 'সাইড মেনু বিন্যাসে কাজ করে',
|
||||
'app.setting.hideheader': 'স্ক্রোল করার সময় হেডার লুকানো',
|
||||
'app.setting.hideheader.hint': 'লুকানো হেডার সক্ষম থাকলে কাজ করে',
|
||||
'app.setting.othersettings': 'অন্যান্য সেটিংস্',
|
||||
'app.setting.weakmode': 'দুর্বল মোড',
|
||||
'app.setting.copy': 'সেটিং কপি করুন',
|
||||
'app.setting.copyinfo': 'সাফল্যের অনুলিপি করুন - প্রতিস্থাপন করুন: src/models/setting.js',
|
||||
'app.setting.production.hint':
|
||||
'কেবল বিকাশের পরিবেশে প্যানেল শো সেট করা হচ্ছে, দয়া করে ম্যানুয়ালি সংশোধন করুন',
|
||||
};
|
59
frontend/src/locales/bn-BD/settings.js
Normal file
@@ -0,0 +1,59 @@
|
||||
export default {
|
||||
'app.settings.menuMap.basic': 'মৌলিক বৈশিষ্ট্যসহ',
|
||||
'app.settings.menuMap.security': 'নিরাপত্তা বিন্যাস',
|
||||
'app.settings.menuMap.binding': 'অ্যাকাউন্ট বাঁধাই',
|
||||
'app.settings.menuMap.notification': 'নতুন বার্তা বিজ্ঞপ্তি',
|
||||
'app.settings.basic.avatar': 'অবতার',
|
||||
'app.settings.basic.change-avatar': 'অবতার পরিবর্তন করুন',
|
||||
'app.settings.basic.email': 'ইমেইল',
|
||||
'app.settings.basic.email-message': 'আপনার ইমেইল ইনপুট করুন!',
|
||||
'app.settings.basic.nickname': 'ডাক নাম',
|
||||
'app.settings.basic.nickname-message': 'আপনার ডাকনামটি ইনপুট করুন!',
|
||||
'app.settings.basic.profile': 'ব্যক্তিগত প্রোফাইল',
|
||||
'app.settings.basic.profile-message': 'আপনার ব্যক্তিগত প্রোফাইল ইনপুট করুন!',
|
||||
'app.settings.basic.profile-placeholder': 'নিজের সাথে সংক্ষিপ্ত পরিচয়',
|
||||
'app.settings.basic.country': 'দেশ/অঞ্চল',
|
||||
'app.settings.basic.country-message': 'আপনার দেশ ইনপুট করুন!',
|
||||
'app.settings.basic.geographic': 'প্রদেশ বা শহর',
|
||||
'app.settings.basic.geographic-message': 'আপনার ভৌগলিক তথ্য ইনপুট করুন!',
|
||||
'app.settings.basic.address': 'রাস্তার ঠিকানা',
|
||||
'app.settings.basic.address-message': 'দয়া করে আপনার ঠিকানা ইনপুট করুন!',
|
||||
'app.settings.basic.phone': 'ফোন নম্বর',
|
||||
'app.settings.basic.phone-message': 'আপনার ফোন ইনপুট করুন!',
|
||||
'app.settings.basic.update': 'তথ্য হালনাগাদ',
|
||||
'app.settings.security.strong': 'শক্তিশালী',
|
||||
'app.settings.security.medium': 'মধ্যম',
|
||||
'app.settings.security.weak': 'দুর্বল',
|
||||
'app.settings.security.password': 'অ্যাকাউন্টের পাসওয়ার্ড',
|
||||
'app.settings.security.password-description': 'বর্তমান পাসওয়ার্ড শক্তি',
|
||||
'app.settings.security.phone': 'সুরক্ষা ফোন',
|
||||
'app.settings.security.phone-description': 'আবদ্ধ ফোন',
|
||||
'app.settings.security.question': 'নিরাপত্তা প্রশ্ন',
|
||||
'app.settings.security.question-description':
|
||||
'সুরক্ষা প্রশ্ন সেট করা নেই, এবং সুরক্ষা নীতি কার্যকরভাবে অ্যাকাউন্ট সুরক্ষা রক্ষা করতে পারে',
|
||||
'app.settings.security.email': 'ব্যাকআপ ইমেইল',
|
||||
'app.settings.security.email-description': 'বাউন্ড ইমেইল',
|
||||
'app.settings.security.mfa': 'MFA ডিভাইস',
|
||||
'app.settings.security.mfa-description':
|
||||
"আনবাউন্ড এমএফএ ডিভাইস, বাঁধাইয়ের পরে, দু'বার নিশ্চিত করা যায়",
|
||||
'app.settings.security.modify': 'পরিবর্তন করুন',
|
||||
'app.settings.security.set': 'সেট',
|
||||
'app.settings.security.bind': 'বাঁধাই',
|
||||
'app.settings.binding.taobao': 'বাঁধাই তাওবাও',
|
||||
'app.settings.binding.taobao-description': 'বর্তমানে আনবাউন্ড তাওবাও অ্যাকাউন্ট',
|
||||
'app.settings.binding.alipay': 'বাইন্ডিং আলিপে',
|
||||
'app.settings.binding.alipay-description': 'বর্তমানে আনবাউন্ড আলিপে অ্যাকাউন্ট',
|
||||
'app.settings.binding.dingding': 'বাঁধাই ডিঙ্গটালক',
|
||||
'app.settings.binding.dingding-description': 'বর্তমানে আনবাউন্ড ডিঙ্গটাল অ্যাকাউন্ট',
|
||||
'app.settings.binding.bind': 'বাঁধাই',
|
||||
'app.settings.notification.password': 'অ্যাকাউন্টের পাসওয়ার্ড',
|
||||
'app.settings.notification.password-description':
|
||||
'অন্যান্য ব্যবহারকারীর বার্তাগুলি স্টেশন চিঠি আকারে জানানো হবে',
|
||||
'app.settings.notification.messages': 'সিস্টেম বার্তা',
|
||||
'app.settings.notification.messages-description':
|
||||
'সিস্টেম বার্তাগুলি স্টেশন চিঠির আকারে জানানো হবে',
|
||||
'app.settings.notification.todo': 'করণীয় বিজ্ঞপ্তি',
|
||||
'app.settings.notification.todo-description': 'করণীয় তালিকাটি স্টেশন থেকে চিঠি আকারে জানানো হবে',
|
||||
'app.settings.open': 'খোলা',
|
||||
'app.settings.close': 'বন্ধ',
|
||||
};
|
24
frontend/src/locales/en-US.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import component from './en-US/component';
|
||||
import globalHeader from './en-US/globalHeader';
|
||||
import menu from './en-US/menu';
|
||||
import pages from './en-US/pages';
|
||||
import pwa from './en-US/pwa';
|
||||
import settingDrawer from './en-US/settingDrawer';
|
||||
import settings from './en-US/settings';
|
||||
export default {
|
||||
'navBar.lang': 'Languages',
|
||||
'layout.user.link.help': 'Help',
|
||||
'layout.user.link.privacy': 'Privacy',
|
||||
'layout.user.link.terms': 'Terms',
|
||||
'app.copyright.produced': 'Produced by RocketMQ',
|
||||
'app.preview.down.block': 'Download this page to your local project',
|
||||
'app.welcome.link.fetch-blocks': 'Get all block',
|
||||
'app.welcome.link.block-list': 'Quickly build standard, pages based on `block` development',
|
||||
...globalHeader,
|
||||
...menu,
|
||||
...settingDrawer,
|
||||
...settings,
|
||||
...pwa,
|
||||
...component,
|
||||
...pages,
|
||||
};
|
5
frontend/src/locales/en-US/component.js
Normal file
@@ -0,0 +1,5 @@
|
||||
export default {
|
||||
'component.tagSelect.expand': 'Expand',
|
||||
'component.tagSelect.collapse': 'Collapse',
|
||||
'component.tagSelect.all': 'All',
|
||||
};
|
17
frontend/src/locales/en-US/globalHeader.js
Normal file
@@ -0,0 +1,17 @@
|
||||
export default {
|
||||
'component.globalHeader.search': 'Search',
|
||||
'component.globalHeader.search.example1': 'Search example 1',
|
||||
'component.globalHeader.search.example2': 'Search example 2',
|
||||
'component.globalHeader.search.example3': 'Search example 3',
|
||||
'component.globalHeader.help': 'Help',
|
||||
'component.globalHeader.notification': 'Notification',
|
||||
'component.globalHeader.notification.empty': 'You have viewed all notifications.',
|
||||
'component.globalHeader.message': 'Message',
|
||||
'component.globalHeader.message.empty': 'You have viewed all messsages.',
|
||||
'component.globalHeader.event': 'Event',
|
||||
'component.globalHeader.event.empty': 'You have viewed all events.',
|
||||
'component.noticeIcon.clear': 'Clear',
|
||||
'component.noticeIcon.cleared': 'Cleared',
|
||||
'component.noticeIcon.empty': 'No notifications',
|
||||
'component.noticeIcon.view-more': 'View more',
|
||||
};
|
53
frontend/src/locales/en-US/menu.js
Normal file
@@ -0,0 +1,53 @@
|
||||
export default {
|
||||
'menu.welcome': 'Welcome',
|
||||
'menu.more-blocks': 'More Blocks',
|
||||
'menu.home': 'Home',
|
||||
'menu.admin': 'Admin',
|
||||
'menu.admin.sub-page': 'Sub-Page',
|
||||
'menu.login': 'Login',
|
||||
'menu.register': 'Register',
|
||||
'menu.register-result': 'Register Result',
|
||||
'menu.dashboard': 'Dashboard',
|
||||
'menu.dashboard.analysis': 'Analysis',
|
||||
'menu.dashboard.monitor': 'Monitor',
|
||||
'menu.dashboard.workplace': 'Workplace',
|
||||
'menu.exception.403': '403',
|
||||
'menu.exception.404': '404',
|
||||
'menu.exception.500': '500',
|
||||
'menu.form': 'Form',
|
||||
'menu.form.basic-form': 'Basic Form',
|
||||
'menu.form.step-form': 'Step Form',
|
||||
'menu.form.step-form.info': 'Step Form(write transfer information)',
|
||||
'menu.form.step-form.confirm': 'Step Form(confirm transfer information)',
|
||||
'menu.form.step-form.result': 'Step Form(finished)',
|
||||
'menu.form.advanced-form': 'Advanced Form',
|
||||
'menu.list': 'List',
|
||||
'menu.list.cluster': 'Cluster',
|
||||
'menu.list.table-list': 'Search Table',
|
||||
'menu.list.basic-list': 'Basic List',
|
||||
'menu.list.card-list': 'Card List',
|
||||
'menu.list.search-list': 'Search List',
|
||||
'menu.list.search-list.articles': 'Search List(articles)',
|
||||
'menu.list.search-list.projects': 'Search List(projects)',
|
||||
'menu.list.search-list.applications': 'Search List(applications)',
|
||||
'menu.profile': 'Profile',
|
||||
'menu.profile.basic': 'Basic Profile',
|
||||
'menu.profile.advanced': 'Advanced Profile',
|
||||
'menu.result': 'Result',
|
||||
'menu.result.success': 'Success',
|
||||
'menu.result.fail': 'Fail',
|
||||
'menu.exception': 'Exception',
|
||||
'menu.exception.not-permission': '403',
|
||||
'menu.exception.not-find': '404',
|
||||
'menu.exception.server-error': '500',
|
||||
'menu.exception.trigger': 'Trigger',
|
||||
'menu.account': 'Account',
|
||||
'menu.account.center': 'Account Center',
|
||||
'menu.account.settings': 'Account Settings',
|
||||
'menu.account.trigger': 'Trigger Error',
|
||||
'menu.account.logout': 'Logout',
|
||||
'menu.editor': 'Graphic Editor',
|
||||
'menu.editor.flow': 'Flow Editor',
|
||||
'menu.editor.mind': 'Mind Editor',
|
||||
'menu.editor.koni': 'Koni Editor',
|
||||
};
|
70
frontend/src/locales/en-US/pages.js
Normal file
@@ -0,0 +1,70 @@
|
||||
export default {
|
||||
'pages.layouts.userLayout.title':
|
||||
'Ant Design is the most influential web design specification in Xihu district',
|
||||
'pages.login.accountLogin.tab': 'Account Login',
|
||||
'pages.login.accountLogin.errorMessage': 'Incorrect username/password(admin/ant.design)',
|
||||
'pages.login.failure': 'Login failed, please try again!',
|
||||
'pages.login.success': 'Login successful!',
|
||||
'pages.login.username.placeholder': 'Username: admin or user',
|
||||
'pages.login.username.required': 'Please input your username!',
|
||||
'pages.login.password.placeholder': 'Password: ant.design',
|
||||
'pages.login.password.required': 'Please input your password!',
|
||||
'pages.login.phoneLogin.tab': 'Phone Login',
|
||||
'pages.login.phoneLogin.errorMessage': 'Verification Code Error',
|
||||
'pages.login.phoneNumber.placeholder': 'Phone Number',
|
||||
'pages.login.phoneNumber.required': 'Please input your phone number!',
|
||||
'pages.login.phoneNumber.invalid': 'Phone number is invalid!',
|
||||
'pages.login.captcha.placeholder': 'Verification Code',
|
||||
'pages.login.captcha.required': 'Please input verification code!',
|
||||
'pages.login.phoneLogin.getVerificationCode': 'Get Code',
|
||||
'pages.getCaptchaSecondText': 'sec(s)',
|
||||
'pages.login.rememberMe': 'Remember me',
|
||||
'pages.login.forgotPassword': 'Forgot Password ?',
|
||||
'pages.login.submit': 'Login',
|
||||
'pages.login.loginWith': 'Login with :',
|
||||
'pages.login.registerAccount': 'Register Account',
|
||||
'pages.welcome.advancedComponent': 'Advanced Component',
|
||||
'pages.welcome.link': 'Welcome',
|
||||
'pages.welcome.advancedLayout': 'Advanced Layout',
|
||||
'pages.welcome.alertMessage': 'Faster and stronger heavy-duty components have been released.',
|
||||
'pages.admin.subPage.title': 'This page can only be viewed by Admin',
|
||||
'pages.admin.subPage.alertMessage':
|
||||
'Umi ui is now released, welcome to use npm run ui to start the experience.',
|
||||
'pages.searchTable.createForm.newRule': 'New Rule',
|
||||
'pages.searchTable.updateForm.ruleConfig': 'Rule configuration',
|
||||
'pages.searchTable.updateForm.basicConfig': 'Basic Information',
|
||||
'pages.searchTable.updateForm.ruleName.nameLabel': 'Rule Name',
|
||||
'pages.searchTable.updateForm.ruleName.nameRules': 'Please enter the rule name!',
|
||||
'pages.searchTable.updateForm.ruleDesc.descLabel': 'Rule Description',
|
||||
'pages.searchTable.updateForm.ruleDesc.descPlaceholder': 'Please enter at least five characters',
|
||||
'pages.searchTable.updateForm.ruleDesc.descRules':
|
||||
'Please enter a rule description of at least five characters!',
|
||||
'pages.searchTable.updateForm.ruleProps.title': 'Configure Properties',
|
||||
'pages.searchTable.updateForm.object': 'Monitoring Object',
|
||||
'pages.searchTable.updateForm.ruleProps.templateLabel': 'Rule Template',
|
||||
'pages.searchTable.updateForm.ruleProps.typeLabel': 'Rule Type',
|
||||
'pages.searchTable.updateForm.schedulingPeriod.title': 'Set Scheduling Period',
|
||||
'pages.searchTable.updateForm.schedulingPeriod.timeLabel': 'Starting Time',
|
||||
'pages.searchTable.updateForm.schedulingPeriod.timeRules': 'Please choose a start time!',
|
||||
'pages.searchTable.titleDesc': 'Description',
|
||||
'pages.searchTable.ruleName': 'Rule name is required',
|
||||
'pages.searchTable.titleCallNo': 'Number of Service Calls',
|
||||
'pages.searchTable.titleStatus': 'Status',
|
||||
'pages.searchTable.nameStatus.default': 'default',
|
||||
'pages.searchTable.nameStatus.running': 'running',
|
||||
'pages.searchTable.nameStatus.online': 'online',
|
||||
'pages.searchTable.nameStatus.abnormal': 'abnormal',
|
||||
'pages.searchTable.titleUpdatedAt': 'Last Scheduled at',
|
||||
'pages.searchTable.exception': 'Please enter the reason for the exception!',
|
||||
'pages.searchTable.titleOption': 'Option',
|
||||
'pages.searchTable.config': 'Configuration',
|
||||
'pages.searchTable.subscribeAlert': 'Subscribe to alerts',
|
||||
'pages.searchTable.title': 'Enquiry Form',
|
||||
'pages.searchTable.new': 'New',
|
||||
'pages.searchTable.chosen': 'chosen',
|
||||
'pages.searchTable.item': 'item',
|
||||
'pages.searchTable.totalServiceCalls': 'Total Number of Service Calls',
|
||||
'pages.searchTable.tenThousand': '0000',
|
||||
'pages.searchTable.batchDeletion': 'bacth deletion',
|
||||
'pages.searchTable.batchApproval': 'batch approval',
|
||||
};
|
6
frontend/src/locales/en-US/pwa.js
Normal file
@@ -0,0 +1,6 @@
|
||||
export default {
|
||||
'app.pwa.offline': 'You are offline now',
|
||||
'app.pwa.serviceworker.updated': 'New content is available',
|
||||
'app.pwa.serviceworker.updated.hint': 'Please press the "Refresh" button to reload current page',
|
||||
'app.pwa.serviceworker.updated.ok': 'Refresh',
|
||||
};
|
31
frontend/src/locales/en-US/settingDrawer.js
Normal file
@@ -0,0 +1,31 @@
|
||||
export default {
|
||||
'app.setting.pagestyle': 'Page style setting',
|
||||
'app.setting.pagestyle.dark': 'Dark style',
|
||||
'app.setting.pagestyle.light': 'Light style',
|
||||
'app.setting.content-width': 'Content Width',
|
||||
'app.setting.content-width.fixed': 'Fixed',
|
||||
'app.setting.content-width.fluid': 'Fluid',
|
||||
'app.setting.themecolor': 'Theme Color',
|
||||
'app.setting.themecolor.dust': 'Dust Red',
|
||||
'app.setting.themecolor.volcano': 'Volcano',
|
||||
'app.setting.themecolor.sunset': 'Sunset Orange',
|
||||
'app.setting.themecolor.cyan': 'Cyan',
|
||||
'app.setting.themecolor.green': 'Polar Green',
|
||||
'app.setting.themecolor.daybreak': 'Daybreak Blue (default)',
|
||||
'app.setting.themecolor.geekblue': 'Geek Glue',
|
||||
'app.setting.themecolor.purple': 'Golden Purple',
|
||||
'app.setting.navigationmode': 'Navigation Mode',
|
||||
'app.setting.sidemenu': 'Side Menu Layout',
|
||||
'app.setting.topmenu': 'Top Menu Layout',
|
||||
'app.setting.fixedheader': 'Fixed Header',
|
||||
'app.setting.fixedsidebar': 'Fixed Sidebar',
|
||||
'app.setting.fixedsidebar.hint': 'Works on Side Menu Layout',
|
||||
'app.setting.hideheader': 'Hidden Header when scrolling',
|
||||
'app.setting.hideheader.hint': 'Works when Hidden Header is enabled',
|
||||
'app.setting.othersettings': 'Other Settings',
|
||||
'app.setting.weakmode': 'Weak Mode',
|
||||
'app.setting.copy': 'Copy Setting',
|
||||
'app.setting.copyinfo': 'copy success,please replace defaultSettings in src/models/setting.js',
|
||||
'app.setting.production.hint':
|
||||
'Setting panel shows in development environment only, please manually modify',
|
||||
};
|
60
frontend/src/locales/en-US/settings.js
Normal file
@@ -0,0 +1,60 @@
|
||||
export default {
|
||||
'app.settings.menuMap.basic': 'Basic Settings',
|
||||
'app.settings.menuMap.security': 'Security Settings',
|
||||
'app.settings.menuMap.binding': 'Account Binding',
|
||||
'app.settings.menuMap.notification': 'New Message Notification',
|
||||
'app.settings.basic.avatar': 'Avatar',
|
||||
'app.settings.basic.change-avatar': 'Change avatar',
|
||||
'app.settings.basic.email': 'Email',
|
||||
'app.settings.basic.email-message': 'Please input your email!',
|
||||
'app.settings.basic.nickname': 'Nickname',
|
||||
'app.settings.basic.nickname-message': 'Please input your Nickname!',
|
||||
'app.settings.basic.profile': 'Personal profile',
|
||||
'app.settings.basic.profile-message': 'Please input your personal profile!',
|
||||
'app.settings.basic.profile-placeholder': 'Brief introduction to yourself',
|
||||
'app.settings.basic.country': 'Country/Region',
|
||||
'app.settings.basic.country-message': 'Please input your country!',
|
||||
'app.settings.basic.geographic': 'Province or city',
|
||||
'app.settings.basic.geographic-message': 'Please input your geographic info!',
|
||||
'app.settings.basic.address': 'Street Address',
|
||||
'app.settings.basic.address-message': 'Please input your address!',
|
||||
'app.settings.basic.phone': 'Phone Number',
|
||||
'app.settings.basic.phone-message': 'Please input your phone!',
|
||||
'app.settings.basic.update': 'Update Information',
|
||||
'app.settings.security.strong': 'Strong',
|
||||
'app.settings.security.medium': 'Medium',
|
||||
'app.settings.security.weak': 'Weak',
|
||||
'app.settings.security.password': 'Account Password',
|
||||
'app.settings.security.password-description': 'Current password strength',
|
||||
'app.settings.security.phone': 'Security Phone',
|
||||
'app.settings.security.phone-description': 'Bound phone',
|
||||
'app.settings.security.question': 'Security Question',
|
||||
'app.settings.security.question-description':
|
||||
'The security question is not set, and the security policy can effectively protect the account security',
|
||||
'app.settings.security.email': 'Backup Email',
|
||||
'app.settings.security.email-description': 'Bound Email',
|
||||
'app.settings.security.mfa': 'MFA Device',
|
||||
'app.settings.security.mfa-description':
|
||||
'Unbound MFA device, after binding, can be confirmed twice',
|
||||
'app.settings.security.modify': 'Modify',
|
||||
'app.settings.security.set': 'Set',
|
||||
'app.settings.security.bind': 'Bind',
|
||||
'app.settings.binding.taobao': 'Binding Taobao',
|
||||
'app.settings.binding.taobao-description': 'Currently unbound Taobao account',
|
||||
'app.settings.binding.alipay': 'Binding Alipay',
|
||||
'app.settings.binding.alipay-description': 'Currently unbound Alipay account',
|
||||
'app.settings.binding.dingding': 'Binding DingTalk',
|
||||
'app.settings.binding.dingding-description': 'Currently unbound DingTalk account',
|
||||
'app.settings.binding.bind': 'Bind',
|
||||
'app.settings.notification.password': 'Account Password',
|
||||
'app.settings.notification.password-description':
|
||||
'Messages from other users will be notified in the form of a station letter',
|
||||
'app.settings.notification.messages': 'System Messages',
|
||||
'app.settings.notification.messages-description':
|
||||
'System messages will be notified in the form of a station letter',
|
||||
'app.settings.notification.todo': 'To-do Notification',
|
||||
'app.settings.notification.todo-description':
|
||||
'The to-do list will be notified in the form of a letter from the station',
|
||||
'app.settings.open': 'Open',
|
||||
'app.settings.close': 'Close',
|
||||
};
|
23
frontend/src/locales/fa-IR.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import component from './fa-IR/component';
|
||||
import globalHeader from './fa-IR/globalHeader';
|
||||
import menu from './fa-IR/menu';
|
||||
import pwa from './fa-IR/pwa';
|
||||
import settingDrawer from './fa-IR/settingDrawer';
|
||||
import settings from './fa-IR/settings';
|
||||
import pages from './fa-IR/pages';
|
||||
export default {
|
||||
'navBar.lang': 'زبان ها ',
|
||||
'layout.user.link.help': 'کمک',
|
||||
'layout.user.link.privacy': 'حریم خصوصی',
|
||||
'layout.user.link.terms': 'مقررات',
|
||||
'app.preview.down.block': 'این صفحه را در پروژه محلی خود بارگیری کنید',
|
||||
'app.welcome.link.fetch-blocks': 'دریافت تمام بلوک',
|
||||
'app.welcome.link.block-list': 'به سرعت صفحات استاندارد مبتنی بر توسعه "بلوک" را بسازید',
|
||||
...globalHeader,
|
||||
...menu,
|
||||
...settingDrawer,
|
||||
...settings,
|
||||
...pwa,
|
||||
...component,
|
||||
...pages,
|
||||
};
|
5
frontend/src/locales/fa-IR/component.js
Normal file
@@ -0,0 +1,5 @@
|
||||
export default {
|
||||
'component.tagSelect.expand': 'باز',
|
||||
'component.tagSelect.collapse': 'بسته ',
|
||||
'component.tagSelect.all': 'همه',
|
||||
};
|
17
frontend/src/locales/fa-IR/globalHeader.js
Normal file
@@ -0,0 +1,17 @@
|
||||
export default {
|
||||
'component.globalHeader.search': 'جستجو ',
|
||||
'component.globalHeader.search.example1': 'مثال 1 را جستجو کنید',
|
||||
'component.globalHeader.search.example2': 'مثال 2 را جستجو کنید',
|
||||
'component.globalHeader.search.example3': 'مثال 3 را جستجو کنید',
|
||||
'component.globalHeader.help': 'کمک',
|
||||
'component.globalHeader.notification': 'اعلان',
|
||||
'component.globalHeader.notification.empty': 'شما همه اعلان ها را مشاهده کرده اید.',
|
||||
'component.globalHeader.message': 'پیام',
|
||||
'component.globalHeader.message.empty': 'شما همه پیام ها را مشاهده کرده اید.',
|
||||
'component.globalHeader.event': 'رویداد',
|
||||
'component.globalHeader.event.empty': 'شما همه رویدادها را مشاهده کرده اید.',
|
||||
'component.noticeIcon.clear': 'پاک کردن',
|
||||
'component.noticeIcon.cleared': 'پاک شد',
|
||||
'component.noticeIcon.empty': 'بدون اعلان',
|
||||
'component.noticeIcon.view-more': 'نمایش بیشتر',
|
||||
};
|
52
frontend/src/locales/fa-IR/menu.js
Normal file
@@ -0,0 +1,52 @@
|
||||
export default {
|
||||
'menu.welcome': 'خوش آمدید',
|
||||
'menu.more-blocks': 'بلوک های بیشتر',
|
||||
'menu.home': 'خانه',
|
||||
'menu.admin': 'مدیر',
|
||||
'menu.admin.sub-page': 'زیر صفحه',
|
||||
'menu.login': 'ورود',
|
||||
'menu.register': 'ثبت نام',
|
||||
'menu.register-result': 'ثبت نام نتیجه',
|
||||
'menu.dashboard': 'داشبورد',
|
||||
'menu.dashboard.analysis': 'تحلیل و بررسی',
|
||||
'menu.dashboard.monitor': 'نظارت',
|
||||
'menu.dashboard.workplace': 'محل کار',
|
||||
'menu.exception.403': '403',
|
||||
'menu.exception.404': '404',
|
||||
'menu.exception.500': '500',
|
||||
'menu.form': 'فرم',
|
||||
'menu.form.basic-form': 'فرم اساسی',
|
||||
'menu.form.step-form': 'فرم مرحله',
|
||||
'menu.form.step-form.info': 'فرم مرحله (نوشتن اطلاعات انتقال)',
|
||||
'menu.form.step-form.confirm': 'فرم مرحله (تأیید اطلاعات انتقال)',
|
||||
'menu.form.step-form.result': 'فرم مرحله (تمام شده)',
|
||||
'menu.form.advanced-form': 'فرم پیشرفته',
|
||||
'menu.list': 'لیست',
|
||||
'menu.list.table-list': 'جدول جستجو',
|
||||
'menu.list.basic-list': 'لیست اصلی',
|
||||
'menu.list.card-list': 'لیست کارت',
|
||||
'menu.list.search-list': 'لیست جستجو',
|
||||
'menu.list.search-list.articles': 'لیست جستجو (مقالات)',
|
||||
'menu.list.search-list.projects': 'لیست جستجو (پروژه ها)',
|
||||
'menu.list.search-list.applications': 'لیست جستجو (برنامه ها)',
|
||||
'menu.profile': 'مشخصات',
|
||||
'menu.profile.basic': 'مشخصات عمومی',
|
||||
'menu.profile.advanced': 'مشخصات پیشرفته',
|
||||
'menu.result': 'نتیجه',
|
||||
'menu.result.success': 'موفق',
|
||||
'menu.result.fail': 'ناموفق',
|
||||
'menu.exception': 'استثنا',
|
||||
'menu.exception.not-permission': '403',
|
||||
'menu.exception.not-find': '404',
|
||||
'menu.exception.server-error': '500',
|
||||
'menu.exception.trigger': 'راه اندازی',
|
||||
'menu.account': 'حساب',
|
||||
'menu.account.center': 'مرکز حساب',
|
||||
'menu.account.settings': 'تنظیمات حساب',
|
||||
'menu.account.trigger': 'خطای راه اندازی',
|
||||
'menu.account.logout': 'خروج',
|
||||
'menu.editor': 'ویرایشگر گرافیک',
|
||||
'menu.editor.flow': 'ویرایشگر جریان',
|
||||
'menu.editor.mind': 'ویرایشگر ذهن',
|
||||
'menu.editor.koni': 'ویرایشگر Koni',
|
||||
};
|
67
frontend/src/locales/fa-IR/pages.js
Normal file
@@ -0,0 +1,67 @@
|
||||
export default {
|
||||
'pages.layouts.userLayout.title': 'طراحی مورچه تأثیرگذارترین مشخصات طراحی وب در منطقه Xihu است',
|
||||
'pages.login.accountLogin.tab': 'ورود به حساب کاربری',
|
||||
'pages.login.accountLogin.errorMessage': 'نام کاربری / رمزعبور نادرست (مدیر / ant.design)',
|
||||
'pages.login.username.placeholder': 'نام کاربری: مدیر یا کاربر',
|
||||
'pages.login.username.required': 'لطفا نام کاربری خود را وارد کنید!',
|
||||
'pages.login.password.placeholder': 'رمز عبور: ant.design',
|
||||
'pages.login.password.required': 'لطفاً رمز ورود خود را وارد کنید!',
|
||||
'pages.login.phoneLogin.tab': 'ورود به سیستم تلفن',
|
||||
'pages.login.phoneLogin.errorMessage': 'خطای کد تأیید',
|
||||
'pages.login.phoneNumber.placeholder': 'شماره تلفن',
|
||||
'pages.login.phoneNumber.required': 'لطفاً شماره تلفن خود را وارد کنید!',
|
||||
'pages.login.phoneNumber.invalid': 'شماره تلفن نامعتبر است!',
|
||||
'pages.login.captcha.placeholder': 'کد تایید',
|
||||
'pages.login.captcha.required': 'لطفا کد تأیید را وارد کنید!',
|
||||
'pages.login.phoneLogin.getVerificationCode': 'دریافت کد',
|
||||
'pages.getCaptchaSecondText': 'ثانیه',
|
||||
'pages.login.rememberMe': 'مرا به خاطر بسپار',
|
||||
'pages.login.forgotPassword': 'رمز عبور را فراموش کرده اید ?',
|
||||
'pages.login.submit': 'ارسال',
|
||||
'pages.login.loginWith': 'وارد شوید با :',
|
||||
'pages.login.registerAccount': 'ثبت نام',
|
||||
'pages.welcome.advancedComponent': 'مولفه پیشرفته',
|
||||
'pages.welcome.link': 'خوش آمدید',
|
||||
'pages.welcome.advancedLayout': 'چیدمان پیشرفته',
|
||||
'pages.welcome.alertMessage': 'اجزای سنگین تر سریعتر و قوی تر آزاد شده اند.',
|
||||
'pages.admin.subPage.title': 'این صفحه فقط توسط مدیر قابل مشاهده است',
|
||||
'pages.admin.subPage.alertMessage':
|
||||
'رابط کاربری Umi اکنون منتشر شده است ، برای شروع تجربه استفاده از npm run ui خوش آمدید.',
|
||||
'pages.searchTable.createForm.newRule': 'قانون جدید',
|
||||
'pages.searchTable.updateForm.ruleConfig': 'پیکربندی قانون',
|
||||
'pages.searchTable.updateForm.basicConfig': 'اطلاعات اولیه',
|
||||
'pages.searchTable.updateForm.ruleName.nameLabel': ' نام قانون',
|
||||
'pages.searchTable.updateForm.ruleName.nameRules': 'لطفاً نام قانون را وارد کنید!',
|
||||
'pages.searchTable.updateForm.ruleDesc.descLabel': 'شرح قانون',
|
||||
'pages.searchTable.updateForm.ruleDesc.descPlaceholder': 'لطفاً حداقل پنج حرف وارد کنید',
|
||||
'pages.searchTable.updateForm.ruleDesc.descRules':
|
||||
'لطفاً حداقل یک قانون حاوی پنج کاراکتر شرح دهید!',
|
||||
'pages.searchTable.updateForm.ruleProps.title': 'پیکربندی خصوصیات',
|
||||
'pages.searchTable.updateForm.object': 'نظارت بر شی',
|
||||
'pages.searchTable.updateForm.ruleProps.templateLabel': 'الگوی قانون',
|
||||
'pages.searchTable.updateForm.ruleProps.typeLabel': 'نوع قانون',
|
||||
'pages.searchTable.updateForm.schedulingPeriod.title': 'تنظیم دوره زمان بندی',
|
||||
'pages.searchTable.updateForm.schedulingPeriod.timeLabel': 'زمان شروع',
|
||||
'pages.searchTable.updateForm.schedulingPeriod.timeRules': 'لطفاً زمان شروع را انتخاب کنید!',
|
||||
'pages.searchTable.titleDesc': 'شرح',
|
||||
'pages.searchTable.ruleName': 'نام قانون لازم است',
|
||||
'pages.searchTable.titleCallNo': 'تعداد تماس های خدماتی',
|
||||
'pages.searchTable.titleStatus': 'وضعیت',
|
||||
'pages.searchTable.nameStatus.default': 'پیش فرض',
|
||||
'pages.searchTable.nameStatus.running': 'در حال دویدن',
|
||||
'pages.searchTable.nameStatus.online': 'برخط',
|
||||
'pages.searchTable.nameStatus.abnormal': 'غیرطبیعی',
|
||||
'pages.searchTable.titleUpdatedAt': 'آخرین برنامه ریزی در',
|
||||
'pages.searchTable.exception': 'لطفا دلیل استثنا را وارد کنید!',
|
||||
'pages.searchTable.titleOption': 'گزینه',
|
||||
'pages.searchTable.config': 'پیکربندی',
|
||||
'pages.searchTable.subscribeAlert': 'مشترک شدن در هشدارها',
|
||||
'pages.searchTable.title': 'فرم درخواست',
|
||||
'pages.searchTable.new': 'جدید',
|
||||
'pages.searchTable.chosen': 'انتخاب شده',
|
||||
'pages.searchTable.item': 'مورد',
|
||||
'pages.searchTable.totalServiceCalls': 'تعداد کل تماس های خدماتی',
|
||||
'pages.searchTable.tenThousand': '0000',
|
||||
'pages.searchTable.batchDeletion': 'حذف دسته ای',
|
||||
'pages.searchTable.batchApproval': 'تصویب دسته ای',
|
||||
};
|
7
frontend/src/locales/fa-IR/pwa.js
Normal file
@@ -0,0 +1,7 @@
|
||||
export default {
|
||||
'app.pwa.offline': 'شما اکنون آفلاین هستید',
|
||||
'app.pwa.serviceworker.updated': 'مطالب جدید در دسترس است',
|
||||
'app.pwa.serviceworker.updated.hint':
|
||||
'لطفاً برای بارگیری مجدد صفحه فعلی ، دکمه "تازه سازی" را فشار دهید',
|
||||
'app.pwa.serviceworker.updated.ok': 'تازه سازی',
|
||||
};
|
32
frontend/src/locales/fa-IR/settingDrawer.js
Normal file
@@ -0,0 +1,32 @@
|
||||
export default {
|
||||
'app.setting.pagestyle': 'تنظیم نوع صفحه',
|
||||
'app.setting.pagestyle.dark': 'سبک تیره',
|
||||
'app.setting.pagestyle.light': 'سبک سبک',
|
||||
'app.setting.content-width': 'عرض محتوا',
|
||||
'app.setting.content-width.fixed': 'ثابت',
|
||||
'app.setting.content-width.fluid': 'شناور',
|
||||
'app.setting.themecolor': 'رنگ تم',
|
||||
'app.setting.themecolor.dust': 'گرد و غبار قرمز',
|
||||
'app.setting.themecolor.volcano': 'آتشفشان',
|
||||
'app.setting.themecolor.sunset': 'غروب نارنجی',
|
||||
'app.setting.themecolor.cyan': 'فیروزه ای',
|
||||
'app.setting.themecolor.green': 'سبز قطبی',
|
||||
'app.setting.themecolor.daybreak': 'آبی روشن(پیشفرض)',
|
||||
'app.setting.themecolor.geekblue': 'چسب گیک',
|
||||
'app.setting.themecolor.purple': 'بنفش طلایی',
|
||||
'app.setting.navigationmode': 'حالت پیمایش',
|
||||
'app.setting.sidemenu': 'طرح منوی کناری',
|
||||
'app.setting.topmenu': 'طرح منوی بالایی',
|
||||
'app.setting.fixedheader': 'سرصفحه ثابت',
|
||||
'app.setting.fixedsidebar': 'نوار کناری ثابت',
|
||||
'app.setting.fixedsidebar.hint': 'کار بر روی منوی کناری',
|
||||
'app.setting.hideheader': 'هدر پنهان هنگام پیمایش',
|
||||
'app.setting.hideheader.hint': 'وقتی Hidden Header فعال باشد کار می کند',
|
||||
'app.setting.othersettings': 'تنظیمات دیگر',
|
||||
'app.setting.weakmode': 'حالت ضعیف',
|
||||
'app.setting.copy': 'تنظیمات کپی',
|
||||
'app.setting.copyinfo':
|
||||
'موفقیت در کپی کردن , لطفا defaultSettings را در src / models / setting.js جایگزین کنید',
|
||||
'app.setting.production.hint':
|
||||
'صفحه تنظیم فقط در محیط توسعه نمایش داده می شود ، لطفاً دستی تغییر دهید',
|
||||
};
|
60
frontend/src/locales/fa-IR/settings.js
Normal file
@@ -0,0 +1,60 @@
|
||||
export default {
|
||||
'app.settings.menuMap.basic': 'تنظیمات پایه ',
|
||||
'app.settings.menuMap.security': 'تنظیمات امنیتی',
|
||||
'app.settings.menuMap.binding': 'صحافی حساب',
|
||||
'app.settings.menuMap.notification': 'اعلان پیام جدید',
|
||||
'app.settings.basic.avatar': 'آواتار',
|
||||
'app.settings.basic.change-avatar': 'آواتار را تغییر دهید',
|
||||
'app.settings.basic.email': 'ایمیل',
|
||||
'app.settings.basic.email-message': 'لطفا ایمیل خود را وارد کنید!',
|
||||
'app.settings.basic.nickname': 'نام مستعار',
|
||||
'app.settings.basic.nickname-message': 'لطفاً نام مستعار خود را وارد کنید!',
|
||||
'app.settings.basic.profile': 'پروفایل شخصی',
|
||||
'app.settings.basic.profile-message': 'لطفاً مشخصات شخصی خود را وارد کنید!',
|
||||
'app.settings.basic.profile-placeholder': 'معرفی مختصر خودتان',
|
||||
'app.settings.basic.country': 'کشور / منطقه',
|
||||
'app.settings.basic.country-message': 'لطفاً کشور خود را وارد کنید!',
|
||||
'app.settings.basic.geographic': 'استان یا شهر',
|
||||
'app.settings.basic.geographic-message': 'لطفاً اطلاعات جغرافیایی خود را وارد کنید!',
|
||||
'app.settings.basic.address': 'آدرس خیابان',
|
||||
'app.settings.basic.address-message': 'لطفا آدرس خود را وارد کنید!',
|
||||
'app.settings.basic.phone': 'شماره تلفن',
|
||||
'app.settings.basic.phone-message': 'لطفاً تلفن خود را وارد کنید!',
|
||||
'app.settings.basic.update': 'به روز رسانی اطلاعات',
|
||||
'app.settings.security.strong': 'قوی',
|
||||
'app.settings.security.medium': 'متوسط',
|
||||
'app.settings.security.weak': 'ضعیف',
|
||||
'app.settings.security.password': 'رمز عبور حساب کاربری',
|
||||
'app.settings.security.password-description': 'قدرت رمز عبور فعلی',
|
||||
'app.settings.security.phone': 'تلفن امنیتی',
|
||||
'app.settings.security.phone-description': 'تلفن مقید',
|
||||
'app.settings.security.question': 'سوال امنیتی',
|
||||
'app.settings.security.question-description':
|
||||
'سوال امنیتی تنظیم نشده است و سیاست امنیتی می تواند به طور موثر از امنیت حساب محافظت کند',
|
||||
'app.settings.security.email': 'ایمیل پشتیبان',
|
||||
'app.settings.security.email-description': 'ایمیل مقید',
|
||||
'app.settings.security.mfa': 'دستگاه MFA',
|
||||
'app.settings.security.mfa-description':
|
||||
'دستگاه MFA بسته نشده ، پس از اتصال ، می تواند دو بار تأیید شود',
|
||||
'app.settings.security.modify': 'تغییر',
|
||||
'app.settings.security.set': 'تنظیم',
|
||||
'app.settings.security.bind': 'بستن',
|
||||
'app.settings.binding.taobao': 'اتصال Taobao',
|
||||
'app.settings.binding.taobao-description': 'حساب Taobao در حال حاضر بسته نشده است',
|
||||
'app.settings.binding.alipay': 'اتصال Alipay',
|
||||
'app.settings.binding.alipay-description': 'حساب Alipay در حال حاضر بسته نشده است',
|
||||
'app.settings.binding.dingding': 'اتصال DingTalk',
|
||||
'app.settings.binding.dingding-description': 'حساب DingTalk در حال حاضر محدود نشده است',
|
||||
'app.settings.binding.bind': 'بستن',
|
||||
'app.settings.notification.password': 'رمز عبور حساب کاربری',
|
||||
'app.settings.notification.password-description':
|
||||
'پیام های سایر کاربران در قالب یک نامه ایستگاهی اعلام خواهد شد',
|
||||
'app.settings.notification.messages': 'پیام های سیستم',
|
||||
'app.settings.notification.messages-description':
|
||||
'پیام های سیستم به صورت نامه ایستگاه مطلع می شوند',
|
||||
'app.settings.notification.todo': 'اعلان کارها',
|
||||
'app.settings.notification.todo-description':
|
||||
'لیست کارها به صورت نامه ای از ایستگاه اطلاع داده می شود',
|
||||
'app.settings.open': 'باز کن',
|
||||
'app.settings.close': 'بستن',
|
||||
};
|
24
frontend/src/locales/id-ID.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import component from './id-ID/component';
|
||||
import globalHeader from './id-ID/globalHeader';
|
||||
import menu from './id-ID/menu';
|
||||
import pwa from './id-ID/pwa';
|
||||
import settingDrawer from './id-ID/settingDrawer';
|
||||
import settings from './id-ID/settings';
|
||||
import pages from './id-ID/pages';
|
||||
export default {
|
||||
'navbar.lang': 'Bahasa',
|
||||
'layout.user.link.help': 'Bantuan',
|
||||
'layout.user.link.privacy': 'Privasi',
|
||||
'layout.user.link.terms': 'Ketentuan',
|
||||
'app.preview.down.block': 'Unduh halaman ini dalam projek lokal anda',
|
||||
'app.welcome.link.fetch-blocks': 'Dapatkan semua blok',
|
||||
'app.welcome.link.block-list':
|
||||
'Buat standar dengan cepat, halaman-halaman berdasarkan pengembangan `block`',
|
||||
...globalHeader,
|
||||
...menu,
|
||||
...settingDrawer,
|
||||
...settings,
|
||||
...pwa,
|
||||
...component,
|
||||
...pages,
|
||||
};
|
5
frontend/src/locales/id-ID/component.js
Normal file
@@ -0,0 +1,5 @@
|
||||
export default {
|
||||
'component.tagSelect.expand': 'Perluas',
|
||||
'component.tagSelect.collapse': 'Lipat',
|
||||
'component.tagSelect.all': 'Semua',
|
||||
};
|
17
frontend/src/locales/id-ID/globalHeader.js
Normal file
@@ -0,0 +1,17 @@
|
||||
export default {
|
||||
'component.globalHeader.search': 'Pencarian',
|
||||
'component.globalHeader.search.example1': 'Contoh 1 Pencarian',
|
||||
'component.globalHeader.search.example2': 'Contoh 2 Pencarian',
|
||||
'component.globalHeader.search.example3': 'Contoh 3 Pencarian',
|
||||
'component.globalHeader.help': 'Bantuan',
|
||||
'component.globalHeader.notification': 'Notifikasi',
|
||||
'component.globalHeader.notification.empty': 'Anda telah membaca semua notifikasi',
|
||||
'component.globalHeader.message': 'Pesan',
|
||||
'component.globalHeader.message.empty': 'Anda telah membaca semua pesan.',
|
||||
'component.globalHeader.event': 'Acara',
|
||||
'component.globalHeader.event.empty': 'Anda telah melihat semua acara.',
|
||||
'component.noticeIcon.clear': 'Kosongkan',
|
||||
'component.noticeIcon.cleared': 'Berhasil dikosongkan',
|
||||
'component.noticeIcon.empty': 'Tidak ada pemberitahuan',
|
||||
'component.noticeIcon.view-more': 'Melihat lebih',
|
||||
};
|
52
frontend/src/locales/id-ID/menu.js
Normal file
@@ -0,0 +1,52 @@
|
||||
export default {
|
||||
'menu.welcome': 'Selamat Datang',
|
||||
'menu.more-blocks': 'Blocks Lainnya',
|
||||
'menu.home': 'Halaman Awal',
|
||||
'menu.admin': 'Admin',
|
||||
'menu.admin.sub-page': 'Sub-Halaman',
|
||||
'menu.login': 'Masuk',
|
||||
'menu.register': 'Pendaftaran',
|
||||
'menu.register-result': 'Hasil Pendaftaran',
|
||||
'menu.dashboard': 'Dasbor',
|
||||
'menu.dashboard.analysis': 'Analisis',
|
||||
'menu.dashboard.monitor': 'Monitor',
|
||||
'menu.dashboard.workplace': 'Workplace',
|
||||
'menu.exception.403': '403',
|
||||
'menu.exception.404': '404',
|
||||
'menu.exception.500': '500',
|
||||
'menu.form': 'Form',
|
||||
'menu.form.basic-form': 'Form Dasar',
|
||||
'menu.form.step-form': 'Form Bertahap',
|
||||
'menu.form.step-form.info': 'Form Bertahap(menulis informasi yang dibagikan)',
|
||||
'menu.form.step-form.confirm': 'Form Bertahap(konfirmasi informasi yang dibagikan)',
|
||||
'menu.form.step-form.result': 'Form Bertahap(selesai)',
|
||||
'menu.form.advanced-form': 'Form Lanjutan',
|
||||
'menu.list': 'Daftar',
|
||||
'menu.list.table-list': 'Tabel Pencarian',
|
||||
'menu.list.basic-list': 'Daftar Dasar',
|
||||
'menu.list.card-list': 'Daftar Kartu',
|
||||
'menu.list.search-list': 'Daftar Pencarian',
|
||||
'menu.list.search-list.articles': 'Daftar Pencarian(artikel)',
|
||||
'menu.list.search-list.projects': 'Daftar Pencarian(projek)',
|
||||
'menu.list.search-list.applications': 'Daftar Pencarian(aplikasi)',
|
||||
'menu.profile': 'Profil',
|
||||
'menu.profile.basic': 'Profil Dasar',
|
||||
'menu.profile.advanced': 'Profile Lanjutan',
|
||||
'menu.result': 'Hasil',
|
||||
'menu.result.success': 'Sukses',
|
||||
'menu.result.fail': 'Gagal',
|
||||
'menu.exception': 'Pengecualian',
|
||||
'menu.exception.not-permission': '403',
|
||||
'menu.exception.not-find': '404',
|
||||
'menu.exception.server-error': '500',
|
||||
'menu.exception.trigger': 'Jalankan',
|
||||
'menu.account': 'Akun',
|
||||
'menu.account.center': 'Detail Akun',
|
||||
'menu.account.settings': 'Pengaturan Akun',
|
||||
'menu.account.trigger': 'Mengaktivasi Error',
|
||||
'menu.account.logout': 'Keluar',
|
||||
'menu.editor': 'Penyusun Grafis',
|
||||
'menu.editor.flow': 'Penyusun Alur',
|
||||
'menu.editor.mind': 'Penyusun Mind',
|
||||
'menu.editor.koni': 'Penyusun Koni',
|
||||
};
|
70
frontend/src/locales/id-ID/pages.js
Normal file
@@ -0,0 +1,70 @@
|
||||
export default {
|
||||
'pages.layouts.userLayout.title':
|
||||
'Ant Design adalah spesifikasi desain Web yang paling berpengaruh di Kabupaten Xihu',
|
||||
'pages.login.accountLogin.tab': 'Login dengan akun',
|
||||
'pages.login.accountLogin.errorMessage': 'Nama pengguna dan kata sandi salah(admin/ant.design)',
|
||||
'pages.login.username.placeholder': 'nama pengguna: admin atau user',
|
||||
'pages.login.username.required': 'Nama pengguna harus diisi!',
|
||||
'pages.login.password.placeholder': 'kata sandi: ant.design',
|
||||
'pages.login.password.required': 'Kata sandi harus diisi!',
|
||||
'pages.login.phoneLogin.tab': 'Login dengan ponsel',
|
||||
'pages.login.phoneLogin.errorMessage': 'Kesalahan kode verifikasi',
|
||||
'pages.login.phoneNumber.placeholder': 'masukkan nomor telepon',
|
||||
'pages.login.phoneNumber.required': 'Nomor ponsel harus diisi!',
|
||||
'pages.login.phoneNumber.invalid': 'Nomor ponsel tidak valid!',
|
||||
'pages.login.captcha.placeholder': 'kode verifikasi',
|
||||
'pages.login.captcha.required': 'Kode verifikasi diperlukan!',
|
||||
'pages.login.phoneLogin.getVerificationCode': 'Dapatkan kode',
|
||||
'pages.getCaptchaSecondText': 'detik tersisa',
|
||||
'pages.login.rememberMe': 'Ingat saya',
|
||||
'pages.login.forgotPassword': 'Lupa Kata Sandi?',
|
||||
'pages.login.submit': 'Masuk',
|
||||
'pages.login.loginWith': 'Masuk dengan :',
|
||||
'pages.login.registerAccount': 'Daftar Akun',
|
||||
'pages.welcome.advancedComponent': 'Formulir Lanjutan',
|
||||
'pages.welcome.link': 'Selamat datang',
|
||||
'pages.welcome.advancedLayout': 'Tata letak Lanjutan',
|
||||
'pages.welcome.alertMessage':
|
||||
'Komponen heavy-duty yang lebih cepat dan lebih kuat telah dirilis.',
|
||||
'pages.admin.subPage.title': 'Halaman ini hanya dapat dilihat oleh admin',
|
||||
'pages.admin.subPage.alertMessage':
|
||||
'umi ui telah dirilis, silahkan gunakan npm run ui untuk memulai pengalaman.',
|
||||
'pages.searchTable.createForm.newRule': 'Aturan baru',
|
||||
'pages.searchTable.updateForm.ruleConfig': 'Konfigurasi aturan',
|
||||
'pages.searchTable.updateForm.basicConfig': 'Informasi dasar',
|
||||
'pages.searchTable.updateForm.ruleName.nameLabel': 'Nama aturan',
|
||||
'pages.searchTable.updateForm.ruleName.nameRules': 'Harap masukkan nama aturan!',
|
||||
'pages.searchTable.updateForm.ruleDesc.descLabel': 'Deskripsi aturan',
|
||||
'pages.searchTable.updateForm.ruleDesc.descPlaceholder':
|
||||
'Harap masukkan setidaknya lima karakter',
|
||||
'pages.searchTable.updateForm.ruleDesc.descRules':
|
||||
'Harap masukkan deskripsi aturan setidaknya lima karakter!',
|
||||
'pages.searchTable.updateForm.ruleProps.title': 'Properti aturan',
|
||||
'pages.searchTable.updateForm.object': 'Objek pemantauan',
|
||||
'pages.searchTable.updateForm.ruleProps.templateLabel': 'Template aturan',
|
||||
'pages.searchTable.updateForm.ruleProps.typeLabel': 'Jenis aturan',
|
||||
'pages.searchTable.updateForm.schedulingPeriod.title': 'Periode penjadwalan',
|
||||
'pages.searchTable.updateForm.schedulingPeriod.timeLabel': 'Waktu mulai',
|
||||
'pages.searchTable.updateForm.schedulingPeriod.timeRules': 'Pilih waktu mulai!',
|
||||
'pages.searchTable.titleDesc': 'deskripsi',
|
||||
'pages.searchTable.ruleName': 'Nama aturan wajib diisi',
|
||||
'pages.searchTable.titleCallNo': 'Jumlah panggilan',
|
||||
'pages.searchTable.titleStatus': 'Status',
|
||||
'pages.searchTable.nameStatus.default': 'default',
|
||||
'pages.searchTable.nameStatus.running': 'menyala',
|
||||
'pages.searchTable.nameStatus.online': 'online',
|
||||
'pages.searchTable.nameStatus.abnormal': 'abnormal',
|
||||
'pages.searchTable.titleUpdatedAt': 'Waktu terjadwal',
|
||||
'pages.searchTable.exception': 'Harap masukkan alasan pengecualian!',
|
||||
'pages.searchTable.titleOption': 'Pengoperasian',
|
||||
'pages.searchTable.config': 'Konfigurasi',
|
||||
'pages.searchTable.subscribeAlert': 'Berlangganan notifikasi',
|
||||
'pages.searchTable.title': 'Formulir pertanyaan',
|
||||
'pages.searchTable.new': 'Baru',
|
||||
'pages.searchTable.chosen': 'Terpilih',
|
||||
'pages.searchTable.item': 'item',
|
||||
'pages.searchTable.totalServiceCalls': 'Jumlah total panggilan layanan',
|
||||
'pages.searchTable.tenThousand': '0000',
|
||||
'pages.searchTable.batchDeletion': 'Penghapusan batch',
|
||||
'pages.searchTable.batchApproval': 'Persetujuan batch',
|
||||
};
|
7
frontend/src/locales/id-ID/pwa.js
Normal file
@@ -0,0 +1,7 @@
|
||||
export default {
|
||||
'app.pwa.offline': 'Koneksi anda terputus',
|
||||
'app.pwa.serviceworker.updated': 'Konten baru sudah tersedia',
|
||||
'app.pwa.serviceworker.updated.hint':
|
||||
'Silahkan klik tombol "Refresh" untuk memuat ulang halaman ini',
|
||||
'app.pwa.serviceworker.updated.ok': 'Memuat ulang',
|
||||
};
|
32
frontend/src/locales/id-ID/settingDrawer.js
Normal file
@@ -0,0 +1,32 @@
|
||||
export default {
|
||||
'app.setting.pagestyle': 'Pengaturan style Halaman',
|
||||
'app.setting.pagestyle.dark': 'Style Gelap',
|
||||
'app.setting.pagestyle.light': 'Style Cerah',
|
||||
'app.setting.content-width': 'Lebar Konten',
|
||||
'app.setting.content-width.fixed': 'Tetap',
|
||||
'app.setting.content-width.fluid': 'Fluid',
|
||||
'app.setting.themecolor': 'Theme Color',
|
||||
'app.setting.themecolor.dust': 'Dust Red',
|
||||
'app.setting.themecolor.volcano': 'Volcano',
|
||||
'app.setting.themecolor.sunset': 'Sunset Orange',
|
||||
'app.setting.themecolor.cyan': 'Cyan',
|
||||
'app.setting.themecolor.green': 'Polar Green',
|
||||
'app.setting.themecolor.daybreak': 'Daybreak Blue (bawaan)',
|
||||
'app.setting.themecolor.geekblue': 'Geek Glue',
|
||||
'app.setting.themecolor.purple': 'Golden Purple',
|
||||
'app.setting.navigationmode': 'Mode Navigasi',
|
||||
'app.setting.sidemenu': 'Susunan Menu Samping',
|
||||
'app.setting.topmenu': 'Susunan Menu Atas',
|
||||
'app.setting.fixedheader': 'Header Tetap',
|
||||
'app.setting.fixedsidebar': 'Sidebar Tetap',
|
||||
'app.setting.fixedsidebar.hint': 'Berjalan pada Susunan Menu Samping',
|
||||
'app.setting.hideheader': 'Sembunyikan Header ketika gulir ke bawah',
|
||||
'app.setting.hideheader.hint': 'Bekerja ketika Header tersembunyi dimunculkan',
|
||||
'app.setting.othersettings': 'Pengaturan Lainnya',
|
||||
'app.setting.weakmode': 'Mode Lemah',
|
||||
'app.setting.copy': 'Salin Pengaturan',
|
||||
'app.setting.copyinfo':
|
||||
'Berhasil disalin,tolong ubah defaultSettings pada src/models/setting.js',
|
||||
'app.setting.production.hint':
|
||||
'Panel pengaturan hanya muncul pada lingkungan pengembangan, silahkan modifikasi secara menual',
|
||||
};
|
60
frontend/src/locales/id-ID/settings.js
Normal file
@@ -0,0 +1,60 @@
|
||||
export default {
|
||||
'app.settings.menuMap.basic': 'Pengaturan Dasar',
|
||||
'app.settings.menuMap.security': 'Pengaturan Keamanan',
|
||||
'app.settings.menuMap.binding': 'Pengikatan Akun',
|
||||
'app.settings.menuMap.notification': 'Notifikasi Pesan Baru',
|
||||
'app.settings.basic.avatar': 'Avatar',
|
||||
'app.settings.basic.change-avatar': 'Ubah avatar',
|
||||
'app.settings.basic.email': 'Email',
|
||||
'app.settings.basic.email-message': 'Tolong masukkan email!',
|
||||
'app.settings.basic.nickname': 'Nickname',
|
||||
'app.settings.basic.nickname-message': 'Tolong masukkan Nickname!',
|
||||
'app.settings.basic.profile': 'Profil Personal',
|
||||
'app.settings.basic.profile-message': 'Tolong masukkan profil personal!',
|
||||
'app.settings.basic.profile-placeholder': 'Perkenalan Singkat tentang Diri Anda',
|
||||
'app.settings.basic.country': 'Negara/Wilayah',
|
||||
'app.settings.basic.country-message': 'Tolong masukkan negara anda!',
|
||||
'app.settings.basic.geographic': 'Provinsi atau kota',
|
||||
'app.settings.basic.geographic-message': 'Tolong masukkan info geografis anda!',
|
||||
'app.settings.basic.address': 'Alamat Jalan',
|
||||
'app.settings.basic.address-message': 'Tolong masukkan Alamat Jalan anda!',
|
||||
'app.settings.basic.phone': 'Nomor Ponsel',
|
||||
'app.settings.basic.phone-message': 'Tolong masukkan Nomor Ponsel anda!',
|
||||
'app.settings.basic.update': 'Perbarui Informasi',
|
||||
'app.settings.security.strong': 'Kuat',
|
||||
'app.settings.security.medium': 'Sedang',
|
||||
'app.settings.security.weak': 'Lemah',
|
||||
'app.settings.security.password': 'Kata Sandi Akun',
|
||||
'app.settings.security.password-description': 'Kekuatan Kata Sandi saat ini',
|
||||
'app.settings.security.phone': 'Keamanan Ponsel',
|
||||
'app.settings.security.phone-description': 'Mengikat Ponsel',
|
||||
'app.settings.security.question': 'Pertanyaan Keamanan',
|
||||
'app.settings.security.question-description':
|
||||
'Pertanyaan Keamanan belum diatur, dan kebijakan keamanan dapat melindungi akun secara efektif',
|
||||
'app.settings.security.email': 'Email Cadangan',
|
||||
'app.settings.security.email-description': 'Mengikat Email',
|
||||
'app.settings.security.mfa': 'Perangka MFA',
|
||||
'app.settings.security.mfa-description':
|
||||
'Tidak mengikat Perangkat MFA, setelah diikat, dapat dikonfirmasi dua kali',
|
||||
'app.settings.security.modify': 'Modifikasi',
|
||||
'app.settings.security.set': 'Setel',
|
||||
'app.settings.security.bind': 'Ikat',
|
||||
'app.settings.binding.taobao': 'Mengikat Taobao',
|
||||
'app.settings.binding.taobao-description': 'Tidak mengikat akun Taobao saat ini',
|
||||
'app.settings.binding.alipay': 'Mengikat Alipay',
|
||||
'app.settings.binding.alipay-description': 'Tidak mengikat akun Alipay saat ini',
|
||||
'app.settings.binding.dingding': 'Mengikat DingTalk',
|
||||
'app.settings.binding.dingding-description': 'Tidak mengikat akun DingTalk',
|
||||
'app.settings.binding.bind': 'Ikat',
|
||||
'app.settings.notification.password': 'Kata Sandi Akun',
|
||||
'app.settings.notification.password-description':
|
||||
'Pesan dari pengguna lain akan diberitahu dalam bentuk surat',
|
||||
'app.settings.notification.messages': 'Pesan Sistem',
|
||||
'app.settings.notification.messages-description':
|
||||
'Pesan sistem akan diberitahu dalam bentuk surat',
|
||||
'app.settings.notification.todo': 'Notifikasi daftar To-do',
|
||||
'app.settings.notification.todo-description':
|
||||
'Daftar to-do akan diberitahukan dalam bentuk surat dari stasiun',
|
||||
'app.settings.open': 'Buka',
|
||||
'app.settings.close': 'Tutup',
|
||||
};
|
23
frontend/src/locales/ja-JP.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import globalHeader from './ja-JP/globalHeader';
|
||||
import menu from './ja-JP/menu';
|
||||
import settingDrawer from './ja-JP/settingDrawer';
|
||||
import settings from './ja-JP/settings';
|
||||
import pwa from './ja-JP/pwa';
|
||||
import component from './ja-JP/component';
|
||||
import pages from './ja-JP/pages';
|
||||
export default {
|
||||
'navBar.lang': '言語',
|
||||
'layout.user.link.help': 'ヘルプ',
|
||||
'layout.user.link.privacy': 'プライバシー',
|
||||
'layout.user.link.terms': '利用規約',
|
||||
'app.preview.down.block': 'このページをローカルプロジェクトにダウンロードしてください',
|
||||
'app.welcome.link.fetch-blocks': '',
|
||||
'app.welcome.link.block-list': '',
|
||||
...globalHeader,
|
||||
...menu,
|
||||
...settingDrawer,
|
||||
...settings,
|
||||
...pwa,
|
||||
...component,
|
||||
...pages,
|
||||
};
|
5
frontend/src/locales/ja-JP/component.js
Normal file
@@ -0,0 +1,5 @@
|
||||
export default {
|
||||
'component.tagSelect.expand': '展開',
|
||||
'component.tagSelect.collapse': '折りたたむ',
|
||||
'component.tagSelect.all': 'すべて',
|
||||
};
|
17
frontend/src/locales/ja-JP/globalHeader.js
Normal file
@@ -0,0 +1,17 @@
|
||||
export default {
|
||||
'component.globalHeader.search': '検索',
|
||||
'component.globalHeader.search.example1': '検索例1',
|
||||
'component.globalHeader.search.example2': '検索例2',
|
||||
'component.globalHeader.search.example3': '検索例3',
|
||||
'component.globalHeader.help': 'ヘルプ',
|
||||
'component.globalHeader.notification': '通知',
|
||||
'component.globalHeader.notification.empty': 'すべての通知を表示しました。',
|
||||
'component.globalHeader.message': 'メッセージ',
|
||||
'component.globalHeader.message.empty': 'すべてのメッセージを表示しました。',
|
||||
'component.globalHeader.event': 'イベント',
|
||||
'component.globalHeader.event.empty': 'すべてのイベントを表示しました。',
|
||||
'component.noticeIcon.clear': 'クリア',
|
||||
'component.noticeIcon.cleared': 'クリア済み',
|
||||
'component.noticeIcon.empty': '通知なし',
|
||||
'component.noticeIcon.view-more': 'もっと見る',
|
||||
};
|
52
frontend/src/locales/ja-JP/menu.js
Normal file
@@ -0,0 +1,52 @@
|
||||
export default {
|
||||
'menu.welcome': 'ようこそ',
|
||||
'menu.more-blocks': 'その他のブロック',
|
||||
'menu.home': 'ホーム',
|
||||
'menu.admin': '管理者',
|
||||
'menu.admin.sub-page': 'サブページ',
|
||||
'menu.login': 'ログイン',
|
||||
'menu.register': '登録',
|
||||
'menu.register-result': '登録結果',
|
||||
'menu.dashboard': 'ダッシュボード',
|
||||
'menu.dashboard.analysis': '分析',
|
||||
'menu.dashboard.monitor': 'モニター',
|
||||
'menu.dashboard.workplace': '職場',
|
||||
'menu.exception.403': '403',
|
||||
'menu.exception.404': '404',
|
||||
'menu.exception.500': '500',
|
||||
'menu.form': 'フォーム',
|
||||
'menu.form.basic-form': '基本フォーム',
|
||||
'menu.form.step-form': 'ステップフォーム',
|
||||
'menu.form.step-form.info': 'ステップフォーム(転送情報の書き込み)',
|
||||
'menu.form.step-form.confirm': 'ステップフォーム(転送情報の確認)',
|
||||
'menu.form.step-form.result': 'ステップフォーム(完成)',
|
||||
'menu.form.advanced-form': '高度なフォーム',
|
||||
'menu.list': 'リスト',
|
||||
'menu.list.table-list': '検索テーブル',
|
||||
'menu.list.basic-list': '基本リスト',
|
||||
'menu.list.card-list': 'カードリスト',
|
||||
'menu.list.search-list': '検索リスト',
|
||||
'menu.list.search-list.articles': '検索リスト(記事)',
|
||||
'menu.list.search-list.projects': '検索リスト(プロジェクト)',
|
||||
'menu.list.search-list.applications': '検索リスト(アプリ)',
|
||||
'menu.profile': 'プロフィール',
|
||||
'menu.profile.basic': '基本プロフィール',
|
||||
'menu.profile.advanced': '高度なプロフィール',
|
||||
'menu.result': '結果',
|
||||
'menu.result.success': '成功',
|
||||
'menu.result.fail': '失敗',
|
||||
'menu.exception': '例外',
|
||||
'menu.exception.not-permission': '403',
|
||||
'menu.exception.not-find': '404',
|
||||
'menu.exception.server-error': '500',
|
||||
'menu.exception.trigger': 'トリガー',
|
||||
'menu.account': 'アカウント',
|
||||
'menu.account.center': 'アカウントセンター',
|
||||
'menu.account.settings': 'アカウント設定',
|
||||
'menu.account.trigger': 'トリガーエラー',
|
||||
'menu.account.logout': 'ログアウト',
|
||||
'menu.editor': 'グラフィックエディタ',
|
||||
'menu.editor.flow': 'フローエディタ',
|
||||
'menu.editor.mind': 'マインドエディター',
|
||||
'menu.editor.koni': 'コニエディター',
|
||||
};
|
67
frontend/src/locales/ja-JP/pages.js
Normal file
@@ -0,0 +1,67 @@
|
||||
export default {
|
||||
'pages.layouts.userLayout.title': 'Ant Designは、西湖区で最も影響力のあるWebデザイン仕様です。',
|
||||
'pages.login.accountLogin.tab': 'アカウントログイン',
|
||||
'pages.login.accountLogin.errorMessage':
|
||||
'ユーザー名/パスワードが正しくありません(admin/ant.design)',
|
||||
'pages.login.username.placeholder': 'ユーザー名:adminまたはuser',
|
||||
'pages.login.username.required': 'ユーザー名を入力してください!',
|
||||
'pages.login.password.placeholder': 'パスワード:ant.design',
|
||||
'pages.login.password.required': 'パスワードを入力してください!',
|
||||
'pages.login.phoneLogin.tab': '電話ログイン',
|
||||
'pages.login.phoneLogin.errorMessage': '検証コードエラー',
|
||||
'pages.login.phoneNumber.placeholder': '電話番号',
|
||||
'pages.login.phoneNumber.required': '電話番号を入力してください!',
|
||||
'pages.login.phoneNumber.invalid': '電話番号が無効です!',
|
||||
'pages.login.captcha.placeholder': '確認コード',
|
||||
'pages.login.captcha.required': '確認コードを入力してください!',
|
||||
'pages.login.phoneLogin.getVerificationCode': '確認コードを取得',
|
||||
'pages.getCaptchaSecondText': '秒',
|
||||
'pages.login.rememberMe': 'Remember me',
|
||||
'pages.login.forgotPassword': 'パスワードをお忘れですか?',
|
||||
'pages.login.submit': 'ログイン',
|
||||
'pages.login.loginWith': 'その他のログイン方法:',
|
||||
'pages.login.registerAccount': 'アカウント登録',
|
||||
'pages.welcome.advancedComponent': '高度なコンポーネント',
|
||||
'pages.welcome.link': 'ようこそ',
|
||||
'pages.welcome.advancedLayout': '高度なレイアウト',
|
||||
'pages.welcome.alertMessage': 'より高速で強力な頑丈なコンポーネントがリリースされました。',
|
||||
'pages.admin.subPage.title': 'このページは管理者のみが表示できます',
|
||||
'pages.admin.subPage.alertMessage':
|
||||
'Umi uiがリリースされました。npm run uiを使用して体験してください。',
|
||||
'pages.searchTable.createForm.newRule': '新しいルール',
|
||||
'pages.searchTable.updateForm.ruleConfig': 'ルール構成',
|
||||
'pages.searchTable.updateForm.basicConfig': '基本情報',
|
||||
'pages.searchTable.updateForm.ruleName.nameLabel': 'ルール名',
|
||||
'pages.searchTable.updateForm.ruleName.nameRules': 'ルール名を入力してください!',
|
||||
'pages.searchTable.updateForm.ruleDesc.descLabel': 'ルールの説明',
|
||||
'pages.searchTable.updateForm.ruleDesc.descPlaceholder': '5文字以上入力してください',
|
||||
'pages.searchTable.updateForm.ruleDesc.descRules': '5文字以上のルールの説明を入力してください!',
|
||||
'pages.searchTable.updateForm.ruleProps.title': 'プロパティの構成',
|
||||
'pages.searchTable.updateForm.object': '監視対象',
|
||||
'pages.searchTable.updateForm.ruleProps.templateLabel': 'ルールテンプレート',
|
||||
'pages.searchTable.updateForm.ruleProps.typeLabel': 'ルールタイプ',
|
||||
'pages.searchTable.updateForm.schedulingPeriod.title': 'スケジュール期間の設定',
|
||||
'pages.searchTable.updateForm.schedulingPeriod.timeLabel': '開始時間',
|
||||
'pages.searchTable.updateForm.schedulingPeriod.timeRules': '開始時間を選択してください!',
|
||||
'pages.searchTable.titleDesc': '説明',
|
||||
'pages.searchTable.ruleName': 'ルール名が必要です',
|
||||
'pages.searchTable.titleCallNo': 'サービスコール数',
|
||||
'pages.searchTable.titleStatus': 'ステータス',
|
||||
'pages.searchTable.nameStatus.default': 'デフォルト',
|
||||
'pages.searchTable.nameStatus.running': '起動中',
|
||||
'pages.searchTable.nameStatus.online': 'オンライン',
|
||||
'pages.searchTable.nameStatus.abnormal': '異常',
|
||||
'pages.searchTable.titleUpdatedAt': '最終スケジュール',
|
||||
'pages.searchTable.exception': '例外の理由を入力してください!',
|
||||
'pages.searchTable.titleOption': 'オプション',
|
||||
'pages.searchTable.config': '構成',
|
||||
'pages.searchTable.subscribeAlert': 'アラートを購読する',
|
||||
'pages.searchTable.title': 'お問い合わせフォーム',
|
||||
'pages.searchTable.new': '新しい',
|
||||
'pages.searchTable.chosen': '選んだ項目',
|
||||
'pages.searchTable.item': '項目',
|
||||
'pages.searchTable.totalServiceCalls': 'サービスコールの総数',
|
||||
'pages.searchTable.tenThousand': '万',
|
||||
'pages.searchTable.batchDeletion': 'バッチ削除',
|
||||
'pages.searchTable.batchApproval': 'バッチ承認',
|
||||
};
|
7
frontend/src/locales/ja-JP/pwa.js
Normal file
@@ -0,0 +1,7 @@
|
||||
export default {
|
||||
'app.pwa.offline': 'あなたは今オフラインです',
|
||||
'app.pwa.serviceworker.updated': '新しいコンテンツが利用可能です',
|
||||
'app.pwa.serviceworker.updated.hint':
|
||||
'現在のページをリロードするには、「更新」ボタンを押してください',
|
||||
'app.pwa.serviceworker.updated.ok': 'リフレッシュ',
|
||||
};
|
31
frontend/src/locales/ja-JP/settingDrawer.js
Normal file
@@ -0,0 +1,31 @@
|
||||
export default {
|
||||
'app.setting.pagestyle': 'ページスタイル設定',
|
||||
'app.setting.pagestyle.dark': 'ダークスタイル',
|
||||
'app.setting.pagestyle.light': 'ライトスタイル',
|
||||
'app.setting.content-width': 'コンテンツの幅',
|
||||
'app.setting.content-width.fixed': '固定',
|
||||
'app.setting.content-width.fluid': '流体',
|
||||
'app.setting.themecolor': 'テーマカラー',
|
||||
'app.setting.themecolor.dust': 'ダストレッド',
|
||||
'app.setting.themecolor.volcano': 'ボルケ-ノ',
|
||||
'app.setting.themecolor.sunset': 'サンセットオレンジ',
|
||||
'app.setting.themecolor.cyan': 'シアン',
|
||||
'app.setting.themecolor.green': 'ポーラーグリーン',
|
||||
'app.setting.themecolor.daybreak': '夜明けの青(デフォルト)',
|
||||
'app.setting.themecolor.geekblue': 'ギーク ブルー',
|
||||
'app.setting.themecolor.purple': 'ゴールデンパープル',
|
||||
'app.setting.navigationmode': 'ナビゲーションモード',
|
||||
'app.setting.sidemenu': 'サイドメニューのレイアウト',
|
||||
'app.setting.topmenu': 'トップメニューのレイアウト',
|
||||
'app.setting.fixedheader': '固定ヘッダー',
|
||||
'app.setting.fixedsidebar': '固定サイドバー',
|
||||
'app.setting.fixedsidebar.hint': 'サイドメニューのレイアウトで動作します',
|
||||
'app.setting.hideheader': 'スクロール時の非表示ヘッダー',
|
||||
'app.setting.hideheader.hint': '非表示ヘッダーが有効になっている場合に機能します',
|
||||
'app.setting.othersettings': 'その他の設定',
|
||||
'app.setting.weakmode': 'ウィークモード',
|
||||
'app.setting.copy': 'コピー設定',
|
||||
'app.setting.copyinfo':
|
||||
'コピーが成功しました。src/models/setting.jsのdefaultSettingsを置き換えてください',
|
||||
'app.setting.production.hint': '設定パネルは開発環境でのみ表示されます。手動で変更してください',
|
||||
};
|
59
frontend/src/locales/ja-JP/settings.js
Normal file
@@ -0,0 +1,59 @@
|
||||
export default {
|
||||
'app.settings.menuMap.basic': '基本設定',
|
||||
'app.settings.menuMap.security': 'セキュリティ設定',
|
||||
'app.settings.menuMap.binding': 'アカウントのバインド',
|
||||
'app.settings.menuMap.notification': '新しいメッセージの通知',
|
||||
'app.settings.basic.avatar': 'アバター',
|
||||
'app.settings.basic.change-avatar': 'アバターを変更する',
|
||||
'app.settings.basic.email': 'メール',
|
||||
'app.settings.basic.email-message': 'メールアドレスを入力してください!',
|
||||
'app.settings.basic.nickname': 'ニックネーム',
|
||||
'app.settings.basic.nickname-message': 'ニックネームを入力してください!',
|
||||
'app.settings.basic.profile': '個人プロフィール',
|
||||
'app.settings.basic.profile-message': '個人プロフィールを入力してください!',
|
||||
'app.settings.basic.profile-placeholder': '自己紹介',
|
||||
'app.settings.basic.country': '国/地域',
|
||||
'app.settings.basic.country-message': 'あなたの国を入力してください!',
|
||||
'app.settings.basic.geographic': '州または市',
|
||||
'app.settings.basic.geographic-message': '地理情報を入力してください!',
|
||||
'app.settings.basic.address': '住所',
|
||||
'app.settings.basic.address-message': '住所を入力してください!',
|
||||
'app.settings.basic.phone': '電話番号',
|
||||
'app.settings.basic.phone-message': '電話番号を入力してください!',
|
||||
'app.settings.basic.update': '更新情報',
|
||||
'app.settings.security.strong': '強い',
|
||||
'app.settings.security.medium': 'ミディアム',
|
||||
'app.settings.security.weak': '弱い',
|
||||
'app.settings.security.password': 'アカウントパスワード',
|
||||
'app.settings.security.password-description': '現在のパスワードの強度',
|
||||
'app.settings.security.phone': 'セキュリティ電話番号',
|
||||
'app.settings.security.phone-description': 'バインドされた電話番号',
|
||||
'app.settings.security.question': '秘密の質問',
|
||||
'app.settings.security.question-description':
|
||||
'セキュリティの質問が設定されてません。セキュリティポリシーはアカウントのセキュリティを効果的に保護できます',
|
||||
'app.settings.security.email': 'バックアップメール',
|
||||
'app.settings.security.email-description': 'バインドされたメール',
|
||||
'app.settings.security.mfa': '多要素認証デバイス',
|
||||
'app.settings.security.mfa-description':
|
||||
'バインドされていない多要素認証デバイスは、バインド後、2回確認できます',
|
||||
'app.settings.security.modify': '変更する',
|
||||
'app.settings.security.set': 'セットする',
|
||||
'app.settings.security.bind': 'バインド',
|
||||
'app.settings.binding.taobao': 'タオバオをバインドする',
|
||||
'app.settings.binding.taobao-description': '現在バインドされていないタオバオアカウント',
|
||||
'app.settings.binding.alipay': 'アリペイをバインドする',
|
||||
'app.settings.binding.alipay-description': '現在バインドされていないアリペイアカウント',
|
||||
'app.settings.binding.dingding': 'ディントークをバインドする',
|
||||
'app.settings.binding.dingding-description': '現在バインドされていないディントークアカウント',
|
||||
'app.settings.binding.bind': 'バインド',
|
||||
'app.settings.notification.password': 'アカウントパスワード',
|
||||
'app.settings.notification.password-description':
|
||||
'他のユーザーからのメッセージは、ステーションレターの形式で通知されます',
|
||||
'app.settings.notification.messages': 'システムメッセージ',
|
||||
'app.settings.notification.messages-description':
|
||||
'システムメッセージは、ステーションレターの形式で通知されます',
|
||||
'app.settings.notification.todo': 'To Do(用事) 通知',
|
||||
'app.settings.notification.todo-description': 'To Doタスクは、内部レターの形式で通知されます',
|
||||
'app.settings.open': '開く',
|
||||
'app.settings.close': '閉じる',
|
||||
};
|
21
frontend/src/locales/pt-BR.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import component from './pt-BR/component';
|
||||
import globalHeader from './pt-BR/globalHeader';
|
||||
import menu from './pt-BR/menu';
|
||||
import pwa from './pt-BR/pwa';
|
||||
import settingDrawer from './pt-BR/settingDrawer';
|
||||
import settings from './pt-BR/settings';
|
||||
import pages from './pt-BR/pages';
|
||||
export default {
|
||||
'navBar.lang': 'Idiomas',
|
||||
'layout.user.link.help': 'ajuda',
|
||||
'layout.user.link.privacy': 'política de privacidade',
|
||||
'layout.user.link.terms': 'termos de serviços',
|
||||
'app.preview.down.block': 'Download this page to your local project',
|
||||
...globalHeader,
|
||||
...menu,
|
||||
...settingDrawer,
|
||||
...settings,
|
||||
...pwa,
|
||||
...component,
|
||||
...pages,
|
||||
};
|
5
frontend/src/locales/pt-BR/component.js
Normal file
@@ -0,0 +1,5 @@
|
||||
export default {
|
||||
'component.tagSelect.expand': 'Expandir',
|
||||
'component.tagSelect.collapse': 'Diminuir',
|
||||
'component.tagSelect.all': 'Todas',
|
||||
};
|