├── ams-web ├── CHANGELOG.md ├── .eslintignore ├── src │ ├── common │ │ ├── config.tsx │ │ ├── api.tsx │ │ └── exportHosts.tsx │ ├── index.html │ ├── @types │ │ └── index.d.ts │ ├── pages │ │ ├── Hosts │ │ │ ├── Extend │ │ │ │ └── config.ts │ │ │ └── Management │ │ │ │ ├── style.less │ │ │ │ └── Dashboard │ │ │ │ └── utils.tsx │ │ └── Nethws │ │ │ ├── index.tsx │ │ │ └── Management │ │ │ ├── Batch.tsx │ │ │ └── BatchSearch.tsx │ ├── index.tsx │ └── HeadlessIndex.tsx ├── config │ ├── theme.js │ ├── webpackConfigResolveAlias.js │ ├── webpack.build.config.js │ └── webpack.dev.config.js ├── .editorconfig ├── .gitignore ├── static │ └── amsMenusConfig.json ├── .eslintrc ├── README.md ├── fetk.config.js ├── tsconfig.json └── package.json ├── job-web ├── CHANGELOG.md ├── src │ ├── pages │ │ ├── Task │ │ │ ├── interface.ts │ │ │ └── style.less │ │ ├── TaskTpl │ │ │ ├── style.less │ │ │ ├── interface.ts │ │ │ ├── Editor.tsx │ │ │ ├── Add.tsx │ │ │ ├── Modify.tsx │ │ │ └── BindTags.tsx │ │ └── TaskOutput │ │ │ ├── host.jsx │ │ │ └── index.jsx │ ├── common │ │ ├── utils.tsx │ │ └── api.tsx │ ├── index.html │ ├── @types │ │ └── index.d.ts │ ├── index.tsx │ ├── HeadlessIndex.tsx │ ├── interface │ │ └── index.tsx │ └── components │ │ └── FieldCopy │ │ └── index.tsx ├── .eslintignore ├── config │ ├── theme.js │ ├── webpackConfigResolveAlias.js │ ├── webpack.build.config.js │ └── webpack.dev.config.js ├── .gitignore ├── .editorconfig ├── .eslintrc ├── README.md ├── fetk.config.js ├── tsconfig.json └── package.json ├── layout-web ├── CHANGELOG.md ├── src │ ├── index.html │ ├── @types │ │ └── index.d.ts │ ├── common │ │ ├── config.tsx │ │ └── api.tsx │ ├── locales │ │ ├── zh.tsx │ │ └── en.tsx │ ├── index.tsx │ ├── pages │ │ ├── BigScreen │ │ │ └── index.tsx │ │ └── TaskOutput │ │ │ ├── host.jsx │ │ │ └── index.jsx │ └── interface │ │ └── index.tsx ├── static │ ├── logo.png │ ├── 400icon.png │ ├── logo-opaque.png │ ├── js │ │ ├── use-default.min.js │ │ ├── named-exports.min.js │ │ └── amd.js │ ├── feConfig.json │ ├── menusConfig.json │ ├── systemsConfig.json │ ├── amsMenusConfig.json │ ├── jobMenusConfig.json │ └── monMenusConfig.json ├── .eslintignore ├── config │ ├── theme.js │ ├── webpackConfigResolveAlias.js │ ├── webpack.dev.config.js │ └── webpack.build.config.js ├── .editorconfig ├── .gitignore ├── .eslintrc ├── fetk.config.js ├── README.md ├── tsconfig.json └── package.json ├── mon-web ├── CHANGELOG.md ├── src │ ├── style.less │ ├── variables.less │ ├── index.html │ ├── pages │ │ ├── API │ │ │ └── config.ts │ │ ├── SNMP │ │ │ └── config.ts │ │ ├── CollectRule │ │ │ ├── config.tsx │ │ │ ├── Types.ts │ │ │ ├── InputWithUpload.tsx │ │ │ └── BaseList.tsx │ │ ├── NginxLog │ │ │ ├── style.less │ │ │ ├── config.ts │ │ │ └── services.jsx │ │ ├── Binlog │ │ │ ├── style.less │ │ │ ├── config.ts │ │ │ └── services.jsx │ │ ├── Collect │ │ │ ├── CollectForm │ │ │ │ └── index.jsx │ │ │ ├── config.tsx │ │ │ └── BatchCloneToNidModal.tsx │ │ ├── Strategy │ │ │ ├── SettingFields │ │ │ │ ├── PeriodTime │ │ │ │ │ └── config.jsx │ │ │ │ ├── utils.jsx │ │ │ │ ├── index.jsx │ │ │ │ ├── Expressions │ │ │ │ │ └── style.less │ │ │ │ ├── Filters │ │ │ │ │ ├── Filter.jsx │ │ │ │ │ └── style.less │ │ │ │ └── WorkGroups │ │ │ │ │ └── index.tsx │ │ │ ├── services.jsx │ │ │ ├── style.less │ │ │ ├── Clone.jsx │ │ │ ├── Modify.jsx │ │ │ └── utils.jsx │ │ ├── Silence │ │ │ ├── services.jsx │ │ │ ├── style.less │ │ │ ├── utils.jsx │ │ │ └── DetailModal.jsx │ │ ├── Screen │ │ │ ├── style.less │ │ │ ├── ScreenDetail │ │ │ │ ├── GraphsContainer.jsx │ │ │ │ ├── AddModal.jsx │ │ │ │ └── ModifyModal.jsx │ │ │ ├── AddModal.jsx │ │ │ └── ModifyModal.jsx │ │ ├── History │ │ │ ├── style.less │ │ │ ├── Current.jsx │ │ │ ├── All.jsx │ │ │ └── index.jsx │ │ ├── Charts │ │ │ └── index.tsx │ │ ├── SRM │ │ │ └── index.tsx │ │ ├── AggrStra │ │ │ └── BatchCloneToNidModal.tsx │ │ ├── BigScreen │ │ │ ├── AddModal.jsx │ │ │ └── ModifyModal.jsx │ │ └── Dashboard │ │ │ └── utils.tsx │ ├── HeadlessIndex.tsx │ ├── @types │ │ └── index.d.ts │ ├── index.tsx │ ├── interface │ │ └── index.tsx │ └── common │ │ └── api.tsx ├── .eslintignore ├── config │ ├── theme.js │ ├── webpackConfigResolveAlias.js │ ├── webpack.build.config.js │ └── webpack.dev.config.js ├── .gitignore ├── .editorconfig ├── .eslintrc ├── README.md ├── tsconfig.json ├── fetk.config.js └── package.json ├── rdb-web ├── CHANGELOG.md ├── .eslintignore ├── src │ ├── common │ │ ├── config.tsx │ │ ├── exportResources.tsx │ │ └── api.tsx │ ├── pages │ │ ├── RoleManagement │ │ │ ├── assets │ │ │ │ ├── role-bg.png │ │ │ │ └── style.less │ │ │ ├── RoleBindUsers.tsx │ │ │ ├── CreateRole.tsx │ │ │ └── SiderList │ │ │ │ └── style.less │ │ ├── TeamManagement │ │ │ ├── assets │ │ │ │ ├── team-bg.png │ │ │ │ └── style.less │ │ │ ├── TeamDetail.tsx │ │ │ ├── CreateTeam.tsx │ │ │ ├── ModifyTeam.tsx │ │ │ ├── SiderList │ │ │ │ └── style.less │ │ │ └── TeamForm.tsx │ │ ├── Settings │ │ │ ├── Security │ │ │ │ ├── White │ │ │ │ │ └── style.less │ │ │ │ ├── Login │ │ │ │ │ └── services.tsx │ │ │ │ └── index.tsx │ │ │ └── SSO │ │ │ │ └── style.less │ │ ├── PersonnelInfo │ │ │ ├── Teams │ │ │ │ ├── assets │ │ │ │ │ ├── team-bg.png │ │ │ │ │ └── style.less │ │ │ │ ├── TeamDetail.tsx │ │ │ │ ├── CreateTeam.tsx │ │ │ │ ├── ModifyTeam.tsx │ │ │ │ ├── SiderList │ │ │ │ │ └── style.less │ │ │ │ └── TeamForm.tsx │ │ │ └── Profile │ │ │ │ └── index.tsx │ │ ├── UserManagement │ │ │ ├── style.less │ │ │ ├── Config.tsx │ │ │ ├── ModifyUser.tsx │ │ │ └── CreateUser.tsx │ │ ├── ResourcesTree │ │ │ ├── Usages │ │ │ │ ├── api.tsx │ │ │ │ └── request.tsx │ │ │ ├── Info │ │ │ │ └── style.less │ │ │ └── index.tsx │ │ ├── TreenodeManagement │ │ │ ├── NodeCate │ │ │ │ └── config.ts │ │ │ └── RecycleBin │ │ │ │ └── index.tsx │ │ └── ResourceGeneral │ │ │ └── LiquCharts.tsx │ ├── @types │ │ └── index.d.ts │ ├── components │ │ ├── ResourceEdit │ │ │ └── index.jsx │ │ └── Resources │ │ │ └── BatchSearch.tsx │ ├── index.html │ ├── HeadlessIndex.tsx │ └── index.tsx ├── config │ ├── theme.js │ ├── webpackConfigResolveAlias.js │ ├── webpack.build.config.js │ └── webpack.dev.config.js ├── .editorconfig ├── .gitignore ├── .eslintrc ├── README.md ├── fetk.config.js ├── tsconfig.json └── package.json ├── .eslintignore ├── .editorconfig ├── .gitignore ├── Makefile ├── nginx.conf └── README.md /ams-web/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /job-web/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /layout-web/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mon-web/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /rdb-web/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /layout-web/src/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /job-web/src/pages/Task/interface.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /job-web/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | config/* 3 | -------------------------------------------------------------------------------- /mon-web/src/style.less: -------------------------------------------------------------------------------- 1 | @import "./variables.less"; 2 | -------------------------------------------------------------------------------- /ams-web/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | config/* 3 | fetk.config.js 4 | -------------------------------------------------------------------------------- /rdb-web/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | config/* 3 | fetk.config.js 4 | -------------------------------------------------------------------------------- /mon-web/src/variables.less: -------------------------------------------------------------------------------- 1 | @import '~antd/lib/style/themes/default.less'; 2 | -------------------------------------------------------------------------------- /layout-web/static/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n9e/fe-v4/HEAD/layout-web/static/logo.png -------------------------------------------------------------------------------- /layout-web/static/400icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n9e/fe-v4/HEAD/layout-web/static/400icon.png -------------------------------------------------------------------------------- /layout-web/static/logo-opaque.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n9e/fe-v4/HEAD/layout-web/static/logo-opaque.png -------------------------------------------------------------------------------- /mon-web/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | config/* 3 | src/packages/Charts/LiquidFillGauge/LiquidFillGauge.js 4 | -------------------------------------------------------------------------------- /layout-web/.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | config/* 3 | src/packages/ccp/* 4 | src/assets/iconfont/* 5 | src/packages/Charts/LiquidFillGauge/* -------------------------------------------------------------------------------- /ams-web/src/common/config.tsx: -------------------------------------------------------------------------------- 1 | export const systemName = 'ams'; 2 | export const appname = systemName; 3 | export const prefixCls = systemName; 4 | -------------------------------------------------------------------------------- /rdb-web/src/common/config.tsx: -------------------------------------------------------------------------------- 1 | export const systemName = 'rdb'; 2 | export const appname = systemName; 3 | export const prefixCls = systemName; 4 | -------------------------------------------------------------------------------- /rdb-web/src/pages/RoleManagement/assets/role-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n9e/fe-v4/HEAD/rdb-web/src/pages/RoleManagement/assets/role-bg.png -------------------------------------------------------------------------------- /rdb-web/src/pages/TeamManagement/assets/team-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n9e/fe-v4/HEAD/rdb-web/src/pages/TeamManagement/assets/team-bg.png -------------------------------------------------------------------------------- /layout-web/src/@types/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'rc-notification'; 2 | declare module 'query-string'; 3 | declare module 'single-spa-react/parcel'; 4 | -------------------------------------------------------------------------------- /rdb-web/src/pages/Settings/Security/White/style.less: -------------------------------------------------------------------------------- 1 | .rdb-settings-security-white { 2 | &-topInput { 3 | margin-bottom: 10px; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /rdb-web/src/pages/PersonnelInfo/Teams/assets/team-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/n9e/fe-v4/HEAD/rdb-web/src/pages/PersonnelInfo/Teams/assets/team-bg.png -------------------------------------------------------------------------------- /ams-web/config/theme.js: -------------------------------------------------------------------------------- 1 | const config = require('../src/packages/config'); 2 | 3 | module.exports = { 4 | 'prefix-cls': 'ams', 5 | ...config.theme, 6 | }; 7 | -------------------------------------------------------------------------------- /job-web/config/theme.js: -------------------------------------------------------------------------------- 1 | const config = require('../src/packages/config'); 2 | 3 | module.exports = { 4 | 'prefix-cls': 'job', 5 | ...config.theme, 6 | }; 7 | -------------------------------------------------------------------------------- /mon-web/config/theme.js: -------------------------------------------------------------------------------- 1 | const config = require('../src/packages/config'); 2 | 3 | module.exports = { 4 | 'prefix-cls': 'mon', 5 | ...config.theme, 6 | }; 7 | -------------------------------------------------------------------------------- /rdb-web/config/theme.js: -------------------------------------------------------------------------------- 1 | const config = require('../src/packages/config'); 2 | 3 | module.exports = { 4 | 'prefix-cls': 'rdb', 5 | ...config.theme, 6 | }; 7 | -------------------------------------------------------------------------------- /job-web/src/common/utils.tsx: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | 3 | export const getFirstPath = (path: string) => { 4 | return _.get(_.split(path, '/'), '[1]'); 5 | }; 6 | -------------------------------------------------------------------------------- /layout-web/config/theme.js: -------------------------------------------------------------------------------- 1 | const config = require('../src/packages/config'); 2 | 3 | module.exports = { 4 | 'prefix-cls': 'layout', 5 | ...config.theme, 6 | }; 7 | -------------------------------------------------------------------------------- /rdb-web/src/@types/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'rc-notification'; 2 | declare module 'query-string'; 3 | declare module 'xlsx'; 4 | declare module 'single-spa-react/parcel' 5 | -------------------------------------------------------------------------------- /rdb-web/src/pages/UserManagement/style.less: -------------------------------------------------------------------------------- 1 | .rdb-pwd { 2 | &-timestamp { 3 | font-size: 12px; 4 | line-height: 20px; 5 | padding-bottom: 12px; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules/* 2 | */config 3 | fetk.config.js 4 | layout-web/src/packages/ccp/* 5 | layout-web/src/assets/iconfont/* 6 | layout-web/src/packages/Charts/LiquidFillGauge/* 7 | -------------------------------------------------------------------------------- /rdb-web/src/components/ResourceEdit/index.jsx: -------------------------------------------------------------------------------- 1 | import Single from './Single'; 2 | import Batch from './Batch'; 3 | 4 | export { 5 | Single as SingleMod, 6 | Batch as BatchMod, 7 | }; 8 | -------------------------------------------------------------------------------- /rdb-web/src/pages/RoleManagement/RoleBindUsers.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Members from '@cpts/Members'; 3 | 4 | export default () => { 5 | return ; 6 | } 7 | -------------------------------------------------------------------------------- /rdb-web/src/pages/TeamManagement/TeamDetail.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Members from '@cpts/Members'; 3 | 4 | export default () => { 5 | return ; 6 | } 7 | -------------------------------------------------------------------------------- /rdb-web/src/pages/PersonnelInfo/Teams/TeamDetail.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Members from '@cpts/Members'; 3 | 4 | export default () => { 5 | return ; 6 | } 7 | -------------------------------------------------------------------------------- /ams-web/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /job-web/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /mon-web/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /rdb-web/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | -------------------------------------------------------------------------------- /ams-web/src/@types/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'rc-notification'; 2 | declare module 'query-string'; 3 | declare module 'xlsx'; 4 | declare module 'react-addons-update'; 5 | declare module 'single-spa-react/parcel'; 6 | -------------------------------------------------------------------------------- /job-web/src/@types/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'rc-notification'; 2 | declare module 'query-string'; 3 | declare module 'react-addons-update'; 4 | declare module 'react-highlight'; 5 | declare module 'single-spa-react/parcel'; 6 | -------------------------------------------------------------------------------- /mon-web/src/pages/API/config.ts: -------------------------------------------------------------------------------- 1 | export const interval = [10, 30, 60, 120, 300, 600, 1800, 3600]; 2 | export const nameRule = { 3 | pattern: /^[\u4e00-\u9fa5a-zA-Z0-9\.\-\_]{0,128}$/, 4 | message: '名称只允许 英文数字 . - _', 5 | }; 6 | -------------------------------------------------------------------------------- /mon-web/src/pages/SNMP/config.ts: -------------------------------------------------------------------------------- 1 | export const interval = [10, 30, 60, 120, 300, 600, 1800, 3600]; 2 | export const nameRule = { 3 | pattern: /^[\u4e00-\u9fa5a-zA-Z0-9\.\-\_]{0,128}$/, 4 | message: '名称只允许 英文数字 . - _', 5 | }; 6 | -------------------------------------------------------------------------------- /layout-web/src/common/config.tsx: -------------------------------------------------------------------------------- 1 | export const appname = 'ecmc'; 2 | export const prefixCls = appname; 3 | export const loginPath = `/login`; 4 | export const defaultPageSizeOptions = ['10', '30', '50', '100', '300', '500', '1000']; 5 | -------------------------------------------------------------------------------- /mon-web/src/pages/CollectRule/config.tsx: -------------------------------------------------------------------------------- 1 | export const interval = [10, 20, 30, 40, 60, 120, 300, 600, 1800, 3600]; 2 | export const nameRule = { 3 | pattern: /^[\u4e00-\u9fa5a-zA-Z0-9.\-_]{0,128}$/, 4 | message: '名称只允许 英文数字 . - _', 5 | }; 6 | -------------------------------------------------------------------------------- /mon-web/src/pages/NginxLog/style.less: -------------------------------------------------------------------------------- 1 | .mon-nginxlog{ 2 | .inp{ 3 | width: 150px; 4 | } 5 | 6 | .ml_20{ 7 | margin-left: 20px; 8 | } 9 | 10 | .mt_20{ 11 | margin-top: 10px; 12 | } 13 | } 14 | 15 | -------------------------------------------------------------------------------- /mon-web/src/pages/Binlog/style.less: -------------------------------------------------------------------------------- 1 | .mon-binlog{ 2 | .inp{ 3 | width: 150px; 4 | } 5 | 6 | .ml_20{ 7 | margin-left: 20px; 8 | } 9 | 10 | .mt_20{ 11 | margin-top: 10px; 12 | } 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /mon-web/src/HeadlessIndex.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './app'; 4 | import '@pkgs/Layout/style.less'; 5 | 6 | ReactDOM.render( 7 | , 8 | document.getElementById('react-content'), 9 | ); 10 | -------------------------------------------------------------------------------- /rdb-web/src/HeadlessIndex.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './app'; 4 | import '@pkgs/Layout/style.less'; 5 | 6 | ReactDOM.render( 7 | , 8 | document.getElementById('react-content'), 9 | ); 10 | -------------------------------------------------------------------------------- /layout-web/static/js/use-default.min.js: -------------------------------------------------------------------------------- 1 | !function(t){var e=t.System.constructor.prototype,n=e.import;e.import=function(){return n.apply(this,arguments).then((function(t){return t.__useDefault?t.default:t}))}}("undefined"!=typeof self?self:global);//# sourceMappingURL=use-default.min.js.map -------------------------------------------------------------------------------- /mon-web/src/@types/index.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'rc-notification'; 2 | declare module 'query-string'; 3 | declare module 'react-addons-update'; 4 | declare module 'd3'; 5 | declare module 'd3-scale-chromatic'; 6 | declare module '@umijs/hooks'; 7 | declare module 'single-spa-react/parcel'; 8 | -------------------------------------------------------------------------------- /layout-web/src/locales/zh.tsx: -------------------------------------------------------------------------------- 1 | import zh from '../packages/locales/zh'; 2 | export default { 3 | ...zh, 4 | 'yes': '是', 5 | 'no': '否', 6 | 'login': '登录', 7 | 'logout': '退出登录', 8 | 'register': '注册', 9 | 'login.title': '账户登录', 10 | 'login.ldap': '使用LDAP账号登录', 11 | }; 12 | -------------------------------------------------------------------------------- /ams-web/src/common/api.tsx: -------------------------------------------------------------------------------- 1 | function getApi(sys: string, path: string) { 2 | const prefix = '/api/'; 3 | return `${prefix}${sys}${path}`; 4 | } 5 | 6 | const api = { 7 | tree: getApi('rdb', '/tree'), 8 | node: getApi('rdb', '/node'), 9 | 10 | }; 11 | 12 | export default api; 13 | -------------------------------------------------------------------------------- /layout-web/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import invalidBrowser from '@pkgs/invalidBrowser'; 4 | import App from './app'; 5 | 6 | invalidBrowser(); 7 | 8 | ReactDOM.render( 9 | , 10 | document.getElementById('layout'), 11 | ); 12 | -------------------------------------------------------------------------------- /layout-web/src/locales/en.tsx: -------------------------------------------------------------------------------- 1 | import en from '../packages/locales/en'; 2 | export default { 3 | ...en, 4 | 'yes': 'yes', 5 | 'no': 'no', 6 | 'login': 'Login', 7 | 'logout': 'Logout', 8 | 'register': 'Register', 9 | 'login.title': 'Login', 10 | 'login.ldap': 'Use LDAP', 11 | }; 12 | -------------------------------------------------------------------------------- /job-web/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .idea/ 3 | .ipr 4 | .iws 5 | *~ 6 | ~* 7 | *.diff 8 | *.patch 9 | *.bak 10 | .DS_Store 11 | Thumbs.db 12 | .project 13 | .*proj 14 | .svn/ 15 | *.swp 16 | *.swo 17 | *.pyc 18 | *.pyo 19 | node_modules 20 | npm-debug.log 21 | coverage 22 | .cache-loader 23 | src/packages 24 | src/packages/* 25 | -------------------------------------------------------------------------------- /mon-web/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .idea/ 3 | .ipr 4 | .iws 5 | *~ 6 | ~* 7 | *.diff 8 | *.patch 9 | *.bak 10 | .DS_Store 11 | Thumbs.db 12 | .project 13 | .*proj 14 | .svn/ 15 | *.swp 16 | *.swo 17 | *.pyc 18 | *.pyo 19 | node_modules 20 | npm-debug.log 21 | coverage 22 | .cache-loader 23 | src/packages 24 | src/packages/* 25 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /mon-web/src/pages/Collect/CollectForm/index.jsx: -------------------------------------------------------------------------------- 1 | import LOGForm from './LOGForm'; 2 | import PORTForm from './PORTForm'; 3 | import PROCForm from './PROCForm'; 4 | import PLUGINForm from './PLUGINForm'; 5 | 6 | export default { 7 | log: LOGForm, 8 | port: PORTForm, 9 | proc: PROCForm, 10 | plugin: PLUGINForm, 11 | }; 12 | -------------------------------------------------------------------------------- /rdb-web/src/pages/ResourcesTree/Usages/api.tsx: -------------------------------------------------------------------------------- 1 | function getZstack(path: string) { 2 | const prefix = '/zstack/v1'; 3 | return `${prefix}${path}`; 4 | } 5 | const api = { 6 | zstack: getZstack('/accounts/quota'), 7 | updateZstack: getZstack('/accounts/quotas'), 8 | }; 9 | 10 | export default api; 11 | -------------------------------------------------------------------------------- /ams-web/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /ams-web/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .idea/ 3 | .ipr 4 | .iws 5 | *~ 6 | ~* 7 | *.diff 8 | *.patch 9 | *.bak 10 | .DS_Store 11 | Thumbs.db 12 | .project 13 | .*proj 14 | .svn/ 15 | *.swp 16 | *.swo 17 | *.pyc 18 | *.pyo 19 | node_modules 20 | npm-debug.log 21 | coverage 22 | .cache-loader 23 | src/packages 24 | src/packages/* 25 | pub/* 26 | -------------------------------------------------------------------------------- /job-web/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /mon-web/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /rdb-web/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /rdb-web/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .idea/ 3 | .ipr 4 | .iws 5 | *~ 6 | ~* 7 | *.diff 8 | *.patch 9 | *.bak 10 | .DS_Store 11 | Thumbs.db 12 | .project 13 | .*proj 14 | .svn/ 15 | *.swp 16 | *.swo 17 | *.pyc 18 | *.pyo 19 | node_modules 20 | npm-debug.log 21 | coverage 22 | .cache-loader 23 | src/packages 24 | src/packages/* 25 | pub/* 26 | -------------------------------------------------------------------------------- /layout-web/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /job-web/src/pages/TaskTpl/style.less: -------------------------------------------------------------------------------- 1 | @tpl-form-prefix-cls: ~"@{prefix-cls}-zeus-tpl-form"; 2 | 3 | .@{tpl-form-prefix-cls} { 4 | width: 800px; 5 | margin: 0 auto; 6 | .ant-form-item-label { 7 | strong { 8 | margin-right: 10px; 9 | } 10 | } 11 | .ant-form-item-label label:after { 12 | content: ''; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /mon-web/src/pages/Strategy/SettingFields/PeriodTime/config.jsx: -------------------------------------------------------------------------------- 1 | const allHoursOfDay = []; 2 | const allDaysOfWeek = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']; 3 | 4 | // eslint-disable-next-line no-plusplus 5 | for (let i = 0; i < 24; i++) { 6 | allHoursOfDay.push(i); 7 | } 8 | 9 | export { 10 | allHoursOfDay, allDaysOfWeek, 11 | }; 12 | -------------------------------------------------------------------------------- /rdb-web/src/pages/UserManagement/Config.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export const Status : any = { 4 | 0:
启用
, 5 | 1:
禁用
, 6 | 2:
锁定
, 7 | 3:
休眠
, 8 | 4:
已注销
9 | } 10 | 11 | export const Type : any = { 12 | 0:
长期账号
, 13 | 1:
临时账号
, 14 | } -------------------------------------------------------------------------------- /layout-web/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .idea/ 3 | .ipr 4 | .iws 5 | *~ 6 | ~* 7 | *.diff 8 | *.patch 9 | *.bak 10 | .DS_Store 11 | Thumbs.db 12 | .project 13 | .*proj 14 | .svn/ 15 | *.swp 16 | *.swo 17 | *.pyc 18 | *.pyo 19 | node_modules 20 | npm-debug.log 21 | coverage 22 | .cache-loader 23 | src/packages 24 | src/packages/* 25 | package-lock.json 26 | pub 27 | -------------------------------------------------------------------------------- /layout-web/static/feConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "header": { 3 | "logo": "/static/logo.png", 4 | "subTitle": "" 5 | }, 6 | "rdb": { 7 | "username": { 8 | "placeholder": "只能输入 a-zA-Z0-9_.", 9 | "rules": [{ 10 | "pattern": "^[a-zA-Z0-9_.]+$", 11 | "message": "只能输入 a-zA-Z0-9_." 12 | }] 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /rdb-web/src/pages/Settings/SSO/style.less: -------------------------------------------------------------------------------- 1 | .sso-login { 2 | .inp { 3 | width: 150px; 4 | } 5 | 6 | .ml_20 { 7 | margin-left: 20px; 8 | } 9 | .mt_20 { 10 | margin-top: 10px; 11 | } 12 | 13 | &-list-width { 14 | width: 150px; 15 | overflow: hidden; 16 | word-wrap: break-word; 17 | word-break: break-all; 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /mon-web/src/pages/Strategy/SettingFields/utils.jsx: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | 3 | export function valToArray(val) { 4 | if (_.isString(val) && val) { 5 | return _.split(val, ','); 6 | } 7 | return []; 8 | } 9 | 10 | export function valToString(val) { 11 | if (_.isArray(val) && val.length) { 12 | return _.join(val, ','); 13 | } 14 | return ''; 15 | } 16 | -------------------------------------------------------------------------------- /mon-web/src/pages/Collect/config.tsx: -------------------------------------------------------------------------------- 1 | export const typeMap: { [index: string]: string } = { 2 | log: '日志', 3 | port: '端口', 4 | proc: '进程', 5 | plugin: '插件', 6 | }; 7 | export const interval = [10, 20, 30, 40, 60, 120, 300, 600, 1800, 3600]; 8 | export const nameRule = { 9 | pattern: /^[\u4e00-\u9fa5a-zA-Z0-9\.\-\_]{0,128}$/, 10 | message: '名称只允许 英文数字 . - _', 11 | }; 12 | -------------------------------------------------------------------------------- /rdb-web/src/pages/ResourcesTree/Info/style.less: -------------------------------------------------------------------------------- 1 | .editable-cell { 2 | position: relative; 3 | } 4 | 5 | .editable-cell-value-wrap { 6 | height: 40px; 7 | line-height: 40px; 8 | padding: 0 12px; 9 | cursor: pointer; 10 | border: 1px solid #fff; 11 | } 12 | 13 | .editable-row:hover .editable-cell-value-wrap { 14 | border: 1px solid #d9d9d9; 15 | border-radius: 4px; 16 | } 17 | -------------------------------------------------------------------------------- /mon-web/src/pages/Strategy/SettingFields/index.jsx: -------------------------------------------------------------------------------- 1 | import Expressions from './Expressions'; 2 | import Filters from './Filters'; 3 | import Actions from './Actions'; 4 | import PeriodTime from './PeriodTime'; 5 | import AlarmUpgrade from './AlarmUpgrade'; 6 | import WorkGroups from './WorkGroups'; 7 | 8 | export { 9 | Expressions, Filters, Actions, PeriodTime, AlarmUpgrade, WorkGroups, 10 | }; 11 | -------------------------------------------------------------------------------- /ams-web/src/pages/Hosts/Extend/config.ts: -------------------------------------------------------------------------------- 1 | export const fields = [ 2 | { 3 | name: '字符串', 4 | ident: 'string', 5 | }, { 6 | name: '数值', 7 | ident: 'number', 8 | }, { 9 | name: '枚举', 10 | ident: 'enum', 11 | }, { 12 | name: '时间', 13 | ident: 'time', 14 | }, { 15 | name: '用户', 16 | ident: 'user', 17 | }, { 18 | name: '团队', 19 | ident: 'team', 20 | }, 21 | ]; 22 | -------------------------------------------------------------------------------- /mon-web/src/pages/CollectRule/Types.ts: -------------------------------------------------------------------------------- 1 | export type FieldType = { 2 | name: string; 3 | itemName?: string; 4 | label: string; 5 | description: string; 6 | required: true; 7 | type: string; 8 | example: string; 9 | default: string | string[] | boolean | number; 10 | items: { 11 | type?: string; 12 | $ref?: string; 13 | }; 14 | format: string; 15 | enum?: (string | number)[]; 16 | }; 17 | -------------------------------------------------------------------------------- /mon-web/src/pages/Silence/services.jsx: -------------------------------------------------------------------------------- 1 | import api from '@common/api'; 2 | import request from '@pkgs/request'; 3 | 4 | export function addSilence(reqData) { 5 | return request(api.maskconf, { 6 | method: 'POST', 7 | body: JSON.stringify(reqData), 8 | }); 9 | } 10 | 11 | export function releaseSilence(id) { 12 | return request(`${api.maskconf}/${id}`, { 13 | method: 'DELETE', 14 | }); 15 | } 16 | -------------------------------------------------------------------------------- /rdb-web/src/pages/RoleManagement/assets/style.less: -------------------------------------------------------------------------------- 1 | @import '~antd/lib/style/themes/default.less'; 2 | @meta-cls: rdb-role-meta; 3 | 4 | .@{meta-cls} { 5 | height: 70px; 6 | padding: 10px 20px; 7 | margin-bottom: 20px; 8 | border-radius: 3px; 9 | background-color: #fafafa; 10 | border: 1px solid @border-color-split; 11 | 12 | .@{meta-cls}-detail { 13 | font-size: 12px; 14 | margin-top: 10px; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /rdb-web/src/pages/TeamManagement/assets/style.less: -------------------------------------------------------------------------------- 1 | @import '~antd/lib/style/themes/default.less'; 2 | @meta-cls: rdb-team-meta; 3 | 4 | .@{meta-cls} { 5 | height: 70px; 6 | padding: 10px 20px; 7 | margin-bottom: 20px; 8 | border-radius: 3px; 9 | background-color: #fafafa; 10 | border: 1px solid @border-color-split; 11 | 12 | .@{meta-cls}-detail { 13 | font-size: 12px; 14 | margin-top: 10px; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /rdb-web/src/pages/TreenodeManagement/NodeCate/config.ts: -------------------------------------------------------------------------------- 1 | export const fields = [ 2 | { 3 | name: '字符串', 4 | ident: 'string', 5 | }, { 6 | name: '数值', 7 | ident: 'number', 8 | }, { 9 | name: '枚举', 10 | ident: 'enum', 11 | }, { 12 | name: '时间', 13 | ident: 'time', 14 | }, { 15 | name: '用户', 16 | ident: 'user', 17 | }, { 18 | name: '团队', 19 | ident: 'team', 20 | }, 21 | ]; 22 | -------------------------------------------------------------------------------- /rdb-web/src/pages/PersonnelInfo/Teams/assets/style.less: -------------------------------------------------------------------------------- 1 | @import '~antd/lib/style/themes/default.less'; 2 | @meta-cls: rdb-team-meta; 3 | 4 | .@{meta-cls} { 5 | height: 70px; 6 | padding: 10px 20px; 7 | margin-bottom: 20px; 8 | border-radius: 3px; 9 | background-color: #fafafa; 10 | border: 1px solid @border-color-split; 11 | 12 | .@{meta-cls}-detail { 13 | font-size: 12px; 14 | margin-top: 10px; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /ams-web/config/webpackConfigResolveAlias.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var cwd = process.cwd(); 3 | 4 | module.exports = { 5 | react: path.resolve('./node_modules/react'), 6 | 'react-dom': '@hot-loader/react-dom', 7 | '@common': path.resolve(cwd, 'src/common'), 8 | '@interface': path.resolve(cwd, 'src/interface'), 9 | '@pkgs': path.resolve(cwd, 'src/packages'), 10 | '@cpts': path.resolve(cwd, 'src/components'), 11 | }; 12 | -------------------------------------------------------------------------------- /ams-web/static/amsMenusConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ams", 3 | "path": "ams", 4 | "icon": "#iconzichanguanlixitongicon", 5 | "children": [{ 6 | "name": "hosts", 7 | "path": "hosts", 8 | "icon": "#iconzhujishebeiicon", 9 | "permissionPoint": "ams_host_mgr_menu", 10 | "children": [{ 11 | "name": "management", 12 | "path": "management" 13 | }, { 14 | "name": "search", 15 | "path": "search" 16 | }] 17 | }] 18 | } 19 | -------------------------------------------------------------------------------- /job-web/config/webpackConfigResolveAlias.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var cwd = process.cwd(); 3 | 4 | module.exports = { 5 | react: path.resolve('./node_modules/react'), 6 | 'react-dom': '@hot-loader/react-dom', 7 | '@common': path.resolve(cwd, 'src/common'), 8 | '@cpts': path.resolve(cwd, 'src/components'), 9 | '@pkgs': path.resolve(cwd, 'src/packages'), 10 | '@interface': path.resolve(cwd, 'src/interface'), 11 | }; 12 | -------------------------------------------------------------------------------- /mon-web/config/webpackConfigResolveAlias.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var cwd = process.cwd(); 3 | 4 | module.exports = { 5 | react: path.resolve('./node_modules/react'), 6 | 'react-dom': '@hot-loader/react-dom', 7 | '@common': path.resolve(cwd, 'src/common'), 8 | '@cpts': path.resolve(cwd, 'src/components'), 9 | '@pkgs': path.resolve(cwd, 'src/packages'), 10 | '@interface': path.resolve(cwd, 'src/interface'), 11 | }; 12 | -------------------------------------------------------------------------------- /rdb-web/config/webpackConfigResolveAlias.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var cwd = process.cwd(); 3 | 4 | module.exports = { 5 | react: path.resolve('./node_modules/react'), 6 | 'react-dom': '@hot-loader/react-dom', 7 | '@common': path.resolve(cwd, 'src/common'), 8 | '@interface': path.resolve(cwd, 'src/interface'), 9 | '@pkgs': path.resolve(cwd, 'src/packages'), 10 | '@cpts': path.resolve(cwd, 'src/components'), 11 | }; 12 | -------------------------------------------------------------------------------- /layout-web/static/js/named-exports.min.js: -------------------------------------------------------------------------------- 1 | !function(){const t=System.constructor.prototype;let e;const n=t.register;t.register=function(t,c){e=c,n.call(this,t,c)};const c=t.getRegister;t.getRegister=function(){const t=c.call(this);if(!t||t[1]===e||0===t[1].length)return t;const n=t[1];return t[1]=function(t,e){let c;const o=n.call(this,function(e,n){"default"===e&&(c=n),"__useDefault"!==e&&t(e,n)},e),s=o.execute;return s&&(o.execute=function(){s.call(this),"object"==typeof c&&t(c)}),o},t}}(); -------------------------------------------------------------------------------- /ams-web/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["airbnb-typescript"], 3 | "parserOptions": { 4 | "project": "./tsconfig.json" 5 | }, 6 | "rules": { 7 | "import/no-cycle": 0, 8 | "max-len": [ 9 | 1, 10 | 100, 11 | 2, 12 | { 13 | "ignoreUrls": true, 14 | "ignoreComments": false, 15 | "ignoreRegExpLiterals": true, 16 | "ignoreStrings": true, 17 | "ignoreTemplateLiterals": true 18 | } 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /job-web/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["airbnb-typescript"], 3 | "parserOptions": { 4 | "project": "./tsconfig.json" 5 | }, 6 | "rules": { 7 | "import/no-cycle": 0, 8 | "max-len": [ 9 | 1, 10 | 100, 11 | 2, 12 | { 13 | "ignoreUrls": true, 14 | "ignoreComments": false, 15 | "ignoreRegExpLiterals": true, 16 | "ignoreStrings": true, 17 | "ignoreTemplateLiterals": true 18 | } 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /mon-web/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["airbnb-typescript"], 3 | "parserOptions": { 4 | "project": "./tsconfig.json" 5 | }, 6 | "rules": { 7 | "import/no-cycle": 0, 8 | "max-len": [ 9 | 1, 10 | 100, 11 | 2, 12 | { 13 | "ignoreUrls": true, 14 | "ignoreComments": false, 15 | "ignoreRegExpLiterals": true, 16 | "ignoreStrings": true, 17 | "ignoreTemplateLiterals": true 18 | } 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /rdb-web/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["airbnb-typescript"], 3 | "parserOptions": { 4 | "project": "./tsconfig.json" 5 | }, 6 | "rules": { 7 | "import/no-cycle": 0, 8 | "max-len": [ 9 | 1, 10 | 100, 11 | 2, 12 | { 13 | "ignoreUrls": true, 14 | "ignoreComments": false, 15 | "ignoreRegExpLiterals": true, 16 | "ignoreStrings": true, 17 | "ignoreTemplateLiterals": true 18 | } 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /layout-web/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["airbnb-typescript"], 3 | "parserOptions": { 4 | "project": "./tsconfig.json" 5 | }, 6 | "rules": { 7 | "import/no-cycle": 0, 8 | "max-len": [ 9 | 1, 10 | 100, 11 | 2, 12 | { 13 | "ignoreUrls": true, 14 | "ignoreComments": false, 15 | "ignoreRegExpLiterals": true, 16 | "ignoreStrings": true, 17 | "ignoreTemplateLiterals": true 18 | } 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /mon-web/src/pages/Screen/style.less: -------------------------------------------------------------------------------- 1 | @screen-prefix-cls: ~"@{prefix-cls}-monitor-screen"; 2 | 3 | .@{screen-prefix-cls} { 4 | tr.drop-over-downward td { 5 | border-bottom: 2px dashed #1890ff; 6 | } 7 | tr.drop-over-upward td { 8 | border-top: 2px dashed #1890ff; 9 | } 10 | } 11 | 12 | .@{screen-prefix-cls}-detail-anchor { 13 | position: fixed; 14 | right: 0; 15 | top: 50%; 16 | z-index: 1; 17 | .ant-anchor-wrapper { 18 | padding-right: 10px; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .idea/ 3 | .ipr 4 | .iws 5 | *~ 6 | ~* 7 | *.diff 8 | *.patch 9 | *.bak 10 | .DS_Store 11 | Thumbs.db 12 | .project 13 | .*proj 14 | .svn/ 15 | *.swp 16 | *.swo 17 | *.pyc 18 | *.pyo 19 | node_modules 20 | */node_modules 21 | npm-debug.log 22 | coverage 23 | .cache-loader 24 | */.cache-loader 25 | src/packages 26 | */src/packages 27 | src/packages/* 28 | package-lock.json 29 | */package-lock.json 30 | pub 31 | */pub 32 | */.gitlab-ci.yml 33 | pub.tar.gz 34 | proxy.config.js 35 | deploy.sh 36 | -------------------------------------------------------------------------------- /layout-web/config/webpackConfigResolveAlias.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var cwd = process.cwd(); 3 | 4 | module.exports = { 5 | react: path.resolve('./node_modules/react'), 6 | 'react-dom': '@hot-loader/react-dom', 7 | '@common': path.resolve(cwd, 'src/common'), 8 | '@BComponent': path.resolve(cwd, 'src/components/BaseComponent'), 9 | '@interface': path.resolve(cwd, 'src/interface'), 10 | '@pkgs': path.resolve(cwd, 'src/packages'), 11 | '@cpts': path.resolve(cwd, 'src/components'), 12 | }; 13 | -------------------------------------------------------------------------------- /job-web/src/common/api.tsx: -------------------------------------------------------------------------------- 1 | function getApi(sys: string, path: string) { 2 | const prefix = '/api/'; 3 | return `${prefix}${sys}${path}`; 4 | } 5 | 6 | const api = { 7 | // instGroups: getApi('job-ce', '/inst-groups'), 8 | // instGroup: getApi('job-ce', '/inst-group'), 9 | tasktpls: getApi('job-ce', '/task-tpls'), 10 | tasktpl: getApi('job-ce', '/task-tpl'), 11 | tasks: getApi('job-ce', '/tasks'), 12 | task: getApi('job-ce', '/task'), 13 | perms: getApi('job-ce', '/builtin-perms'), 14 | }; 15 | 16 | export default api; 17 | -------------------------------------------------------------------------------- /job-web/src/pages/TaskTpl/interface.ts: -------------------------------------------------------------------------------- 1 | 2 | export interface Tpl { 3 | id: number, 4 | title: string, 5 | batch: number, // 并发度,页面填充的默认值是0, 6 | tolerance: number, // 容忍度,页面填充的默认值是0, 7 | timeout: number, // 单机超时时间,页面填充的默认值是30, 8 | pause: number, // 暂停点,默认值为空, 9 | script: string, // 脚本内容,默认值参看之前四维的版本, 10 | args: string, // 脚本参数,默认值为空, 11 | tags: string, // 任务模板的标签, 12 | account: string, // 运行账号, 13 | hosts: string[], 14 | creator: string, 15 | created: string, 16 | last_updator: string, 17 | last_updated: string, 18 | // grp: Group, 19 | } 20 | -------------------------------------------------------------------------------- /mon-web/src/pages/Silence/style.less: -------------------------------------------------------------------------------- 1 | @strategy-prefix-cls: ~"@{prefix-cls}-monitor-silence"; 2 | 3 | .@{strategy-prefix-cls} { 4 | .noMarginBottom { 5 | margin-bottom: 0; 6 | } 7 | .readOnly { 8 | .ant-radio-disabled .ant-radio-inner:after { 9 | background-color: #666; 10 | } 11 | .ant-select-disabled .ant-select-selection--multiple .ant-select-selection__choice { 12 | color: #666; 13 | } 14 | .ant-input-number-input[disabled], .ant-input[disabled], fieldset[disabled] .ant-input { 15 | color: #666; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /mon-web/src/pages/Strategy/SettingFields/Expressions/style.less: -------------------------------------------------------------------------------- 1 | .strategy-expressions { 2 | .expressions-and { 3 | position: relative; 4 | } 5 | .expressions-and-tagBorder { 6 | position: absolute; 7 | top: -40px; 8 | right: -30px; 9 | z-index: 1; 10 | width: 30px; 11 | height: 70px; 12 | border: 1px solid #ddd; 13 | border-left: 0 none; 14 | } 15 | .expressions-and-tag { 16 | position: absolute; 17 | top: -23px; 18 | right: -50px; 19 | z-index: 1; 20 | } 21 | .ant-card { 22 | line-height: inherit; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /rdb-web/src/pages/Settings/Security/Login/services.tsx: -------------------------------------------------------------------------------- 1 | import api from '@common/api'; 2 | import request from '@pkgs/request'; 3 | 4 | export const auth = async () => { 5 | try { 6 | const data = await request(api.auth); 7 | return data; 8 | } catch (e) { 9 | console.log(e); 10 | } 11 | } 12 | 13 | export const authPost = async (reqBody: {}) => { 14 | try { 15 | const data = await request(api.auth, { 16 | method: "PUT", 17 | body: JSON.stringify(reqBody), 18 | }); 19 | return data; 20 | } catch (e) { 21 | console.log(e); 22 | } 23 | } -------------------------------------------------------------------------------- /ams-web/src/common/exportHosts.tsx: -------------------------------------------------------------------------------- 1 | import XLSX from 'xlsx'; 2 | import _ from 'lodash'; 3 | 4 | export default function exportHosts(data: any, pickProperty: any, filename = 'hosts') { 5 | const newData = _.map(data, (item) => { 6 | const baseProperty = ['id', 'ident', 'ip', 'name', 'sn', 'cpu', 'mem', 'disk', 'tenant', 'cate', 'note']; 7 | return _.pick(item, _.concat(baseProperty, pickProperty)); 8 | }); 9 | const wb = XLSX.utils.book_new(); 10 | const ws = XLSX.utils.json_to_sheet(newData); 11 | 12 | XLSX.utils.book_append_sheet(wb, ws, filename); 13 | XLSX.writeFile(wb, `${filename}.xlsx`); 14 | } 15 | -------------------------------------------------------------------------------- /rdb-web/src/common/exportResources.tsx: -------------------------------------------------------------------------------- 1 | import XLSX from 'xlsx'; 2 | import _ from 'lodash'; 3 | 4 | export default function exportHosts(data: any, pickProperty: any, filename = 'resources') { 5 | const newData = _.map(data, (item) => { 6 | const baseProperty = ['id', 'uuid', 'ident', 'name', 'labels', 'note', 'extend', 'cate', 'tenant']; 7 | return _.pick(item, _.concat(baseProperty, pickProperty)); 8 | }); 9 | const wb = XLSX.utils.book_new(); 10 | const ws = XLSX.utils.json_to_sheet(newData); 11 | 12 | XLSX.utils.book_append_sheet(wb, ws, filename); 13 | XLSX.writeFile(wb, `${filename}.xlsx`); 14 | } 15 | -------------------------------------------------------------------------------- /layout-web/static/menusConfig.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "name": "开发与运维", 3 | "nameEn": "ECMC", 4 | "type": "group", 5 | "children": [{ 6 | "name": "用户资源中心", 7 | "nameEn": "RDB", 8 | "path": "rdb", 9 | "icon": "#iconyonghuziyuanzhongxinicon" 10 | }, { 11 | "name": "资产管理系统", 12 | "nameEn": "AMS", 13 | "path": "ams", 14 | "icon": "#iconzichanguanlixitongicon" 15 | }, { 16 | "name": "任务执行中心", 17 | "nameEn": "JOB", 18 | "path": "job", 19 | "icon": "#iconrenwuzhongxinicon" 20 | }, { 21 | "name": "监控告警系统", 22 | "nameEn": "MON", 23 | "path": "mon", 24 | "icon": "#iconjiankonggaojingxitongicon" 25 | }] 26 | }] 27 | -------------------------------------------------------------------------------- /mon-web/src/pages/Binlog/config.ts: -------------------------------------------------------------------------------- 1 | export const interval = [10, 30, 60, 120, 300, 600, 1800, 3600]; 2 | export const serviceRule = { 3 | pattern: /^[\u4e00-\u9fa5a-zA-Z0-9\_]{0,128}$/, 4 | message: "服务只允许英文、数字、_", 5 | }; 6 | 7 | // 获取url,search部分转换为对象 8 | export const getQueryVariabe = (name: any) => { 9 | try{ 10 | let h = window.location.href.split("?")[1]; 11 | let vars = h.split("&"); 12 | let pair = [] as any; 13 | for (let i = 0; i < vars.length; i++) { 14 | pair = vars[i].split("="); 15 | if (pair[0] == name) return pair[1]; 16 | } 17 | return pair[1]; 18 | }catch{ 19 | return '' 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /mon-web/src/pages/NginxLog/config.ts: -------------------------------------------------------------------------------- 1 | export const interval = [10, 30, 60, 120, 300, 600, 1800, 3600]; 2 | export const serviceRule = { 3 | pattern: /^[\u4e00-\u9fa5a-zA-Z0-9\_]{0,128}$/, 4 | message: "服务只允许英文、数字、_", 5 | }; 6 | 7 | // 获取url,search部分转换为对象 8 | export const getQueryVariabe = (name: any) => { 9 | try{ 10 | let h = window.location.href.split("?")[1]; 11 | let vars = h.split("&"); 12 | let pair = [] as any; 13 | for (let i = 0; i < vars.length; i++) { 14 | pair = vars[i].split("="); 15 | if (pair[0] == name) return pair[1]; 16 | } 17 | return pair[1]; 18 | }catch{ 19 | return '' 20 | } 21 | }; 22 | -------------------------------------------------------------------------------- /mon-web/src/pages/History/style.less: -------------------------------------------------------------------------------- 1 | @prefixCls: ~"@{prefix-cls}-history"; 2 | 3 | .@{prefixCls}-detail { 4 | .ant-card-head { 5 | min-height: unset; 6 | // height: 35px; 7 | // line-height: 35px; 8 | background-color: #f9f9f9; 9 | padding: 0 10px !important; 10 | } 11 | .ant-card-head-title { 12 | padding: 0; 13 | } 14 | } 15 | 16 | .@{prefixCls}-detail-list { 17 | & > div { 18 | margin-bottom: 10px; 19 | } 20 | .label { 21 | display: inline-block; 22 | width: 90px; 23 | text-align: right; 24 | } 25 | .ant-table-wrapper { 26 | display: inline-block; 27 | width: 400px; 28 | vertical-align: top; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /job-web/src/pages/Task/style.less: -------------------------------------------------------------------------------- 1 | @task-table-prefix-cls: ~"@{prefix-cls}-zeus-task-table"; 2 | @task-result-prefix-cls: ~"@{prefix-cls}-zeus-task-result"; 3 | 4 | .@{task-table-prefix-cls} { 5 | .ant-table-small > .ant-table-content > .ant-table-body { 6 | margin: 0; 7 | } 8 | .ant-table-small > .ant-table-content > .ant-table-body > table > .ant-table-tbody > tr > td:first-child { 9 | font-weight: 500; 10 | text-align: right; 11 | } 12 | pre { 13 | margin-bottom: 0; 14 | border-radius: 4px; 15 | code { 16 | padding: 15px; 17 | } 18 | } 19 | } 20 | 21 | .@{task-result-prefix-cls} { 22 | .active { 23 | text-decoration: underline; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /layout-web/fetk.config.js: -------------------------------------------------------------------------------- 1 | let proxyConf = {}; 2 | 3 | try { 4 | proxyConf = require('../proxy.config.js'); 5 | } catch (e) { 6 | console.log('根目录缺少 proxy.config.js 文件'); 7 | } 8 | 9 | module.exports = { 10 | devEntry: { 11 | layout: './src/index.tsx', 12 | }, 13 | buildEntry: { 14 | layout: './src/index.tsx', 15 | }, 16 | webpackDevConfig: 'config/webpack.dev.config.js', 17 | webpackBuildConfig: 'config/webpack.build.config.js', 18 | theme: 'config/theme.js', 19 | template: 'src/index.html', 20 | output: '../pub/layout', 21 | eslintFix: false, 22 | hmr: false, 23 | port: 8000, 24 | devServer: { 25 | inline: true, 26 | proxy: proxyConf, 27 | historyApiFallback: true, 28 | }, 29 | }; 30 | -------------------------------------------------------------------------------- /ams-web/README.md: -------------------------------------------------------------------------------- 1 | ## 开发 2 | 3 | ```shell 4 | // 安装公共组件 5 | git clone src/packages 6 | // 安装第三方依赖 7 | npm install 8 | // 运行子系统 9 | npm run start 10 | ``` 11 | 12 | ## 构建 13 | 14 | ```shell 15 | npm run build 16 | ``` 17 | 18 | 构建后的代码默认会存放到 `../pub` 文件夹里 19 | 20 | ## 目录结构 21 | 22 | - config: 开发 & 构建配置 23 | - theme.js:antd 主题配置 24 | - webpack.dev.config.js:webpack 开发环境补充配置,覆盖默认配置 25 | - webpack.build.config.js:webpack 构建补充配置,覆盖默认配置 26 | - webpackConfigResolveAlias.js 文件路径别名配置 27 | - src:源代码所在目录 28 | - assets:全局资源 img、css 29 | - common: 全局配置、通用方法 30 | - components:公共组件 31 | - pages:路由匹配的页面组件 32 | - app.jsx 菜单、路由配置组件 33 | - index.html:单页 34 | - index.jsx:入口文件 35 | - fetk.config.js 开发工具配置页面 36 | 37 | -------------------------------------------------------------------------------- /job-web/README.md: -------------------------------------------------------------------------------- 1 | ## 开发 2 | 3 | ```shell 4 | // 安装公共组件 5 | git clone src/packages 6 | // 安装第三方依赖 7 | npm install 8 | // 运行子系统 9 | npm run start 10 | ``` 11 | 12 | ## 构建 13 | 14 | ```shell 15 | npm run build 16 | ``` 17 | 18 | 构建后的代码默认会存放到 `../pub` 文件夹里 19 | 20 | ## 目录结构 21 | 22 | - config: 开发 & 构建配置 23 | - theme.js:antd 主题配置 24 | - webpack.dev.config.js:webpack 开发环境补充配置,覆盖默认配置 25 | - webpack.build.config.js:webpack 构建补充配置,覆盖默认配置 26 | - webpackConfigResolveAlias.js 文件路径别名配置 27 | - src:源代码所在目录 28 | - assets:全局资源 img、css 29 | - common: 全局配置、通用方法 30 | - components:公共组件 31 | - pages:路由匹配的页面组件 32 | - app.jsx 菜单、路由配置组件 33 | - index.html:单页 34 | - index.jsx:入口文件 35 | - fetk.config.js 开发工具配置页面 36 | 37 | -------------------------------------------------------------------------------- /layout-web/README.md: -------------------------------------------------------------------------------- 1 | ## 开发 2 | 3 | ```shell 4 | // 安装公共组件 5 | git clone src/packages 6 | // 安装第三方依赖 7 | npm install 8 | // 运行基座 9 | npm run start 10 | ``` 11 | 12 | ## 构建 13 | 14 | ```shell 15 | npm run build 16 | ``` 17 | 18 | 构建后的代码默认会存放到 `../pub` 文件夹里 19 | 20 | ## 目录结构 21 | 22 | - config: 开发 & 构建配置 23 | - theme.js:antd 主题配置 24 | - webpack.dev.config.js:webpack 开发环境补充配置,覆盖默认配置 25 | - webpack.build.config.js:webpack 构建补充配置,覆盖默认配置 26 | - webpackConfigResolveAlias.js 文件路径别名配置 27 | - src:源代码所在目录 28 | - assets:全局资源 img、css 29 | - common: 全局配置、通用方法 30 | - components:公共组件 31 | - pages:路由匹配的页面组件 32 | - app.jsx 菜单、路由配置组件 33 | - index.html:单页 34 | - index.jsx:入口文件 35 | - fetk.config.js 开发工具配置页面 36 | 37 | -------------------------------------------------------------------------------- /mon-web/README.md: -------------------------------------------------------------------------------- 1 | ## 开发 2 | 3 | ```shell 4 | // 安装公共组件 5 | git clone src/packages 6 | // 安装第三方依赖 7 | npm install 8 | // 运行子系统 9 | npm run start 10 | ``` 11 | 12 | ## 构建 13 | 14 | ```shell 15 | npm run build 16 | ``` 17 | 18 | 构建后的代码默认会存放到 `../pub` 文件夹里 19 | 20 | ## 目录结构 21 | 22 | - config: 开发 & 构建配置 23 | - theme.js:antd 主题配置 24 | - webpack.dev.config.js:webpack 开发环境补充配置,覆盖默认配置 25 | - webpack.build.config.js:webpack 构建补充配置,覆盖默认配置 26 | - webpackConfigResolveAlias.js 文件路径别名配置 27 | - src:源代码所在目录 28 | - assets:全局资源 img、css 29 | - common: 全局配置、通用方法 30 | - components:公共组件 31 | - pages:路由匹配的页面组件 32 | - app.jsx 菜单、路由配置组件 33 | - index.html:单页 34 | - index.jsx:入口文件 35 | - fetk.config.js 开发工具配置页面 36 | 37 | -------------------------------------------------------------------------------- /rdb-web/README.md: -------------------------------------------------------------------------------- 1 | ## 开发 2 | 3 | ```shell 4 | // 安装公共组件 5 | git clone src/packages 6 | // 安装第三方依赖 7 | npm install 8 | // 运行子系统 9 | npm run start 10 | ``` 11 | 12 | ## 构建 13 | 14 | ```shell 15 | npm run build 16 | ``` 17 | 18 | 构建后的代码默认会存放到 `../pub` 文件夹里 19 | 20 | ## 目录结构 21 | 22 | - config: 开发 & 构建配置 23 | - theme.js:antd 主题配置 24 | - webpack.dev.config.js:webpack 开发环境补充配置,覆盖默认配置 25 | - webpack.build.config.js:webpack 构建补充配置,覆盖默认配置 26 | - webpackConfigResolveAlias.js 文件路径别名配置 27 | - src:源代码所在目录 28 | - assets:全局资源 img、css 29 | - common: 全局配置、通用方法 30 | - components:公共组件 31 | - pages:路由匹配的页面组件 32 | - app.jsx 菜单、路由配置组件 33 | - index.html:单页 34 | - index.jsx:入口文件 35 | - fetk.config.js 开发工具配置页面 36 | 37 | -------------------------------------------------------------------------------- /ams-web/fetk.config.js: -------------------------------------------------------------------------------- 1 | const pkgJson = require('./package'); 2 | 3 | module.exports = { 4 | devEntry: { 5 | [pkgJson.systemName]: process.env.Mode === 'headless' ? './src/HeadlessIndex.tsx' : './src/index.tsx', 6 | }, 7 | buildEntry: { 8 | [pkgJson.systemName]: './src/index.tsx', 9 | }, 10 | webpackDevConfig: 'config/webpack.dev.config.js', 11 | webpackBuildConfig: 'config/webpack.build.config.js', 12 | theme: 'config/theme.js', 13 | template: 'src/index.html', 14 | output: '../pub/ams', 15 | eslintFix: false, 16 | hmr: false, 17 | port: 8002, 18 | devServer: { 19 | inline: true, 20 | historyApiFallback: true, 21 | headers: { 22 | 'Access-Control-Allow-Origin': '*', 23 | }, 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /job-web/fetk.config.js: -------------------------------------------------------------------------------- 1 | const pkgJson = require('./package'); 2 | 3 | module.exports = { 4 | devEntry: { 5 | [pkgJson.systemName]: process.env.Mode === 'headless' ? './src/HeadlessIndex.tsx' : './src/index.tsx', 6 | }, 7 | buildEntry: { 8 | [pkgJson.systemName]: './src/index.tsx', 9 | }, 10 | webpackDevConfig: 'config/webpack.dev.config.js', 11 | webpackBuildConfig: 'config/webpack.build.config.js', 12 | theme: 'config/theme.js', 13 | template: 'src/index.html', 14 | output: '../pub/job', 15 | eslintFix: false, 16 | hmr: false, 17 | port: 8003, 18 | devServer: { 19 | inline: true, 20 | historyApiFallback: true, 21 | headers: { 22 | 'Access-Control-Allow-Origin': '*', 23 | }, 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /rdb-web/fetk.config.js: -------------------------------------------------------------------------------- 1 | const pkgJson = require('./package'); 2 | 3 | module.exports = { 4 | devEntry: { 5 | [pkgJson.systemName]: process.env.Mode === 'headless' ? './src/HeadlessIndex.tsx' : './src/index.tsx', 6 | }, 7 | buildEntry: { 8 | [pkgJson.systemName]: './src/index.tsx', 9 | }, 10 | webpackDevConfig: 'config/webpack.dev.config.js', 11 | webpackBuildConfig: 'config/webpack.build.config.js', 12 | theme: 'config/theme.js', 13 | template: 'src/index.html', 14 | output: '../pub/rdb', 15 | eslintFix: false, 16 | hmr: false, 17 | port: 8001, 18 | devServer: { 19 | inline: true, 20 | historyApiFallback: true, 21 | headers: { 22 | 'Access-Control-Allow-Origin': '*', 23 | }, 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /ams-web/src/pages/Nethws/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Switch, Route, Redirect } from 'react-router-dom'; 3 | import PrivateRoute from '@pkgs/Auth/PrivateRoute'; 4 | import Management from './Management'; 5 | import MIB from './MIB'; 6 | 7 | export default class Routes extends Component { 8 | render() { 9 | const prePath = '/nethws'; 10 | return ( 11 | 12 | } /> 13 | 14 | 15 | } /> 16 | 17 | ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /mon-web/src/pages/Strategy/services.jsx: -------------------------------------------------------------------------------- 1 | import api from '@common/api'; 2 | import request from '@pkgs/request'; 3 | 4 | export function getStrategies() { 5 | return request(api.stra); 6 | } 7 | 8 | export function addStrategy(reqData) { 9 | return request(api.stra, { 10 | method: 'POST', 11 | body: JSON.stringify(reqData), 12 | }); 13 | } 14 | 15 | export function delStrategy(ids) { 16 | return request(api.stra, { 17 | method: 'DELETE', 18 | body: JSON.stringify({ 19 | ids, 20 | }), 21 | }); 22 | } 23 | 24 | export function getStrategy(id) { 25 | return request(`${api.stra}/${id}`); 26 | } 27 | 28 | export function modifyStrategy(reqData) { 29 | return request(api.stra, { 30 | method: 'PUT', 31 | body: JSON.stringify(reqData), 32 | }); 33 | } 34 | -------------------------------------------------------------------------------- /layout-web/config/webpack.dev.config.js: -------------------------------------------------------------------------------- 1 | const webpackConfigResolveAlias = require('./webpackConfigResolveAlias'); 2 | const CoverHtmlWebpackPlugin = require('./CoverHtmlWebpackPlugin.js'); 3 | 4 | module.exports = function(webpackConfig) { 5 | webpackConfig.output.library = 'layout'; 6 | webpackConfig.output.libraryTarget = 'amd'; 7 | webpackConfig.resolve.alias = webpackConfigResolveAlias; 8 | webpackConfig.module.rules.unshift({ 9 | parser: { system: false }, 10 | }); 11 | webpackConfig.externals = [ 12 | /^react$/, 13 | /^react\/lib.*/, 14 | /^react-dom$/, 15 | /.*react-dom.*/, 16 | /^single-spa$/, 17 | /^antd$/, 18 | /^d3$/ 19 | ]; 20 | webpackConfig.plugins.push( 21 | new CoverHtmlWebpackPlugin(), 22 | ); 23 | return webpackConfig; 24 | } 25 | -------------------------------------------------------------------------------- /rdb-web/src/pages/Settings/Security/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Tabs } from 'antd'; 3 | import Login from './Login'; 4 | import White from './White'; 5 | 6 | 7 | const { TabPane } = Tabs; 8 | const defaultActiveKey = window.localStorage.getItem('resources-tree-active-key') || 'role'; 9 | 10 | function index() { 11 | return ( 12 | { 16 | window.localStorage.setItem('resources-tree-active-key', key); 17 | }} 18 | > 19 | 20 | < Login/> 21 | 22 | 23 | < White/> 24 | 25 | 26 | ) 27 | } 28 | 29 | export default index; 30 | -------------------------------------------------------------------------------- /mon-web/src/pages/Charts/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import SolidGauge from '@pkgs/Charts/SolidGauge'; 3 | import LiquidFillGauge from '@pkgs/Charts/LiquidFillGauge'; 4 | import Pie from '@pkgs/Charts/Pie'; 5 | 6 | export default function index() { 7 | return ( 8 |
9 | 10 | 11 | 29 |
30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /mon-web/src/pages/Strategy/SettingFields/Filters/Filter.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Card, Tag } from 'antd'; 3 | import _ from 'lodash'; 4 | import { FormattedMessage } from 'react-intl'; 5 | 6 | const toptMap = { 7 | '=': 'stra.tag.include', 8 | '!=': 'stra.tag.exclude', 9 | }; 10 | 11 | export default function Filter(props) { 12 | const { data, extra } = props; 13 | const { tkey, topt, tval } = data; 14 | 15 | return ( 16 | 20 | {tkey} 21 | {} 22 | 23 | } 24 | extra={extra} 25 | > 26 | { 27 | _.map(tval, o => {o}) 28 | } 29 | 30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /mon-web/src/pages/Binlog/services.jsx: -------------------------------------------------------------------------------- 1 | import api from '@common/api'; 2 | import request from '@pkgs/request'; 3 | 4 | export const getList = () => { 5 | return request(api.binlog); 6 | }; 7 | 8 | export const getSignalList = (id) => { 9 | return request(`${api.binlogSearch}/${id}`); 10 | }; 11 | 12 | export const getTreeData = () => { 13 | return request(api.tree); 14 | }; 15 | 16 | export const addList = (body) => { 17 | return request(api.binlog, { 18 | method: 'POST', 19 | body: JSON.stringify(body), 20 | }); 21 | }; 22 | export const deletebinlog = (ids) => { 23 | return request(api.binlog, { 24 | method: 'DELETE', 25 | body: JSON.stringify({ ids }), 26 | }); 27 | }; 28 | 29 | export const updateList = (body) => { 30 | return request(api.binlog, { 31 | method: 'PUT', 32 | body: JSON.stringify(body), 33 | }); 34 | }; 35 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | define build-one 2 | rm -rf $(1)/src/packages &&\ 3 | cp -r fe-packages $(1)/src/packages && cd $(1) && npm install && npm run build && cd .. 4 | endef 5 | 6 | clone-pkg: 7 | git clone https://github.com/n9e/fe-packages 8 | 9 | update-pkg:clean clone-pkg 10 | @echo "done update" 11 | 12 | build: 13 | $(call build-one, layout-web) 14 | $(call build-one, mon-web) 15 | $(call build-one, ams-web) 16 | $(call build-one, job-web) 17 | $(call build-one, rdb-web) 18 | cp -r layout-web/static pub/ 19 | 20 | clean: 21 | rm -rf fe-packages 22 | 23 | local-run: 24 | sudo docker run --name n9e-nginx --rm --net host --add-host "n9e.rdb n9e.ams n9e.job n9e.index n9e.monapi n9e.transfer:127.0.0.1" \ 25 | -v $(shell pwd)/pub:/home/ecmc/pub -v $(shell pwd)/nginx.conf:/etc/nginx/conf.d/default.conf -dit nginx:1.17 26 | local-stop: 27 | sudo docker stop n9e-nginx -------------------------------------------------------------------------------- /ams-web/src/pages/Hosts/Management/style.less: -------------------------------------------------------------------------------- 1 | .ant-card-head-title{ 2 | color: #526ecc; 3 | } 4 | 5 | .ams-hosts-desc-item { 6 | display: flex; 7 | flex-wrap: wrap; 8 | margin-bottom: 4px; 9 | font-size: 12px; 10 | } 11 | 12 | .ams-hosts-desc-item-title { 13 | position: relative; 14 | flex: 0 1 auto; 15 | width: 80px; 16 | margin-right: 12px; 17 | word-break: break-word; 18 | text-align: right; 19 | line-height: 1.8; 20 | font-weight: 600; 21 | color: rgba(0, 0, 0, 0.85); 22 | } 23 | 24 | .ams-hosts-desc-item-content { 25 | // flex: 1; 26 | width: auto; 27 | word-break: break-word; 28 | line-height: 1.8; 29 | color: rgba(0, 0, 0, 0.65); 30 | } 31 | 32 | .ams-hosts-desc-item-show { 33 | height: 40px; 34 | line-height: 42px; 35 | flex: 1; 36 | width: auto; 37 | word-break: break-word; 38 | color: rgba(0, 0, 0, 0.65); 39 | } -------------------------------------------------------------------------------- /mon-web/src/pages/NginxLog/services.jsx: -------------------------------------------------------------------------------- 1 | import api from '@common/api'; 2 | import request from '@pkgs/request'; 3 | 4 | export const getList = () => { 5 | return request(api.nginx); 6 | }; 7 | 8 | export const getSignalList = (value) => { 9 | return request(`${api.nginxSearch}?value=${value}`); 10 | }; 11 | 12 | export const getTreeData = () => { 13 | return request(api.tree); 14 | }; 15 | 16 | export const addList = (body) => { 17 | return request(api.nginx, { 18 | method: 'POST', 19 | body: JSON.stringify(body), 20 | }); 21 | }; 22 | export const deletenginx = (ids) => { 23 | return request(api.nginx, { 24 | method: 'DELETE', 25 | body: JSON.stringify({ ids }), 26 | }); 27 | }; 28 | 29 | export const updateList = (body) => { 30 | return request(api.nginx, { 31 | method: 'PUT', 32 | body: JSON.stringify(body), 33 | }); 34 | }; 35 | -------------------------------------------------------------------------------- /job-web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "noFallthroughCasesInSwitch": true, 5 | "noUnusedParameters": true, 6 | "noImplicitReturns": true, 7 | "moduleResolution": "node", 8 | "esModuleInterop": true, 9 | "noUnusedLocals": true, 10 | "noImplicitAny": true, 11 | "target": "es2015", 12 | "module": "es2015", 13 | "strict": true, 14 | "jsx": "react", 15 | "allowJs": true, 16 | "noEmit": true, 17 | "baseUrl": ".", 18 | "paths": { 19 | "@common/*": ["src/common/*"], 20 | "@cpts/*": ["src/components/*"], 21 | "@pkgs/*": ["src/packages/*"], 22 | "@interface": ["src/interface"] 23 | } 24 | }, 25 | "include": [ 26 | "src/**/*" 27 | ], 28 | "exclude": [ 29 | "node_modules/*", 30 | "dist/*", 31 | "examples/*" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /mon-web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "noFallthroughCasesInSwitch": true, 5 | "noUnusedParameters": true, 6 | "noImplicitReturns": true, 7 | "moduleResolution": "node", 8 | "esModuleInterop": true, 9 | "noUnusedLocals": true, 10 | "noImplicitAny": true, 11 | "target": "es2015", 12 | "module": "es2015", 13 | "strict": true, 14 | "jsx": "react", 15 | "allowJs": true, 16 | "noEmit": true, 17 | "baseUrl": ".", 18 | "paths": { 19 | "@common/*": ["src/common/*"], 20 | "@cpts/*": ["src/components/*"], 21 | "@pkgs/*": ["src/packages/*"], 22 | "@interface": ["src/interface"] 23 | } 24 | }, 25 | "include": [ 26 | "src/**/*", 27 | ], 28 | "exclude": [ 29 | "node_modules/*", 30 | "dist/*", 31 | "examples/*" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /mon-web/src/pages/Strategy/SettingFields/WorkGroups/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import { Select } from 'antd'; 3 | import _ from 'lodash'; 4 | import request from '@pkgs/request'; 5 | 6 | export default function index(props: any) { 7 | const [data, setData] = useState([]); 8 | 9 | useEffect(() => { 10 | request('/api/ticket/queues?limit=5000').then((res) => { 11 | setData(res.list); 12 | }); 13 | }, []); 14 | 15 | return ( 16 | 31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /mon-web/src/pages/Strategy/SettingFields/Filters/style.less: -------------------------------------------------------------------------------- 1 | .strategy-filters { 2 | .ant-card-small { 3 | line-height: normal; 4 | .ant-card-head { 5 | height: 28px !important; 6 | line-height: 28px !important; 7 | padding: 0 10px !important; 8 | min-height: unset; 9 | } 10 | .ant-card-head-wrapper { 11 | height: 28px; 12 | } 13 | .ant-card-head-title { 14 | font-size: 12px; 15 | width: 90%; 16 | padding: 0; 17 | } 18 | .ant-card-extra { 19 | top: 5px !important; 20 | right: 10px !important; 21 | } 22 | .ant-card-body { 23 | padding: 10px !important; 24 | } 25 | } 26 | .ant-tag-fix { 27 | word-break: break-all; 28 | height: auto; 29 | overflow: inherit; 30 | } 31 | .strategy-filter-operation .anticon { 32 | cursor: pointer; 33 | padding: 0 3px; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /job-web/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import singleSpaReact from 'single-spa-react'; 4 | import { auth } from '@pkgs/Auth'; 5 | import App from './app'; 6 | 7 | function domElementGetter() { 8 | let el = document.getElementById('ecmc-layout-container'); 9 | if (!el) { 10 | el = document.createElement('div'); 11 | el.id = 'ecmc-layout-container'; 12 | document.body.appendChild(el); 13 | } 14 | 15 | return el; 16 | } 17 | 18 | const reactLifecycles = singleSpaReact({ 19 | React, 20 | ReactDOM, 21 | rootComponent: () => { 22 | auth.checkAuthenticate(); 23 | return ; 24 | }, 25 | domElementGetter, 26 | }); 27 | 28 | export const bootstrap = [ 29 | reactLifecycles.bootstrap, 30 | ]; 31 | 32 | export const mount = [ 33 | reactLifecycles.mount, 34 | ]; 35 | 36 | export const unmount = [ 37 | reactLifecycles.unmount, 38 | ]; 39 | -------------------------------------------------------------------------------- /mon-web/fetk.config.js: -------------------------------------------------------------------------------- 1 | const pkgJson = require('./package'); 2 | 3 | module.exports = { 4 | devEntry: { 5 | [pkgJson.systemName]: process.env.Mode === 'headless' ? './src/HeadlessIndex.tsx' : './src/index.tsx', 6 | }, 7 | buildEntry: { 8 | [pkgJson.systemName]: './src/index.tsx', 9 | }, 10 | webpackDevConfig: 'config/webpack.dev.config.js', 11 | webpackBuildConfig: 'config/webpack.build.config.js', 12 | theme: 'config/theme.js', 13 | template: 'src/index.html', 14 | output: '../pub/mon', 15 | eslintFix: false, 16 | hmr: false, 17 | port: 8004, 18 | extraBabelPlugins: [ 19 | [ 20 | 'babel-plugin-import', 21 | { 22 | libraryName: 'antd', 23 | style: true, 24 | }, 25 | ], 26 | ], 27 | devServer: { 28 | inline: true, 29 | historyApiFallback: true, 30 | headers: { 31 | 'Access-Control-Allow-Origin': '*', 32 | }, 33 | }, 34 | }; 35 | -------------------------------------------------------------------------------- /mon-web/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import singleSpaReact from 'single-spa-react'; 4 | import { auth } from '@pkgs/Auth'; 5 | import App from './app'; 6 | 7 | function domElementGetter() { 8 | let el = document.getElementById('ecmc-layout-container'); 9 | if (!el) { 10 | el = document.createElement('div'); 11 | el.id = 'ecmc-layout-container'; 12 | document.body.appendChild(el); 13 | } 14 | 15 | return el; 16 | } 17 | 18 | const reactLifecycles = singleSpaReact({ 19 | React, 20 | ReactDOM, 21 | rootComponent: () => { 22 | auth.checkAuthenticate(); 23 | return ; 24 | }, 25 | domElementGetter, 26 | }); 27 | 28 | export const bootstrap = [ 29 | reactLifecycles.bootstrap, 30 | ]; 31 | 32 | export const mount = [ 33 | reactLifecycles.mount, 34 | ]; 35 | 36 | export const unmount = [ 37 | reactLifecycles.unmount, 38 | ]; 39 | -------------------------------------------------------------------------------- /ams-web/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import singleSpaReact from 'single-spa-react'; 4 | import { auth } from '@pkgs/Auth'; 5 | import App from './app'; 6 | 7 | function domElementGetter() { 8 | let el = document.getElementById('ecmc-layout-container'); 9 | if (!el) { 10 | el = document.createElement('div'); 11 | el.id = 'ecmc-layout-container'; 12 | document.body.appendChild(el); 13 | } 14 | 15 | return el; 16 | } 17 | 18 | const reactLifecycles = singleSpaReact({ 19 | React, 20 | ReactDOM, 21 | rootComponent: (_props: any) => { 22 | auth.checkAuthenticate() 23 | return ; 24 | }, 25 | domElementGetter, 26 | }); 27 | 28 | export const bootstrap = [ 29 | reactLifecycles.bootstrap, 30 | ]; 31 | 32 | export const mount = [ 33 | reactLifecycles.mount, 34 | ]; 35 | 36 | export const unmount = [ 37 | reactLifecycles.unmount, 38 | ]; 39 | 40 | -------------------------------------------------------------------------------- /rdb-web/src/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import singleSpaReact from 'single-spa-react'; 4 | import { auth } from '@pkgs/Auth'; 5 | import App from './app'; 6 | 7 | function domElementGetter() { 8 | let el = document.getElementById('ecmc-layout-container'); 9 | if (!el) { 10 | el = document.createElement('div'); 11 | el.id = 'ecmc-layout-container'; 12 | document.body.appendChild(el); 13 | } 14 | 15 | return el; 16 | } 17 | 18 | const reactLifecycles = singleSpaReact({ 19 | React, 20 | ReactDOM, 21 | rootComponent: (_props: any) => { 22 | auth.checkAuthenticate() 23 | return ; 24 | }, 25 | domElementGetter, 26 | }); 27 | 28 | export const bootstrap = [ 29 | reactLifecycles.bootstrap, 30 | ]; 31 | 32 | export const mount = [ 33 | reactLifecycles.mount, 34 | ]; 35 | 36 | export const unmount = [ 37 | reactLifecycles.unmount, 38 | ]; 39 | 40 | -------------------------------------------------------------------------------- /ams-web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "noFallthroughCasesInSwitch": true, 5 | "noUnusedParameters": true, 6 | "noImplicitReturns": true, 7 | "moduleResolution": "node", 8 | "esModuleInterop": true, 9 | "noUnusedLocals": true, 10 | "noImplicitAny": true, 11 | "target": "es2015", 12 | "module": "es2015", 13 | "strict": true, 14 | "jsx": "react", 15 | "allowJs": true, 16 | "noEmit": true, 17 | "baseUrl": ".", 18 | "paths": { 19 | "@pkgs/*": ["src/packages/*"], 20 | "@common/*": ["src/common/*"], 21 | "@cpts/*": ["src/components/*"], 22 | "@BComponent": ["src/components/BaseComponent"], 23 | "@interface": ["src/interface"], 24 | }, 25 | }, 26 | "include": [ 27 | "src/**/*" 28 | ], 29 | "exclude": [ 30 | "node_modules/*", 31 | "dist/*", 32 | "examples/*", 33 | ], 34 | } 35 | -------------------------------------------------------------------------------- /rdb-web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "noFallthroughCasesInSwitch": true, 5 | "noUnusedParameters": true, 6 | "noImplicitReturns": true, 7 | "moduleResolution": "node", 8 | "esModuleInterop": true, 9 | "noUnusedLocals": true, 10 | "noImplicitAny": true, 11 | "target": "es2015", 12 | "module": "es2015", 13 | "strict": true, 14 | "jsx": "react", 15 | "allowJs": true, 16 | "noEmit": true, 17 | "baseUrl": ".", 18 | "paths": { 19 | "@pkgs/*": ["src/packages/*"], 20 | "@common/*": ["src/common/*"], 21 | "@cpts/*": ["src/components/*"], 22 | "@BComponent": ["src/components/BaseComponent"], 23 | "@interface": ["src/interface"], 24 | }, 25 | }, 26 | "include": [ 27 | "src/**/*" 28 | ], 29 | "exclude": [ 30 | "node_modules/*", 31 | "dist/*", 32 | "examples/*", 33 | ], 34 | } 35 | -------------------------------------------------------------------------------- /layout-web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "allowSyntheticDefaultImports": true, 4 | "noFallthroughCasesInSwitch": true, 5 | "noUnusedParameters": true, 6 | "noImplicitReturns": true, 7 | "moduleResolution": "node", 8 | "esModuleInterop": true, 9 | "noUnusedLocals": true, 10 | "noImplicitAny": true, 11 | "target": "es2015", 12 | "module": "es2015", 13 | "strict": true, 14 | "jsx": "react", 15 | "allowJs": true, 16 | "noEmit": true, 17 | "baseUrl": ".", 18 | "paths": { 19 | "@pkgs/*": ["src/packages/*"], 20 | "@common/*": ["src/common/*"], 21 | "@cpts/*": ["src/components/*"], 22 | "@BComponent": ["src/components/BaseComponent"], 23 | "@interface": ["src/interface"], 24 | }, 25 | }, 26 | "include": [ 27 | "src/**/*" 28 | ], 29 | "exclude": [ 30 | "node_modules/*", 31 | "dist/*", 32 | "examples/*", 33 | ], 34 | } 35 | -------------------------------------------------------------------------------- /nginx.conf: -------------------------------------------------------------------------------- 1 | server { 2 | listen 80 default_server; 3 | server_name ecmc; 4 | root /root/ecmc/pub; 5 | 6 | location =/ { 7 | rewrite / /mon; 8 | } 9 | 10 | location / { 11 | try_files $uri /layout/index.html; 12 | } 13 | 14 | location ~ .*(.htm|.html|manifest.json)$ { 15 | add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate"; 16 | } 17 | 18 | location /api/rdb { 19 | proxy_pass http://n9e.rdb; 20 | } 21 | 22 | location /api/ams { 23 | proxy_pass http://n9e.ams; 24 | } 25 | 26 | location /api/job { 27 | proxy_pass http://n9e.job; 28 | } 29 | 30 | location /api/mon { 31 | proxy_pass http://n9e.monapi; 32 | } 33 | 34 | location /api/index { 35 | proxy_pass http://n9e.index; 36 | } 37 | 38 | location /api/transfer { 39 | proxy_pass http://n9e.transfer; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 开发 2 | 3 | 1、先运行基座(layout-web) 4 | 2、运行指定子系统 5 | 6 | ## 构建 7 | 8 | 你可以分别构建基座和各个子系(请参考各子系统目录下的`README.md`文件),或者直接使用`make build`进行统一构建, 9 | 构建后的代码默认会存放到 `/pub` 文件夹里 10 | 11 | ## 部署 12 | 13 | 把 `/pub` 部署到环境机器上,修改 nginx server root 配置 14 | 分别构建时需要复制 `/layout-web/static` 到环境机器的 `pub` 下 15 | 16 | > static 里面存放的是一些前端的静态配置,没有特殊需求不需要做任何修改,后面会逐步完善文档。 17 | 18 | ## 常见问题 19 | 20 | 1、Error: Cannot find module '../src/package/xxxx' 21 | 子系统没有安装公共组件 git clone src/packages 22 | 23 | 2、根目录缺少 proxy.config.js 文件 24 | 需要手动在根目录创建代理配置文件 25 | 26 | ``` 27 | module.exports = { 28 | '/api/rdb': 'http://rdb.com', 29 | '/api/ams-ce': '', 30 | '/api/job': '', 31 | '/api/ticket': '', 32 | '/api/mon': '', 33 | '/api/transfer': '', 34 | '/api/index': '', 35 | } 36 | ``` 37 | 38 | ## 环境支持 39 | 40 | Chrome: last 2 versions 41 | Node: v12 42 | 43 | ## Build 44 | 45 | ``` 46 | make clone-pkg 47 | make build 48 | make clean 49 | ``` 50 | -------------------------------------------------------------------------------- /ams-web/src/HeadlessIndex.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import _ from 'lodash'; 4 | import request from '@pkgs/request'; 5 | import api from '@pkgs/api'; 6 | import '@pkgs/Layout/style.less'; 7 | import App from './app'; 8 | 9 | function HeadlessIndex() { 10 | useEffect(() => { 11 | request(api.permissionPoint).then((res) => { 12 | const permissionPoint: any = {}; 13 | _.forEach(res, (val, key) => { 14 | permissionPoint[key] = true; 15 | }); 16 | window.postMessage({ 17 | type: 'permissionPoint', 18 | value: permissionPoint, 19 | }, window.location.origin); 20 | }); 21 | }) 22 | return ( 23 | <> 24 |
headless
25 | 26 | 27 | ); 28 | } 29 | 30 | ReactDOM.render( 31 | , 32 | document.getElementById('react-content'), 33 | ); 34 | -------------------------------------------------------------------------------- /job-web/src/HeadlessIndex.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect } from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import _ from 'lodash'; 4 | import request from '@pkgs/request'; 5 | import api from '@pkgs/api'; 6 | import App from './app'; 7 | import '@pkgs/Layout/style.less'; 8 | 9 | function HeadlessIndex() { 10 | useEffect(() => { 11 | request(api.permissionPoint).then((res) => { 12 | const permissionPoint: any = {}; 13 | _.forEach(res, (val, key) => { 14 | permissionPoint[key] = true; 15 | }); 16 | window.postMessage({ 17 | type: 'permissionPoint', 18 | value: permissionPoint, 19 | }, window.location.origin); 20 | }); 21 | }) 22 | return ( 23 | <> 24 |
headless
25 | 26 | 27 | ); 28 | } 29 | 30 | ReactDOM.render( 31 | , 32 | document.getElementById('react-content'), 33 | ); 34 | -------------------------------------------------------------------------------- /mon-web/src/pages/Screen/ScreenDetail/GraphsContainer.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import _ from 'lodash'; 3 | import { Row } from 'antd'; 4 | import { SortableContainer } from 'react-sortable-hoc'; 5 | import RenderGraph from './RenderGraph'; 6 | 7 | function GraphsContainer(props) { 8 | return ( 9 | 10 | { 11 | _.map(props.data, (item, index) => ( 12 | 24 | )) 25 | } 26 | 27 | ); 28 | } 29 | 30 | export default SortableContainer(GraphsContainer); 31 | -------------------------------------------------------------------------------- /rdb-web/src/pages/PersonnelInfo/Profile/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Tabs } from 'antd'; 3 | import _ from 'lodash'; 4 | import { injectIntl, WrappedComponentProps } from 'react-intl'; 5 | import Profile from '@pkgs/Layout/Self/Profile'; 6 | import Password from '@pkgs/Layout/Self/Password'; 7 | import Token from '@pkgs/Layout/Self/Token'; 8 | 9 | const { TabPane } = Tabs; 10 | 11 | function Settings(props: WrappedComponentProps) { 12 | return ( 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | ); 25 | } 26 | 27 | export default injectIntl(Settings); 28 | -------------------------------------------------------------------------------- /mon-web/src/pages/History/Current.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import _ from 'lodash'; 3 | import { FormattedMessage } from 'react-intl'; 4 | import CreateIncludeNsTree from '@pkgs/Layout/CreateIncludeNsTree'; 5 | import { NsTreeContext } from '@pkgs/Layout/Provider'; 6 | import List from './List'; 7 | 8 | class index extends Component { 9 | static contextType = NsTreeContext; 10 | 11 | render() { 12 | const { selectedNode } = this.context.data; 13 | const nodepath = _.get(selectedNode, 'path'); 14 | const nid = _.get(selectedNode, 'id'); 15 | 16 | if (!nid) { 17 | return ( 18 |
19 | 20 |
21 | ); 22 | } 23 | 24 | return ( 25 | 31 | ); 32 | } 33 | } 34 | 35 | export default CreateIncludeNsTree(index, { visible: true }); 36 | -------------------------------------------------------------------------------- /job-web/src/pages/TaskTpl/Editor.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import AceEditor from 'react-ace'; 3 | import 'ace-builds/src-noconflict/mode-sh'; 4 | import 'ace-builds/src-noconflict/theme-monokai'; 5 | 6 | interface Props { 7 | value: string; 8 | onChange: (value: string) => void; 9 | } 10 | 11 | export default function Editor(props: Props) { 12 | return ( 13 | { 32 | props.onChange(newValue); 33 | }} 34 | /> 35 | ) 36 | } 37 | -------------------------------------------------------------------------------- /layout-web/src/common/api.tsx: -------------------------------------------------------------------------------- 1 | function getApi(path: string) { 2 | const prefix = '/api/uic'; 3 | return `${prefix}${path}`; 4 | } 5 | 6 | function getOrderApi(path: string) { 7 | const prefix = '/api/ticket'; 8 | return `${prefix}${path}`; 9 | } 10 | 11 | const api = { 12 | login: getApi('/auth/login'), 13 | logout: getApi('/auth/logout'), 14 | selftProfile: getApi('/self/profile'), 15 | selftPassword: getApi('/self/password'), 16 | selftToken: getApi('/self/token'), 17 | user: getApi('/user'), 18 | tenant: getApi('/tenant'), 19 | team: getApi('/team'), 20 | configs: getApi('/configs'), 21 | role: getApi('/role'), 22 | ops: getApi('/ops'), 23 | log: getApi('/log'), 24 | homeStatistics: getApi('/home/statistics'), 25 | project: getApi('/project'), 26 | projects: getApi('/projects'), 27 | queues: getOrderApi('/queues'), 28 | tickets: getOrderApi('/tickets'), 29 | template: getOrderApi('/templates'), 30 | upload: getOrderApi('/file/upload'), 31 | 32 | task: '/api/job-ce/task', 33 | }; 34 | 35 | export default api; 36 | -------------------------------------------------------------------------------- /layout-web/static/systemsConfig.json: -------------------------------------------------------------------------------- 1 | 2 | [{ 3 | "ident": "rdb", 4 | "development": { 5 | "publicPath": "http://localhost:8001/rdb/", 6 | "index": "http://localhost:8001/rdb/manifest.json" 7 | }, 8 | "production": { 9 | "publicPath": "/rdb/", 10 | "index": "/rdb/manifest.json" 11 | } 12 | }, { 13 | "ident": "ams", 14 | "development": { 15 | "publicPath": "http://localhost:8002/ams/", 16 | "index": "http://localhost:8002/ams/manifest.json" 17 | }, 18 | "production": { 19 | "publicPath": "/ams/", 20 | "index": "/ams/manifest.json" 21 | } 22 | }, { 23 | "ident": "job", 24 | "development": { 25 | "publicPath": "http://localhost:8003/job/", 26 | "index": "http://localhost:8003/job/manifest.json" 27 | }, 28 | "production": { 29 | "publicPath": "/job/", 30 | "index": "/job/manifest.json" 31 | } 32 | }, { 33 | "ident": "mon", 34 | "development": { 35 | "publicPath": "http://localhost:8004/mon/", 36 | "index": "http://localhost:8004/mon/manifest.json" 37 | }, 38 | "production": { 39 | "publicPath": "/mon/", 40 | "index": "/mon/manifest.json" 41 | } 42 | }] 43 | -------------------------------------------------------------------------------- /layout-web/static/amsMenusConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ams", 3 | "path": "ams", 4 | "icon": "#iconzichanguanlixitongicon", 5 | "children": [{ 6 | "name": "hosts", 7 | "path": "hosts", 8 | "icon": "#iconzhujishebeiicon", 9 | "children": [{ 10 | "name": "management", 11 | "path": "management", 12 | "permissionPoint": "ams_host_mgr_menu" 13 | }, { 14 | "name": "extend", 15 | "path": "extend", 16 | "permissionPoint": "ams_host_mgr_menu" 17 | }, { 18 | "name": "search", 19 | "path": "search" 20 | }] 21 | }, { 22 | "name": "shortcuts", 23 | "type": "group", 24 | "path": "", 25 | "icon": "", 26 | "children": [{ 27 | "name": "rdb", 28 | "path": "rdb", 29 | "isAbsolutePath": true, 30 | "icon": "#iconyonghuziyuanzhongxinicon" 31 | }, { 32 | "name": "job", 33 | "path": "job", 34 | "isAbsolutePath": true, 35 | "icon": "#iconrenwuzhongxinicon" 36 | }, { 37 | "name": "mon", 38 | "path": "mon", 39 | "isAbsolutePath": true, 40 | "icon": "#iconjiankonggaojingxitongicon" 41 | }] 42 | }] 43 | } 44 | -------------------------------------------------------------------------------- /layout-web/static/jobMenusConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "job", 3 | "path": "job", 4 | "icon": "#iconrenwuzhongxinicon", 5 | "children": [ 6 | { 7 | "name": "tasks-add", 8 | "path": "tasks-add", 9 | "icon": "#iconjishirenwuicon" 10 | }, { 11 | "name": "tasks", 12 | "path": "tasks", 13 | "icon": "#iconguanlishijiaoicon" 14 | }, { 15 | "name": "tpls", 16 | "path": "tpls", 17 | "icon": "#iconyupeizhimobanicon" 18 | }, { 19 | "name": "shortcuts", 20 | "type": "group", 21 | "path": "", 22 | "icon": "", 23 | "children": [{ 24 | "name": "rdb", 25 | "path": "rdb", 26 | "isAbsolutePath": true, 27 | "icon": "#iconyonghuziyuanzhongxinicon" 28 | }, { 29 | "name": "ams", 30 | "path": "ams", 31 | "isAbsolutePath": true, 32 | "icon": "#iconzichanguanlixitongicon" 33 | }, { 34 | "name": "mon", 35 | "path": "mon", 36 | "isAbsolutePath": true, 37 | "icon": "#iconjiankonggaojingxitongicon" 38 | }] 39 | } 40 | ] 41 | } 42 | -------------------------------------------------------------------------------- /mon-web/src/pages/Strategy/style.less: -------------------------------------------------------------------------------- 1 | @strategy-prefix-cls: ~"@{prefix-cls}-monitor-strategy"; 2 | 3 | .@{strategy-prefix-cls} { 4 | .mr10 { margin-right: 10px; } 5 | .mb10 { margin-bottom: 10px; } 6 | .textAlignRight { text-align: right; } 7 | .operation-btns { 8 | a { margin-right: 10px; } 9 | } 10 | } 11 | 12 | .@{strategy-prefix-cls}-form { 13 | .ant-input-number { 14 | margin-right: 8px; 15 | } 16 | } 17 | 18 | .@{strategy-prefix-cls}-form-field { 19 | border-bottom: 1px solid #efefef; 20 | margin-bottom: 20px; 21 | .ant-radio-button-wrapper-disabled.ant-radio-button-wrapper-checked { 22 | background-color: #999; 23 | box-shadow: none !important; 24 | } 25 | } 26 | 27 | .@{strategy-prefix-cls}-conditions-action { 28 | .ant-select-selection__rendered { 29 | margin-right: 0; 30 | } 31 | } 32 | 33 | .@{strategy-prefix-cls}-conditions-condition { 34 | background: #efefef; 35 | padding: 10px 20px; 36 | margin-bottom: 10px; 37 | position: relative; 38 | } 39 | 40 | .@{strategy-prefix-cls}-modelChart-report { 41 | background-color: #efefef; 42 | margin: 10px; 43 | padding: 10px; 44 | .mark { font-size: 36px; color: red; } 45 | .judge { font-size: 16px; color: red; } 46 | } 47 | -------------------------------------------------------------------------------- /mon-web/src/pages/History/All.jsx: -------------------------------------------------------------------------------- 1 | import React, { useContext, useState, useEffect } from 'react'; 2 | import _ from 'lodash'; 3 | import queryString from 'query-string'; 4 | import { FormattedMessage } from 'react-intl'; 5 | import CreateIncludeNsTree from '@pkgs/Layout/CreateIncludeNsTree'; 6 | import { NsTreeContext } from '@pkgs/Layout/Provider'; 7 | import List from './List'; 8 | 9 | function index() { 10 | const nstreeData = useContext(NsTreeContext); 11 | const { selectedNode } = nstreeData.data; 12 | const currentNodePath = _.get(selectedNode, 'path'); 13 | const [nodePath, setNodePath] = useState(currentNodePath); 14 | const nid = _.get(selectedNode, 'id'); 15 | // eslint-disable-next-line no-restricted-globals 16 | const query = queryString.parse(location.search); 17 | 18 | useEffect(() => { 19 | setNodePath(query.nodepath); 20 | }, []); 21 | 22 | useEffect(() => { 23 | if (currentNodePath) { 24 | setNodePath(currentNodePath); 25 | } 26 | }, [currentNodePath]); 27 | 28 | if (!nid) { 29 | return ( 30 |
31 | 32 |
33 | ); 34 | } 35 | 36 | return ; 42 | } 43 | 44 | export default CreateIncludeNsTree(index, { visible: true }); 45 | -------------------------------------------------------------------------------- /job-web/src/pages/TaskTpl/Add.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Button, message } from 'antd'; 3 | import _ from 'lodash'; 4 | import request from '@pkgs/request'; 5 | import { Link } from 'react-router-dom'; 6 | import api from '@common/api'; 7 | import useFormatMessage from '@pkgs/hooks/useFormatMessage'; 8 | import CreateIncludeNsTree from '@pkgs/Layout/CreateIncludeNsTree'; 9 | import TplForm from './TplForm'; 10 | 11 | const Add = (props: any) => { 12 | const intlFmtMsg = useFormatMessage(); 13 | const handleSubmit = (values: any) => { 14 | request(`${api.tasktpls}?nid=${values.nid}`, { 15 | method: 'POST', 16 | body: JSON.stringify(values), 17 | }).then(() => { 18 | message.success(intlFmtMsg({ id: 'msg.create.success' })); 19 | props.history.push({ 20 | pathname: `/tpls`, 21 | }); 22 | }); 23 | }; 24 | 25 | return ( 26 | 30 | 33 | 36 | 37 | } 38 | /> 39 | ) 40 | } 41 | 42 | export default CreateIncludeNsTree(Add, { visible: false }); 43 | -------------------------------------------------------------------------------- /layout-web/src/pages/BigScreen/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import * as singleSpa from 'single-spa'; 3 | import Parcel from 'single-spa-react/parcel'; 4 | import { fetchManifest, getPathBySuffix, createStylesheetLink } from '@pkgs/utils'; 5 | 6 | const bigScreenConf = { 7 | development: { 8 | publicPath: 'http://localhost:8001/monitor-dashboard/', 9 | index: 'http://localhost:8001/monitor-dashboard/index.html', 10 | }, 11 | production: { 12 | publicPath: '/monitor-dashboard/', 13 | index: '/monitor-dashboard/index.html', 14 | }, 15 | }; 16 | 17 | export default function index(props: any) { 18 | return ( 19 | { 21 | const sysUrl = bigScreenConf[process.env.NODE_ENV].index; 22 | const htmlData = await fetchManifest(sysUrl, bigScreenConf[process.env.NODE_ENV].publicPath); 23 | const lifecyclesFile = await System.import(htmlData); 24 | const jsPath = await getPathBySuffix(bigScreenConf, lifecyclesFile.default, '.js'); 25 | const cssPath = await getPathBySuffix(bigScreenConf, lifecyclesFile.default, '.css'); 26 | createStylesheetLink('ticket', cssPath); 27 | const reactLifecycles = await System.import(jsPath); 28 | return reactLifecycles; 29 | }} 30 | mountParcel={singleSpa.mountRootParcel} 31 | {...props} 32 | mode={props.mode} 33 | /> 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /layout-web/config/webpack.build.config.js: -------------------------------------------------------------------------------- 1 | const StatsPlugin = require('stats-webpack-plugin'); 2 | const webpackConfigResolveAlias = require('./webpackConfigResolveAlias'); 3 | const CoverHtmlWebpackPlugin = require('./CoverHtmlWebpackPlugin.js'); 4 | const pkgJson = require('../package.json'); 5 | 6 | module.exports = function(webpackConfig) { 7 | webpackConfig.output.library = 'layout'; 8 | webpackConfig.output.libraryTarget = 'amd'; 9 | webpackConfig.output.publicPath = '/layout/'; 10 | webpackConfig.resolve.alias = webpackConfigResolveAlias; 11 | webpackConfig.module.rules.unshift({ 12 | parser: { system: false }, 13 | }); 14 | webpackConfig.externals = [ 15 | /^react$/, 16 | /^react\/lib.*/, 17 | /^react-dom$/, 18 | /.*react-dom.*/, 19 | /^single-spa$/, 20 | /^antd$/, 21 | /^d3$/ 22 | ]; 23 | webpackConfig.plugins.push( 24 | new CoverHtmlWebpackPlugin(), 25 | ); 26 | 27 | const manifestName = `manifest.json`; 28 | webpackConfig.plugins.push( 29 | new StatsPlugin( 30 | manifestName, 31 | { 32 | chunkModules: false, 33 | source: true, 34 | chunks: false, 35 | modules: false, 36 | assets: true, 37 | children: false, 38 | outputPath: false, 39 | exclude: [/node_modules/] 40 | }, { 41 | v: pkgJson.version, 42 | n: pkgJson.name, 43 | } 44 | ) 45 | ); 46 | return webpackConfig; 47 | } 48 | -------------------------------------------------------------------------------- /mon-web/src/pages/CollectRule/InputWithUpload.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Input, Upload, Icon, Button } from 'antd'; 3 | import _ from 'lodash'; 4 | 5 | interface Props { 6 | value: string; 7 | onChange?: ((event: React.ChangeEvent) => void) | undefined; 8 | placeholder: string; 9 | } 10 | 11 | export default class InputWithUpload extends Component { 12 | render() { 13 | const uploadprops = { 14 | name: "file", 15 | beforeUpload: (file: any) => { 16 | if (window.FileReader) { 17 | var reader = new FileReader(); 18 | reader.onload = () => { 19 | if (_.isString(reader.result) && this.props.onChange) { 20 | this.props.onChange({ 21 | target: { 22 | value: reader.result 23 | } 24 | } as React.ChangeEvent); 25 | } 26 | }; 27 | reader.readAsText(file); 28 | } 29 | return false; 30 | }, 31 | showUploadList: false, 32 | }; 33 | return ( 34 | <> 35 | 40 | 41 | 44 | 45 | 46 | ); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /mon-web/src/pages/SRM/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import _ from 'lodash'; 3 | import * as singleSpa from 'single-spa'; 4 | import Parcel from 'single-spa-react/parcel'; 5 | import { fetchManifest, getPathBySuffix, createStylesheetLink } from '@pkgs/utils'; 6 | import CreateIncludeNsTree from '@pkgs/Layout/CreateIncludeNsTree'; 7 | 8 | const systemsConfItem = { 9 | ident: 'srm', 10 | development: { 11 | publicPath: 'http://localhost:9800/srm/', 12 | index: 'http://localhost:9800/srm/index.html', 13 | }, 14 | production: { 15 | publicPath: '/srm/', 16 | index: '/srm/index.html', 17 | }, 18 | }; 19 | 20 | function index(props: any) { 21 | return ( 22 | { 24 | const sysUrl = systemsConfItem[process.env.NODE_ENV].index; 25 | const htmlData = await fetchManifest(sysUrl, systemsConfItem[process.env.NODE_ENV].publicPath); 26 | const lifecyclesFile = await System.import(htmlData); 27 | const jsPath = await getPathBySuffix(systemsConfItem, lifecyclesFile.default, '.js'); 28 | const cssPath = await getPathBySuffix(systemsConfItem, lifecyclesFile.default, '.css'); 29 | createStylesheetLink('srm', cssPath); 30 | const reactLifecycles = await System.import(jsPath); 31 | return reactLifecycles; 32 | }} 33 | mountParcel={singleSpa.mountRootParcel} 34 | history={props.history} 35 | /> 36 | ); 37 | } 38 | 39 | export default CreateIncludeNsTree(index, { visible: false }) as any; 40 | -------------------------------------------------------------------------------- /mon-web/src/pages/AggrStra/BatchCloneToNidModal.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Modal, Form, TreeSelect } from 'antd'; 3 | import _ from 'lodash'; 4 | import ModalControl from '@pkgs/ModalControl'; 5 | import { renderTreeNodes } from '@pkgs/Layout/utils'; 6 | 7 | const FormItem = Form.Item; 8 | 9 | const BatchCloneToNidModal = (props: any) => { 10 | return ( 11 | { 15 | props.form.validateFields(async (err: any, values: any) => { 16 | if (!err) { 17 | props.onOk(values.nid); 18 | props.destroy(); 19 | } 20 | }); 21 | }} 22 | onCancel={() => { 23 | props.destroy(); 24 | }} 25 | > 26 |
27 | 30 | { 31 | props.form.getFieldDecorator('nid', { 32 | })( 33 | 41 | {renderTreeNodes(props.treeNodes, 'treeSelect')} 42 | , 43 | ) 44 | } 45 | 46 |
47 |
48 | ); 49 | } 50 | 51 | export default ModalControl(Form.create()(BatchCloneToNidModal)); 52 | -------------------------------------------------------------------------------- /mon-web/src/pages/Collect/BatchCloneToNidModal.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Modal, Form, TreeSelect } from 'antd'; 3 | import _ from 'lodash'; 4 | import ModalControl from '@pkgs/ModalControl'; 5 | import { renderTreeNodes } from '@pkgs/Layout/utils'; 6 | 7 | const FormItem = Form.Item; 8 | 9 | const BatchCloneToNidModal = (props: any) => { 10 | return ( 11 | { 15 | props.form.validateFields(async (err: any, values: any) => { 16 | if (!err) { 17 | props.onOk(values.nid); 18 | props.destroy(); 19 | } 20 | }); 21 | }} 22 | onCancel={() => { 23 | props.destroy(); 24 | }} 25 | > 26 |
27 | 30 | { 31 | props.form.getFieldDecorator('nid', { 32 | })( 33 | 41 | {renderTreeNodes(props.treeNodes, 'treeSelect')} 42 | , 43 | ) 44 | } 45 | 46 |
47 |
48 | ); 49 | } 50 | 51 | export default ModalControl(Form.create()(BatchCloneToNidModal)); 52 | -------------------------------------------------------------------------------- /mon-web/src/pages/Silence/utils.jsx: -------------------------------------------------------------------------------- 1 | import moment from 'moment'; 2 | import _ from 'lodash'; 3 | 4 | /** 5 | * trim 结构体中所有的字符串类型的值 6 | * @return {Object} [description] 7 | */ 8 | export function objectTrim(object) { 9 | if (_.isArray(object)) { 10 | _.each(object, (item) => { 11 | objectTrim(item); 12 | }); 13 | } else if (_.isPlainObject(object)) { 14 | _.each(object, (val, key) => { 15 | if (_.isString(val)) { 16 | object[key] = _.trim(val); 17 | } else if (_.isArray(val) && _.every(val, o => _.isString(o))) { 18 | object[key] = _.map(val, o => _.trim(o)); 19 | } else if (_.isArray(val) || _.isPlainObject(val)) { 20 | objectTrim(val); 21 | } 22 | }); 23 | } 24 | } 25 | 26 | /** 27 | * 待优化!!!! 28 | */ 29 | export function getProductNsPath(fullpath = '') { 30 | if (!fullpath || !fullpath.length) { 31 | return ''; 32 | } 33 | 34 | const nses = _.split(fullpath, '.'); 35 | const nssize = nses.length; 36 | if (nssize < 3) { 37 | return ''; 38 | } 39 | 40 | // eslint-disable-next-line prefer-template 41 | return nses[nssize - 3] + '.' + nses[nssize - 2] + '.' + nses[nssize - 1]; 42 | } 43 | 44 | export function normalizReqData(data) { 45 | const reqData = { 46 | btime: moment(data.btime).unix(), 47 | etime: moment(data.etime).unix(), 48 | cause: data.cause, 49 | metric: data.metric, 50 | tags: data.tags, 51 | endpoints: _.split(data.endpoints, '\n'), 52 | curNidPaths: data.curNidPaths, 53 | category: data.category, 54 | }; 55 | 56 | return reqData; 57 | } 58 | -------------------------------------------------------------------------------- /mon-web/src/pages/Strategy/Clone.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { message } from 'antd'; 3 | import _ from 'lodash'; 4 | import CreateIncludeNsTree from '@pkgs/Layout/CreateIncludeNsTree'; 5 | import SettingFields from './SettingFields'; 6 | import { getStrategy, addStrategy } from './services'; 7 | import { normalizeFormData } from './utils'; 8 | import './style.less'; 9 | 10 | class Add extends Component { 11 | constructor(props) { 12 | super(props); 13 | this.state = { 14 | values: undefined, 15 | }; 16 | } 17 | 18 | componentDidMount = () => { 19 | this.getStrategy(this.props); 20 | } 21 | 22 | getStrategy(props) { 23 | const strategyId = _.get(props, 'match.params.strategyId'); 24 | if (strategyId) { 25 | getStrategy(strategyId).then((values) => { 26 | this.setState({ 27 | values: normalizeFormData(values), 28 | }); 29 | }); 30 | } 31 | } 32 | 33 | handleSubmit = (values) => { 34 | const { history } = this.props; 35 | addStrategy(values).then(() => { 36 | message.success('添加报警策略成功!'); 37 | history.push({ 38 | pathname: '/strategy', 39 | }); 40 | }); 41 | } 42 | 43 | render() { 44 | const { values } = this.state; 45 | 46 | if (values) { 47 | return ( 48 |
49 | 53 |
54 | ); 55 | } 56 | return null; 57 | } 58 | } 59 | 60 | export default CreateIncludeNsTree(Add); 61 | -------------------------------------------------------------------------------- /layout-web/static/js/amd.js: -------------------------------------------------------------------------------- 1 | !function(){function t(t,e){return(e||"")+" (SystemJS https://git.io/JvFET#"+t+")"}!function(e){function r(){throw Error(t(5))}function n(){}function i(t,e){function n(t){f.push((function(e){u[t]=e.__useDefault?e.default:e}))}for(var i={},o={exports:i},u=[],f=[],s=0,l=0;t.length>l;l++){var a=t[l],c=f.length;"require"===a?(u[l]=r,s++):"module"===a?(u[l]=o,s++):"exports"===a?(u[l]=i,s++):n(l),s&&(t[c]=a)}s&&(t.length-=s);var g=e;return[t,function(t){return t({default:i,__useDefault:!0}),{setters:f,execute:function(){var e=g.apply(i,u);void 0!==e&&(o.exports=e),t(o.exports),t("default",o.exports)}}}]}function o(t,e){return t instanceof Array?[t,e]:"object"==typeof t?[[],function(){return t}]:"function"==typeof t?[g,t]:void 0}function u(t,e){s||(s=e,Promise.resolve().then((function(){s=null}))),f=e,System.registerRegistry[t]=System.getRegister(),f=null}var f,s,l,a=e.System.constructor.prototype,c=[[],function(){return{}}],g=["require","exports","module"],p=a.register;a.register=function(t,e,r){l="string"==typeof t?r:e,p.apply(this,arguments)};var y=a.instantiate;a.instantiate=function(){return v=null,y.apply(this,arguments)};var v,d,h=a.getRegister;a.getRegister=function(){if(f)return f;var t=s;s=null;var e=h.call(this);if(e&&e[1]===l)return e;var r=v;return v=null,t||(r?i(r,d):e||c)},e.define=function(e,r,f){var s;if("string"==typeof e){if(s=o(r,f),v){if(!System.registerRegistry)throw Error(t(6));return u(e,i(s[0],s[1])),v=[],void(d=n)}System.registerRegistry&&u(e,i([].concat(s[0]),s[1])),e=r,r=f}s=o(e,r),v=s[0],d=s[1]},e.define.amd={}}("undefined"!=typeof self?self:global)}();//# sourceMappingURL=amd.min.js.map -------------------------------------------------------------------------------- /rdb-web/src/common/api.tsx: -------------------------------------------------------------------------------- 1 | function getApi(path: string) { 2 | const prefix = '/api/rdb'; 3 | return `${prefix}${path}`; 4 | } 5 | 6 | function gethspApi(path: string) { 7 | const prefix = '/api/rdb'; 8 | return `${prefix}${path}`; 9 | } 10 | 11 | const api = { 12 | sso: gethspApi('/sso'), 13 | login: getApi('/auth/login'), 14 | logout: getApi('/auth/logout'), 15 | projs: getApi('/tree/projs'), 16 | selftProfile: getApi('/self/profile'), 17 | selftPassword: getApi('/self/password'), 18 | selftToken: getApi('/self/token'), 19 | user: getApi('/user'), 20 | users: getApi('/users'), 21 | tenant: getApi('/tenant'), 22 | team: getApi('/team'), 23 | teams: getApi('/teams'), 24 | configs: getApi('/configs'), 25 | role: getApi('/role'), 26 | roles: getApi('/roles'), 27 | ops: getApi('/ops'), 28 | log: getApi('/log'), 29 | homeStatistics: getApi('/home/statistics'), 30 | project: getApi('/project'), 31 | projects: getApi('/projects'), 32 | tree: gethspApi('/tree'), 33 | node: gethspApi('/node'), 34 | nodeCate: gethspApi('/node-cate'), 35 | nodeCates: gethspApi('/node-cates'), 36 | mgr: gethspApi('/mgr'), 37 | host: gethspApi('/host'), 38 | nethw: gethspApi('/nethw'), 39 | nethws: gethspApi('/nethws'), 40 | mibs: gethspApi('/mibs'), 41 | rdbResources: gethspApi('/resources'), 42 | resources: gethspApi('/resources'), 43 | white: getApi('/auth/white-list'), 44 | auth: getApi('/configs/auth'), 45 | quota: '/zstack/v1/cmp/dashboard/manager/quota', 46 | volume: '/zstack/v1/cmp/dashboard/manager/volume/capacity/used', 47 | }; 48 | 49 | export default api; 50 | -------------------------------------------------------------------------------- /mon-web/src/pages/BigScreen/AddModal.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Modal, Form, Input } from 'antd'; 3 | import _ from 'lodash'; 4 | import { FormattedMessage } from 'react-intl'; 5 | import ModalControl from '@pkgs/ModalControl'; 6 | 7 | const FormItem = Form.Item; 8 | 9 | class AddModal extends Component { 10 | static defaultProps = { 11 | title: '', 12 | visible: true, 13 | onOk: _.noop, 14 | onCancel: _.noop, 15 | destroy: _.noop, 16 | }; 17 | 18 | handleOk = () => { 19 | this.props.form.validateFields((err, values) => { 20 | if (!err) { 21 | this.props.onOk(values); 22 | this.props.destroy(); 23 | } 24 | }); 25 | } 26 | 27 | handleCancel = () => { 28 | this.props.destroy(); 29 | } 30 | 31 | render() { 32 | const { title, visible } = this.props; 33 | const { getFieldDecorator } = this.props.form; 34 | 35 | return ( 36 | 42 |
{ 43 | e.preventDefault(); 44 | this.handleOk(); 45 | }}> 46 | }> 47 | {getFieldDecorator('name', { 48 | rules: [{ required: true, message: '必填项!' }], 49 | })( 50 | , 51 | )} 52 | 53 |
54 |
55 | ); 56 | } 57 | } 58 | 59 | export default ModalControl(Form.create()(AddModal)); 60 | -------------------------------------------------------------------------------- /job-web/src/interface/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | // TODO: 菜单配置接口有点乱,看是否可以归类下,以及是否可以去掉一些非必要的属性 3 | export interface MenuConfItem { 4 | key?: string, 5 | name: string | React.ReactNode, 6 | path: string, 7 | icon?: string, 8 | children?: MenuConfItem[], 9 | visible?: boolean, 10 | rootVisible?: boolean, 11 | to?: string, 12 | divider?: boolean, 13 | target?: string, 14 | getQuery?: (query: any) => any, 15 | } 16 | 17 | export interface TreeNode { 18 | id: number, 19 | pid: number, 20 | name: string, 21 | path: string, 22 | type: number, 23 | leaf: number, 24 | children?: TreeNode[], 25 | cate?: string, 26 | icon_color: string, 27 | icon_char: string, 28 | } 29 | 30 | export interface ResponseDat { 31 | list: any[], 32 | total: number, 33 | } 34 | 35 | export interface Response { 36 | err : string, 37 | dat: any | ResponseDat, 38 | } 39 | 40 | export interface UserProfile { 41 | id: number, 42 | username: string, 43 | dispname: string, 44 | email: string, 45 | phone: string, 46 | im: string, 47 | isroot: boolean, 48 | } 49 | 50 | export interface Tenant { 51 | id: number, 52 | ident: string, 53 | name: string, 54 | note: string, 55 | } 56 | 57 | export interface Team { 58 | id: number, 59 | ident: string, 60 | name: string, 61 | note: string, 62 | mgmt: number, 63 | } 64 | 65 | export interface Role { 66 | id: number, 67 | name: string, 68 | note: string, 69 | cate: 'global' | 'local', 70 | operations: string[], 71 | } 72 | 73 | export interface NodeCate { 74 | id: number, 75 | name: string, 76 | icon_color: string, 77 | icon_char: string, 78 | note: string, 79 | cate: string, 80 | } 81 | -------------------------------------------------------------------------------- /mon-web/src/interface/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | // TODO: 菜单配置接口有点乱,看是否可以归类下,以及是否可以去掉一些非必要的属性 3 | export interface MenuConfItem { 4 | key?: string, 5 | name: string | React.ReactNode, 6 | path?: string, 7 | icon?: string, 8 | children?: MenuConfItem[], 9 | visible?: boolean, 10 | rootVisible?: boolean, 11 | to?: string, 12 | divider?: boolean, 13 | target?: string, 14 | getQuery?: (query: any) => any, 15 | } 16 | 17 | export interface TreeNode { 18 | id: number, 19 | pid: number, 20 | name: string, 21 | path: string, 22 | type: number, 23 | leaf: number, 24 | children?: TreeNode[], 25 | cate?: string, 26 | icon_color: string, 27 | icon_char: string, 28 | } 29 | 30 | export interface ResponseDat { 31 | list: any[], 32 | total: number, 33 | } 34 | 35 | export interface Response { 36 | err : string, 37 | dat: any | ResponseDat, 38 | } 39 | 40 | export interface UserProfile { 41 | id: number, 42 | username: string, 43 | dispname: string, 44 | email: string, 45 | phone: string, 46 | im: string, 47 | isroot: boolean, 48 | } 49 | 50 | export interface Tenant { 51 | id: number, 52 | ident: string, 53 | name: string, 54 | note: string, 55 | } 56 | 57 | export interface Team { 58 | id: number, 59 | ident: string, 60 | name: string, 61 | note: string, 62 | mgmt: number, 63 | } 64 | 65 | export interface Role { 66 | id: number, 67 | name: string, 68 | note: string, 69 | cate: 'global' | 'local', 70 | operations: string[], 71 | } 72 | 73 | export interface NodeCate { 74 | id: number, 75 | name: string, 76 | icon_color: string, 77 | icon_char: string, 78 | note: string, 79 | cate: string, 80 | } 81 | -------------------------------------------------------------------------------- /mon-web/src/pages/BigScreen/ModifyModal.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Modal, Form, Input } from 'antd'; 3 | import _ from 'lodash'; 4 | import { FormattedMessage } from 'react-intl'; 5 | import ModalControl from '@pkgs/ModalControl'; 6 | 7 | const FormItem = Form.Item; 8 | 9 | class ModifyModal extends Component { 10 | static defaultProps = { 11 | title: '', 12 | visible: true, 13 | onOk: _.noop, 14 | onCancel: _.noop, 15 | destroy: _.noop, 16 | }; 17 | 18 | handleOk = () => { 19 | this.props.form.validateFields((err, values) => { 20 | if (!err) { 21 | this.props.onOk(values); 22 | this.props.destroy(); 23 | } 24 | }); 25 | } 26 | 27 | handleCancel = () => { 28 | this.props.destroy(); 29 | } 30 | 31 | render() { 32 | const { title, visible } = this.props; 33 | const { getFieldDecorator } = this.props.form; 34 | 35 | return ( 36 | 42 |
{ 43 | e.preventDefault(); 44 | this.handleOk(); 45 | }}> 46 | }> 47 | {getFieldDecorator('name', { 48 | initialValue: this.props.name, 49 | rules: [{ required: true, message: '请填写大屏名称!' }], 50 | })( 51 | , 52 | )} 53 | 54 |
55 |
56 | ); 57 | } 58 | } 59 | 60 | export default ModalControl(Form.create()(ModifyModal)); 61 | -------------------------------------------------------------------------------- /ams-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ams", 3 | "systemName": "ams", 4 | "version": "3.3.0", 5 | "description": "", 6 | "engines": { 7 | "node": ">= 8.0.0", 8 | "npm": ">= 6.0.0" 9 | }, 10 | "scripts": { 11 | "start": "fetk run devServer", 12 | "build": "rm -rf ../pub/ams & fetk run build", 13 | "lint": "fetk run lint" 14 | }, 15 | "dependencies": { 16 | "@d3-charts/ts-graph": "^0.2.4", 17 | "@hot-loader/react-dom": "16.8.6", 18 | "@umijs/hooks": "^1.9.0", 19 | "antd": "^3.24.0", 20 | "bowser": "^2.11.0", 21 | "classnames": "^2.2.6", 22 | "d3": "^4.13.0", 23 | "d3-scale-chromatic": "^1.5.0", 24 | "jquery": "^3.5.1", 25 | "less": "^2.7.3", 26 | "lodash": "^4.17.11", 27 | "moment": "^2.24.0", 28 | "numeral": "^2.0.6", 29 | "query-string": "^5.0.1", 30 | "rc-notification": "^3.3.1", 31 | "react": "16.8.6", 32 | "react-addons-update": "^15.6.2", 33 | "react-copy-to-clipboard": "^5.0.1", 34 | "react-dom": "16.8.6", 35 | "react-intl": "^3.2.1", 36 | "react-router-dom": "4.x", 37 | "react-sortable-hoc": "^1.8.3", 38 | "single-spa": "^5.5.5", 39 | "single-spa-react": "^2.14.0", 40 | "xlsx": "^0.16.6" 41 | }, 42 | "devDependencies": { 43 | "@babel/core": "^7.5.5", 44 | "@types/classnames": "^2.2.9", 45 | "@types/lodash": "^4.14.138", 46 | "@types/pubsub-js": "^1.5.18", 47 | "@types/query-string": "^6.3.0", 48 | "@types/react-dom": "^16.9.0", 49 | "@types/react-router-dom": "^4.3.5", 50 | "@types/single-spa-react": "^2.12.0", 51 | "babel-plugin-import": "^1.12.0", 52 | "fetk": "0.5.1", 53 | "stats-webpack-plugin": "^0.7.0" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /mon-web/src/pages/Strategy/Modify.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { message } from 'antd'; 3 | import _ from 'lodash'; 4 | import CreateIncludeNsTree from '@pkgs/Layout/CreateIncludeNsTree'; 5 | import SettingFields from './SettingFields'; 6 | import { getStrategy, modifyStrategy } from './services'; 7 | import { normalizeFormData } from './utils'; 8 | import './style.less'; 9 | 10 | class Modify extends Component { 11 | constructor(props) { 12 | super(props); 13 | this.state = { 14 | values: undefined, 15 | }; 16 | } 17 | 18 | componentDidMount = () => { 19 | this.getStrategy(this.props); 20 | } 21 | 22 | getStrategy(props) { 23 | const strategyId = _.get(props, 'match.params.strategyId'); 24 | if (strategyId) { 25 | getStrategy(strategyId).then((values) => { 26 | this.setState({ 27 | values: normalizeFormData(values), 28 | }); 29 | }); 30 | } 31 | } 32 | 33 | handleSubmit = (newValues) => { 34 | const { history } = this.props; 35 | const { values } = this.state; 36 | modifyStrategy({ 37 | ...newValues, 38 | id: values.id, 39 | }).then(() => { 40 | message.success('修改报警策略成功!'); 41 | history.push({ 42 | pathname: '/strategy', 43 | }); 44 | }); 45 | } 46 | 47 | render() { 48 | const { values } = this.state; 49 | if (values) { 50 | return ( 51 |
52 | 56 |
57 | ); 58 | } 59 | return null; 60 | } 61 | } 62 | 63 | export default CreateIncludeNsTree(Modify); 64 | -------------------------------------------------------------------------------- /rdb-web/src/pages/TeamManagement/CreateTeam.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Modal, message } from 'antd'; 3 | import _ from 'lodash'; 4 | import { injectIntl, WrappedComponentProps } from 'react-intl'; 5 | import ModalControl, { ModalWrapProps } from '@pkgs/ModalControl'; 6 | import request from '@pkgs/request'; 7 | import api from '@common/api'; 8 | import TeamForm from './TeamForm'; 9 | 10 | class CreateTeam extends Component { 11 | static defaultProps = { 12 | visible: true, 13 | onOk: _.noop, 14 | onCancel: _.noop, 15 | destroy: _.noop, 16 | }; 17 | 18 | private formRef: any; // TODO: ref type 19 | 20 | handleOk = () => { 21 | this.formRef.validateFields((err: any, values: any) => { 22 | if (!err) { 23 | request(`${api.teams}`, { 24 | method: 'POST', 25 | body: JSON.stringify(values), 26 | }).then(() => { 27 | message.success(this.props.intl.formatMessage({ id: 'msg.create.success' })); 28 | this.props.onOk(); 29 | this.props.destroy(); 30 | }); 31 | } 32 | }); 33 | } 34 | 35 | handleCancel = () => { 36 | this.props.destroy(); 37 | } 38 | 39 | render() { 40 | const { visible } = this.props; 41 | 42 | return ( 43 | 49 | { this.formRef = ref; }} /> 50 | 51 | ); 52 | } 53 | } 54 | 55 | export default ModalControl(injectIntl(CreateTeam) as any); 56 | -------------------------------------------------------------------------------- /rdb-web/src/pages/PersonnelInfo/Teams/CreateTeam.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Modal, message } from 'antd'; 3 | import _ from 'lodash'; 4 | import { injectIntl, WrappedComponentProps } from 'react-intl'; 5 | import ModalControl, { ModalWrapProps } from '@pkgs/ModalControl'; 6 | import request from '@pkgs/request'; 7 | import api from '@common/api'; 8 | import TeamForm from './TeamForm'; 9 | 10 | class CreateTeam extends Component { 11 | static defaultProps = { 12 | visible: true, 13 | onOk: _.noop, 14 | onCancel: _.noop, 15 | destroy: _.noop, 16 | }; 17 | 18 | private formRef: any; // TODO: ref type 19 | 20 | handleOk = () => { 21 | this.formRef.validateFields((err: any, values: any) => { 22 | if (!err) { 23 | request(`${api.teams}`, { 24 | method: 'POST', 25 | body: JSON.stringify(values), 26 | }).then(() => { 27 | message.success(this.props.intl.formatMessage({ id: 'msg.create.success' })); 28 | this.props.onOk(); 29 | this.props.destroy(); 30 | }); 31 | } 32 | }); 33 | } 34 | 35 | handleCancel = () => { 36 | this.props.destroy(); 37 | } 38 | 39 | render() { 40 | const { visible } = this.props; 41 | 42 | return ( 43 | 49 | { this.formRef = ref; }} /> 50 | 51 | ); 52 | } 53 | } 54 | 55 | export default ModalControl(injectIntl(CreateTeam) as any); 56 | -------------------------------------------------------------------------------- /mon-web/src/pages/History/index.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Tabs } from 'antd'; 3 | import _ from 'lodash'; 4 | import { FormattedMessage } from 'react-intl'; 5 | import CreateIncludeNsTree from '@pkgs/Layout/CreateIncludeNsTree'; 6 | import { NsTreeContext } from '@pkgs/Layout/Provider'; 7 | import List from './List'; 8 | 9 | const { TabPane } = Tabs; 10 | 11 | class index extends Component { 12 | static contextType = NsTreeContext; 13 | 14 | state = { 15 | activeKey: 'alert', 16 | }; 17 | 18 | render() { 19 | const { selectedNode } = this.context.data; 20 | const nodepath = _.get(selectedNode, 'path'); 21 | const nid = _.get(selectedNode, 'id'); 22 | 23 | if (!nid) { 24 | return ( 25 |
26 | 27 |
28 | ); 29 | } 30 | 31 | return ( 32 | { 35 | this.setState({ activeKey }); 36 | }} 37 | > 38 | } key="alert"> 39 | 45 | 46 | } key="all"> 47 | 53 | 54 | 55 | ); 56 | } 57 | } 58 | 59 | export default CreateIncludeNsTree(index, { visible: true }); 60 | -------------------------------------------------------------------------------- /rdb-web/src/pages/TeamManagement/ModifyTeam.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Modal, message } from 'antd'; 3 | import _ from 'lodash'; 4 | import { injectIntl, WrappedComponentProps } from 'react-intl'; 5 | import ModalControl, { ModalWrapProps } from '@pkgs/ModalControl'; 6 | import request from '@pkgs/request'; 7 | import api from '@common/api'; 8 | import TeamForm from './TeamForm'; 9 | 10 | class ModifyTeam extends Component { 11 | static defaultProps = { 12 | visible: true, 13 | onOk: _.noop, 14 | onCancel: _.noop, 15 | destroy: _.noop, 16 | }; 17 | 18 | private formRef: any; 19 | 20 | handleOk = () => { 21 | this.formRef.validateFields((err: any, values: any) => { 22 | if (!err) { 23 | request(`${api.team}/${this.props.data.id}`, { 24 | method: 'PUT', 25 | body: JSON.stringify(values), 26 | }).then(() => { 27 | message.success(this.props.intl.formatMessage({ id: 'msg.modify.success' })); 28 | this.props.onOk(); 29 | this.props.destroy(); 30 | }); 31 | } 32 | }); 33 | } 34 | 35 | handleCancel = () => { 36 | this.props.destroy(); 37 | } 38 | 39 | render() { 40 | const { visible, data } = this.props; 41 | 42 | return ( 43 | 49 | { this.formRef = ref; }} /> 50 | 51 | ); 52 | } 53 | } 54 | 55 | export default ModalControl(injectIntl(ModifyTeam) as any); 56 | -------------------------------------------------------------------------------- /mon-web/src/common/api.tsx: -------------------------------------------------------------------------------- 1 | function getApi(sys: string, path: string) { 2 | const prefix = '/api/'; 3 | return `${prefix}${sys}${path}`; 4 | } 5 | 6 | const api = { 7 | tree: getApi('rdb', '/tree'), 8 | node: getApi('rdb', '/node'), 9 | hosts: getApi('ams-ce', '/hosts'), 10 | teams: getApi('rdb', '/teams'), 11 | users: getApi('rdb', '/users'), 12 | 13 | screenTpl: getApi('mon', '/tpl'), 14 | tmpchart: getApi('mon', '/tmpchart'), 15 | monNode: getApi('mon', '/node'), 16 | screen: getApi('mon', '/screen'), 17 | subclass: getApi('mon', '/subclass'), 18 | stra: getApi('mon', '/stra'), 19 | event: getApi('mon', '/event'), 20 | chart: getApi('mon', '/chart'), 21 | collect: getApi('mon', '/collect'), 22 | collectRules:getApi('mon', '/collect-rules/types'), 23 | createRules:getApi('mon', '/collect-rules'), 24 | regions:getApi('mon', '/regions'), 25 | getRulesList:getApi('mon', '/collect-rules/list'), 26 | handlerRules:getApi('mon', '/collect-rules'), 27 | networkCollect: getApi('mon-ee', '/collect'), 28 | maskconf: getApi('mon', '/maskconf'), 29 | snmp: getApi('mon-ee', '/snmp'), 30 | metricsPods: getApi('mon', '/index/metrics'), 31 | tagkvPods: getApi('mon', '/index/tagkv'), 32 | aggr: getApi('mon', '/aggr'), 33 | metrics: getApi('index', '/metrics'), 34 | tagkv: getApi('index', '/tagkv'), 35 | fullmatch: getApi('index', '/counter/fullmatch'), 36 | points: getApi('transfer', '/data/ui'), 37 | nginx: getApi('mon-ee', '/nginx-log-configs'), 38 | nginxSearch: getApi('mon-ee', '/nginx-log-config'), 39 | binlog: getApi('mon-ee', '/binlog-configs'), 40 | binlogSearch: getApi('mon-ee', '/binlog-config'), 41 | 42 | 43 | bigScreen: '/api/v1/dashboard', 44 | 45 | }; 46 | 47 | export default api; 48 | -------------------------------------------------------------------------------- /rdb-web/src/pages/PersonnelInfo/Teams/ModifyTeam.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Modal, message } from 'antd'; 3 | import _ from 'lodash'; 4 | import { injectIntl, WrappedComponentProps } from 'react-intl'; 5 | import ModalControl, { ModalWrapProps } from '@pkgs/ModalControl'; 6 | import request from '@pkgs/request'; 7 | import api from '@common/api'; 8 | import TeamForm from './TeamForm'; 9 | 10 | class ModifyTeam extends Component { 11 | static defaultProps = { 12 | visible: true, 13 | onOk: _.noop, 14 | onCancel: _.noop, 15 | destroy: _.noop, 16 | }; 17 | 18 | private formRef: any; 19 | 20 | handleOk = () => { 21 | this.formRef.validateFields((err: any, values: any) => { 22 | if (!err) { 23 | request(`${api.team}/${this.props.data.id}`, { 24 | method: 'PUT', 25 | body: JSON.stringify(values), 26 | }).then(() => { 27 | message.success(this.props.intl.formatMessage({ id: 'msg.modify.success' })); 28 | this.props.onOk(); 29 | this.props.destroy(); 30 | }); 31 | } 32 | }); 33 | } 34 | 35 | handleCancel = () => { 36 | this.props.destroy(); 37 | } 38 | 39 | render() { 40 | const { visible, data } = this.props; 41 | 42 | return ( 43 | 49 | { this.formRef = ref; }} /> 50 | 51 | ); 52 | } 53 | } 54 | 55 | export default ModalControl(injectIntl(ModifyTeam) as any); 56 | -------------------------------------------------------------------------------- /job-web/src/pages/TaskTpl/Modify.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import { Button, Spin, message } from 'antd'; 3 | import _ from 'lodash'; 4 | import request from '@pkgs/request'; 5 | import api from '@common/api'; 6 | import useFormatMessage from '@pkgs/hooks/useFormatMessage'; 7 | import CreateIncludeNsTree from '@pkgs/Layout/CreateIncludeNsTree'; 8 | import TplForm from './TplForm'; 9 | 10 | const Modify = (props: any) => { 11 | const id = _.get(props, 'match.params.id'); 12 | const intlFmtMsg = useFormatMessage(); 13 | const [loading, setLoading] = useState(false); 14 | const [data, setData] = useState({}); 15 | const handleSubmit = (values: any) => { 16 | request(`${api.tasktpl}/${id}`, { 17 | method: 'PUT', 18 | body: JSON.stringify(values), 19 | }).then(() => { 20 | message.success(intlFmtMsg({ id: 'msg.modify.success'})); 21 | props.history.push({ 22 | pathname: `/tpls`, 23 | }); 24 | }); 25 | }; 26 | 27 | useEffect(() => { 28 | if (id) { 29 | setLoading(true); 30 | request(`${api.tasktpl}/${id}`).then((data) => { 31 | setData({ 32 | ...data.tpl, 33 | hosts: data.hosts, 34 | grp: data.grp, 35 | }); 36 | }).finally(() => { 37 | setLoading(false); 38 | }); 39 | } 40 | }, [id]) 41 | 42 | return ( 43 | 44 | 49 | {intlFmtMsg({ id: 'form.submit' })} 50 | 51 | } 52 | /> 53 | 54 | ) 55 | } 56 | 57 | export default CreateIncludeNsTree(Modify, { visible: false }); 58 | -------------------------------------------------------------------------------- /mon-web/src/pages/Strategy/utils.jsx: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | 3 | export function normalizeFormData(values) { 4 | return { 5 | ...values, 6 | action: { 7 | converge: values.converge, 8 | recovery_notify: values.recovery_notify, 9 | notify_group: values.notify_group || undefined, 10 | notify_user: values.notify_user || undefined, 11 | notify_group_detail: values.notify_group_detail || [], 12 | notify_user_detail: values.notify_user_detail || [], 13 | callback: values.callback, 14 | }, 15 | period_time: { 16 | enable_stime: values.enable_stime, 17 | enable_etime: values.enable_etime, 18 | enable_days_of_week: values.enable_days_of_week, 19 | }, 20 | alert_upgrade: { 21 | enabled: !!values.need_upgrade, 22 | duration: _.get(values, 'alert_upgrade.duration', undefined), 23 | level: _.get(values, 'alert_upgrade.level', undefined), 24 | users: _.get(values, 'alert_upgrade.users', []), 25 | groups: _.get(values, 'alert_upgrade.groups', []), 26 | }, 27 | }; 28 | } 29 | 30 | export function processReqData(values) { 31 | const { action, period_time: periodTime } = values; 32 | const reqData = { 33 | ...values, 34 | ...action, 35 | ...periodTime, 36 | recovery_notify: values.recovery_notify ? 0 : 1, 37 | need_upgrade: _.get(values, 'alert_upgrade.enabled') ? 1 : 0, 38 | alert_upgrade: { 39 | duration: _.get(values, 'alert_upgrade.duration', undefined), 40 | level: _.get(values, 'alert_upgrade.level', undefined), 41 | users: _.get(values, 'alert_upgrade.users', []), 42 | groups: _.get(values, 'alert_upgrade.groups', []), 43 | }, 44 | }; 45 | delete reqData.action; 46 | delete reqData.period_time; 47 | return reqData; 48 | } 49 | -------------------------------------------------------------------------------- /layout-web/src/interface/index.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | // TODO: 菜单配置接口有点乱,看是否可以归类下,以及是否可以去掉一些非必要的属性 3 | export interface MenuConfItem { 4 | key?: string, 5 | name: string | React.ReactNode, 6 | path: string, 7 | icon?: string, 8 | children?: MenuConfItem[], 9 | visible?: boolean, 10 | rootVisible?: boolean, 11 | to?: string, 12 | divider?: boolean, 13 | target?: string, 14 | getQuery?: (query: any) => any, 15 | } 16 | 17 | export interface TreeNode { 18 | id: number, 19 | pid: number, 20 | name: string, 21 | path: string, 22 | type: number, 23 | leaf: number, 24 | children?: TreeNode[], 25 | icon_color?: string, 26 | icon_char?: string, 27 | cate?: string, 28 | note?: string, 29 | selectable?: boolean, 30 | } 31 | 32 | export interface ResponseDat { 33 | list: any[], 34 | total: number, 35 | } 36 | 37 | export interface Response { 38 | err : string, 39 | dat: any | ResponseDat, 40 | } 41 | 42 | export interface UserProfile { 43 | id: number, 44 | username: string, 45 | dispname: string, 46 | email: string, 47 | phone: string, 48 | im: string, 49 | isroot: boolean, 50 | } 51 | 52 | export interface Tenant { 53 | id: number, 54 | ident: string, 55 | name: string, 56 | note: string, 57 | } 58 | 59 | export interface Team { 60 | id: number, 61 | ident: string, 62 | name: string, 63 | note: string, 64 | mgmt: number, 65 | } 66 | 67 | export interface Role { 68 | id: number, 69 | name: string, 70 | note: string, 71 | cate: 'global' | 'local', 72 | operations: string[], 73 | } 74 | 75 | export interface Order { 76 | id: number, 77 | title: string, 78 | levels: number, 79 | cc: string, 80 | content: string, 81 | scheduleStartTime: string, 82 | status: string, 83 | creator: string, 84 | } 85 | -------------------------------------------------------------------------------- /rdb-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rdb", 3 | "systemName": "rdb", 4 | "version": "3.3.1", 5 | "description": "", 6 | "engines": { 7 | "node": ">= 8.0.0", 8 | "npm": ">= 6.0.0" 9 | }, 10 | "scripts": { 11 | "dev": "Mode=headless fetk run devServer", 12 | "start": "fetk run devServer", 13 | "build": "rm -rf ../pub/rdb & fetk run build", 14 | "lint": "fetk run lint" 15 | }, 16 | "dependencies": { 17 | "@hot-loader/react-dom": "16.8.6", 18 | "@umijs/hooks": "^1.9.0", 19 | "antd": "^3.24.0", 20 | "bowser": "^2.11.0", 21 | "classnames": "^2.2.6", 22 | "echarts": "^4.9.0", 23 | "echarts-for-react": "^2.0.16", 24 | "echarts-liquidfill": "^2.0.6", 25 | "jquery": "^3.5.1", 26 | "less": "^2.7.3", 27 | "lodash": "^4.17.11", 28 | "moment": "^2.24.0", 29 | "query-string": "^5.0.1", 30 | "rc-notification": "^3.3.1", 31 | "react": "16.8.6", 32 | "react-copy-to-clipboard": "^5.0.1", 33 | "react-dom": "16.8.6", 34 | "react-intl": "^3.2.1", 35 | "react-router-dom": "4.x", 36 | "react-sticky": "^6.0.3", 37 | "single-spa": "^5.8.0", 38 | "single-spa-react": "^2.14.0", 39 | "xlsx": "^0.16.6" 40 | }, 41 | "devDependencies": { 42 | "@babel/core": "^7.5.5", 43 | "@types/classnames": "^2.2.9", 44 | "@types/echarts": "^4.9.3", 45 | "@types/jquery": "^3.5.5", 46 | "@types/lodash": "^4.14.138", 47 | "@types/pubsub-js": "^1.5.18", 48 | "@types/query-string": "^6.3.0", 49 | "@types/react-dom": "^16.9.0", 50 | "@types/react-router-dom": "^4.3.5", 51 | "@types/single-spa-react": "^2.12.0", 52 | "antd-theme-webpack-plugin": "^1.3.1", 53 | "babel-plugin-import": "^1.12.0", 54 | "fetk": "0.5.1", 55 | "stats-webpack-plugin": "^0.7.0" 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /mon-web/src/pages/CollectRule/BaseList.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | Form, Input, Icon, Col, Row, 4 | } from 'antd'; 5 | import { useDynamicList } from '@umijs/hooks'; 6 | import { Field } from './Types'; 7 | 8 | interface IParams { 9 | nType: string; 10 | hasLabel?: boolean; 11 | data: Field; 12 | getFieldDecorator: any; 13 | initialValues: any; 14 | } 15 | 16 | export default (props: IParams) => { 17 | const { 18 | list, remove, getKey, push, 19 | } = useDynamicList( 20 | (props.nType === 'modify' ? props.initialValues : props.data.default) || [''], 21 | ); 22 | const { 23 | name, example, required, 24 | } = props.data; 25 | const Rows = (index: number, item: any) => ( 26 | 27 | 28 | 29 | {props.getFieldDecorator(`${name}[${getKey(index)}]`, { 30 | initialValue: item, 31 | rules: [ 32 | { 33 | required, 34 | message: '必填项!', 35 | }, 36 | ], 37 | })( 38 | , 39 | )} 40 | 41 | 42 | 43 | {list.length > 1 && ( 44 | { 48 | remove(index); 49 | }} 50 | /> 51 | )} 52 | { 56 | push(''); 57 | }} 58 | /> 59 | 60 | 61 | ); 62 | return
{list.map((ele: any, index: any) => Rows(index, ele))}
; 63 | }; 64 | -------------------------------------------------------------------------------- /layout-web/static/monMenusConfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mon", 3 | "path": "mon", 4 | "icon": "#iconjiankonggaojingxitongicon", 5 | "children": [{ 6 | "name": "dashboard", 7 | "path": "", 8 | "icon": "#iconjiankongkantuicon", 9 | "children": [{ 10 | "name": "realTime", 11 | "path": "dashboard" 12 | }, { 13 | "name": "screen", 14 | "path": "screen" 15 | }] 16 | }, { 17 | "name": "collect", 18 | "path": "collect", 19 | "icon": "#iconwangluojiankongicon", 20 | "children": [{ 21 | "name": "port", 22 | "path": "port" 23 | }, { 24 | "name": "proc", 25 | "path": "proc" 26 | }, { 27 | "name": "plugin", 28 | "path": "plugin" 29 | }, { 30 | "name": "log", 31 | "path": "log" 32 | }, { 33 | "name": "collect-rules", 34 | "path": "/collect-rules" 35 | }] 36 | }, { 37 | "name": "strategy", 38 | "path": "", 39 | "icon": "#iconcelvepeizhiicon", 40 | "children": [{ 41 | "name": "strategy", 42 | "path": "strategy" 43 | }, { 44 | "name": "silence", 45 | "path": "silence" 46 | }] 47 | }, { 48 | "name": "history", 49 | "path": "history", 50 | "icon": "#iconbaojingfuwu", 51 | "children": [{ 52 | "name": "cur", 53 | "path": "cur" 54 | }, { 55 | "name": "all", 56 | "path": "all" 57 | }] 58 | }, { 59 | "name": "shortcuts", 60 | "type": "group", 61 | "path": "", 62 | "icon": "", 63 | "children": [{ 64 | "name": "rdb", 65 | "path": "rdb", 66 | "isAbsolutePath": true, 67 | "icon": "#iconyonghuziyuanzhongxinicon" 68 | }, { 69 | "name": "ams", 70 | "path": "ams", 71 | "isAbsolutePath": true, 72 | "icon": "#iconzichanguanlixitongicon" 73 | }, { 74 | "name": "job", 75 | "path": "job", 76 | "isAbsolutePath": true, 77 | "icon": "#iconrenwuzhongxinicon" 78 | }] 79 | }] 80 | } 81 | -------------------------------------------------------------------------------- /rdb-web/src/pages/RoleManagement/CreateRole.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Modal, message } from 'antd'; 3 | import _ from 'lodash'; 4 | import { injectIntl, WrappedComponentProps } from 'react-intl'; 5 | import ModalControl, { ModalWrapProps } from '@pkgs/ModalControl'; 6 | import request from '@pkgs/request'; 7 | import api from '@common/api'; 8 | import RoleForm from './RoleForm'; 9 | 10 | interface Props { 11 | cate: 'global' | 'local'; 12 | onOk: (id: number) => void; 13 | } 14 | 15 | class CreateRole extends Component { 16 | static defaultProps = { 17 | visible: true, 18 | onOk: _.noop, 19 | onCancel: _.noop, 20 | destroy: _.noop, 21 | }; 22 | 23 | private formRef: any; // TODO: ref type 24 | 25 | handleOk = () => { 26 | this.formRef.validateFields((err: any, values: any) => { 27 | if (!err) { 28 | request(api.roles, { 29 | method: 'POST', 30 | body: JSON.stringify(values), 31 | }).then((res) => { 32 | message.success(this.props.intl.formatMessage({ id: 'msg.create.success' })); 33 | this.props.onOk(res.id); 34 | this.props.destroy(); 35 | }); 36 | } 37 | }); 38 | } 39 | 40 | handleCancel = () => { 41 | this.props.destroy(); 42 | } 43 | 44 | render() { 45 | const { visible, cate } = this.props; 46 | 47 | return ( 48 | 54 | { this.formRef = ref; }} /> 55 | 56 | ); 57 | } 58 | } 59 | 60 | export default ModalControl(injectIntl(CreateRole) as any); 61 | -------------------------------------------------------------------------------- /rdb-web/src/pages/ResourcesTree/Usages/request.tsx: -------------------------------------------------------------------------------- 1 | import api from "./api"; 2 | import { errNotify } from "@pkgs/request"; 3 | 4 | export const getUsages = async (tenant: number) => { 5 | const response = await fetch(api.zstack + "/" + tenant + "/usages"); 6 | const data = await response.json(); 7 | if (response.status < 200 || response.status >= 300) { 8 | console.log(data.err); 9 | } 10 | return data; 11 | }; 12 | 13 | const statusPoll = async (status: number, url: string) => { 14 | if (status === 202) { 15 | var reg = /(http:\/\/|https:\/\/)((\w|=|\?|\.|\/|&|-)+)(:[0-9]{1,4})?/g; 16 | const URL = url.replace(reg, ' '); 17 | const response = await fetch(URL); 18 | const data = await response.json(); 19 | if (response.status !== 200) { 20 | errNotify(data.error.details); 21 | throw new Error(data.error.details); 22 | } 23 | statusPoll(response.status, data.location); 24 | return data; 25 | } 26 | }; 27 | 28 | export const updateQuota = async ( 29 | tenant: string, 30 | name: string, 31 | value: number 32 | ) => { 33 | const response = await fetch(api.updateZstack + "/actions", { 34 | method: "PUT", 35 | body: JSON.stringify({ 36 | updateQuota: { 37 | identityUuid: tenant, 38 | name: name, 39 | value: value, 40 | }, 41 | }), 42 | }); 43 | const data = await response.json(); 44 | if (response.status < 200 || response.status >= 300) { 45 | if (response.status === 401) { 46 | const redirect = window.location.pathname; 47 | window.location.href = `/login?redirect=${redirect}`; 48 | } 49 | if (response.status === 403) { 50 | window.location.href = "/403"; 51 | } 52 | console.log(data.err); 53 | } 54 | 55 | statusPoll(response.status, data.location); 56 | 57 | return data; 58 | }; 59 | -------------------------------------------------------------------------------- /mon-web/src/pages/Screen/AddModal.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Modal, Form, Input } from 'antd'; 4 | import _ from 'lodash'; 5 | import { FormattedMessage } from 'react-intl'; 6 | import ModalControl from '@pkgs/ModalControl'; 7 | 8 | const FormItem = Form.Item; 9 | 10 | class AddModal extends Component { 11 | static propTypes = { 12 | title: PropTypes.string, 13 | visible: PropTypes.bool, 14 | onOk: PropTypes.func, 15 | onCancel: PropTypes.func, 16 | destroy: PropTypes.func, 17 | }; 18 | 19 | static defaultProps = { 20 | title: '', 21 | visible: true, 22 | onOk: _.noop, 23 | onCancel: _.noop, 24 | destroy: _.noop, 25 | }; 26 | 27 | handleOk = () => { 28 | this.props.form.validateFields((err, values) => { 29 | if (!err) { 30 | this.props.onOk(values); 31 | this.props.destroy(); 32 | } 33 | }); 34 | } 35 | 36 | handleCancel = () => { 37 | this.props.destroy(); 38 | } 39 | 40 | render() { 41 | const { title, visible } = this.props; 42 | const { getFieldDecorator } = this.props.form; 43 | 44 | return ( 45 | 51 |
{ 52 | e.preventDefault(); 53 | this.handleOk(); 54 | }}> 55 | }> 56 | {getFieldDecorator('name', { 57 | rules: [{ required: true, message: '必填项!' }], 58 | })( 59 | , 60 | )} 61 | 62 |
63 |
64 | ); 65 | } 66 | } 67 | 68 | export default ModalControl(Form.create()(AddModal)); 69 | -------------------------------------------------------------------------------- /mon-web/src/pages/Screen/ScreenDetail/AddModal.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Modal, Form, Input } from 'antd'; 4 | import _ from 'lodash'; 5 | import { FormattedMessage } from 'react-intl'; 6 | import ModalControl from '@pkgs/ModalControl'; 7 | 8 | const FormItem = Form.Item; 9 | 10 | class AddModal extends Component { 11 | static propTypes = { 12 | title: PropTypes.string, 13 | visible: PropTypes.bool, 14 | onOk: PropTypes.func, 15 | onCancel: PropTypes.func, 16 | destroy: PropTypes.func, 17 | }; 18 | 19 | static defaultProps = { 20 | title: '', 21 | visible: true, 22 | onOk: _.noop, 23 | onCancel: _.noop, 24 | destroy: _.noop, 25 | }; 26 | 27 | handleOk = () => { 28 | this.props.form.validateFields((err, values) => { 29 | if (!err) { 30 | this.props.onOk(values); 31 | this.props.destroy(); 32 | } 33 | }); 34 | } 35 | 36 | handleCancel = () => { 37 | this.props.destroy(); 38 | } 39 | 40 | render() { 41 | const { title, visible } = this.props; 42 | const { getFieldDecorator } = this.props.form; 43 | 44 | return ( 45 | 51 |
{ 52 | e.preventDefault(); 53 | this.handleOk(); 54 | }}> 55 | }> 56 | {getFieldDecorator('name', { 57 | rules: [{ required: true, message: '必填项!' }], 58 | })( 59 | , 60 | )} 61 | 62 |
63 |
64 | ); 65 | } 66 | } 67 | 68 | export default ModalControl(Form.create()(AddModal)); 69 | -------------------------------------------------------------------------------- /mon-web/src/pages/Silence/DetailModal.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Modal } from 'antd'; 4 | import _ from 'lodash'; 5 | import { FormattedMessage } from 'react-intl'; 6 | import ModalControl from '@pkgs/ModalControl'; 7 | import CustomForm from './CustomForm'; 8 | 9 | class DetailModal extends Component { 10 | static propTypes = { 11 | data: PropTypes.object.isRequired, 12 | visible: PropTypes.bool, 13 | onOk: PropTypes.func, 14 | onCancel: PropTypes.func, 15 | destroy: PropTypes.func, 16 | }; 17 | 18 | static defaultProps = { 19 | visible: true, 20 | onOk: _.noop, 21 | onCancel: _.noop, 22 | destroy: _.noop, 23 | }; 24 | 25 | constructor(props) { 26 | super(props); 27 | this.state = { 28 | submitLoading: false, 29 | }; 30 | } 31 | 32 | handleOk = () => { 33 | this.props.onOk(); 34 | this.props.destroy(); 35 | } 36 | 37 | handleCancel = () => { 38 | this.props.onCancel(); 39 | this.props.destroy(); 40 | } 41 | 42 | render() { 43 | const { 44 | visible, category, data, treeData, 45 | } = this.props; 46 | const { submitLoading } = this.state; 47 | 48 | return ( 49 |
50 | } 53 | visible={visible} 54 | onOk={this.handleOk} 55 | onCancel={this.handleCancel} 56 | confirmLoading={submitLoading} 57 | > 58 | { this.customForm = ref; }} 60 | category={category} 61 | treeData={treeData} 62 | initialValues={data} 63 | readOnly 64 | /> 65 | 66 |
67 | ); 68 | } 69 | } 70 | 71 | export default ModalControl(DetailModal); 72 | -------------------------------------------------------------------------------- /job-web/src/pages/TaskOutput/host.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Spin } from 'antd'; 3 | import _ from 'lodash'; 4 | import request from '@pkgs/request'; 5 | import api from '@common/api'; 6 | 7 | export default class index extends Component { 8 | constructor(props) { 9 | super(props); 10 | this.state = { 11 | loading: false, 12 | data: '', 13 | }; 14 | } 15 | 16 | componentDidMount = () => { 17 | this.fetchData(); 18 | document.title = '任务输出'; 19 | document.body.style.backgroundColor = '#fff'; 20 | document.body.style.color = '#000'; 21 | } 22 | 23 | componentWillMount = () => { 24 | document.body.style.backgroundColor = '#f0f2f5'; 25 | document.body.style.color = 'rgba(0, 0, 0, 0.65)'; 26 | } 27 | 28 | fetchData() { 29 | const taskId = _.get(this.props, 'match.params.taskId'); 30 | const host = _.get(this.props, 'match.params.host'); 31 | const outputType = _.get(this.props, 'match.params.outputType'); 32 | 33 | if (taskId !== undefined && host !== undefined) { 34 | this.setState({ loading: true }); 35 | request(`${api.task}/${taskId}/host/${host}/${outputType}`).then((data) => { 36 | this.setState({ data }); 37 | }).finally(() => { 38 | this.setState({ loading: false }); 39 | }); 40 | } 41 | } 42 | 43 | getOutput() { 44 | const host = _.get(this.props, 'match.params.host'); 45 | const { data } = this.state; 46 | let output = ''; 47 | output += `${host}\n`; 48 | output += `${data}\n\n`; 49 | return output; 50 | } 51 | 52 | render() { 53 | const { loading } = this.state; 54 | const output = this.getOutput(); 55 | return ( 56 | 57 |
58 |           {output}
59 |         
60 |
61 | ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /layout-web/src/pages/TaskOutput/host.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Spin } from 'antd'; 3 | import _ from 'lodash'; 4 | import request from '@pkgs/request'; 5 | import api from '@common/api'; 6 | 7 | export default class index extends Component { 8 | constructor(props) { 9 | super(props); 10 | this.state = { 11 | loading: false, 12 | data: '', 13 | }; 14 | } 15 | 16 | componentDidMount = () => { 17 | this.fetchData(); 18 | document.title = '任务输出'; 19 | document.body.style.backgroundColor = '#fff'; 20 | document.body.style.color = '#000'; 21 | } 22 | 23 | componentWillMount = () => { 24 | document.body.style.backgroundColor = '#f0f2f5'; 25 | document.body.style.color = 'rgba(0, 0, 0, 0.65)'; 26 | } 27 | 28 | getOutput() { 29 | const host = _.get(this.props, 'match.params.host'); 30 | const { data } = this.state; 31 | let output = ''; 32 | output += `${host}\n`; 33 | output += `${data}\n\n`; 34 | return output; 35 | } 36 | 37 | fetchData() { 38 | const taskId = _.get(this.props, 'match.params.taskId'); 39 | const host = _.get(this.props, 'match.params.host'); 40 | const outputType = _.get(this.props, 'match.params.outputType'); 41 | 42 | if (taskId !== undefined && host !== undefined) { 43 | this.setState({ loading: true }); 44 | request(`${api.task}/${taskId}/host/${host}/${outputType}`).then((data) => { 45 | this.setState({ data }); 46 | }).finally(() => { 47 | this.setState({ loading: false }); 48 | }); 49 | } 50 | } 51 | 52 | render() { 53 | const { loading } = this.state; 54 | const output = this.getOutput(); 55 | return ( 56 | 57 |
58 |           {output}
59 |         
60 |
61 | ); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /job-web/src/pages/TaskOutput/index.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Spin } from 'antd'; 3 | import _ from 'lodash'; 4 | import request from '@pkgs/request'; 5 | import api from '@common/api'; 6 | 7 | export default class index extends Component { 8 | constructor(props) { 9 | super(props); 10 | this.state = { 11 | loading: false, 12 | data: [], 13 | }; 14 | } 15 | 16 | componentDidMount = () => { 17 | this.fetchData(); 18 | document.title = '任务输出'; 19 | document.body.style.backgroundColor = '#fff'; 20 | document.body.style.color = '#000'; 21 | } 22 | 23 | componentWillMount = () => { 24 | document.body.style.backgroundColor = '#f0f2f5'; 25 | document.body.style.color = 'rgba(0, 0, 0, 0.65)'; 26 | } 27 | 28 | fetchData() { 29 | const taskId = _.get(this.props, 'match.params.taskId'); 30 | const outputType = _.get(this.props, 'match.params.outputType'); 31 | 32 | if (taskId !== undefined && outputType !== undefined) { 33 | this.setState({ loading: true }); 34 | request(`${api.task}/${taskId}/${outputType}`).then((data) => { 35 | this.setState({ data }); 36 | }).finally(() => { 37 | this.setState({ loading: false }); 38 | }); 39 | } 40 | } 41 | 42 | getOutput() { 43 | const outputType = _.get(this.props, 'match.params.outputType'); 44 | const { data } = this.state; 45 | let output = ''; 46 | _.each(data, (item) => { 47 | output += `${item.host}\n`; 48 | output += `${item[outputType]}\n\n`; 49 | }); 50 | return output; 51 | } 52 | 53 | render() { 54 | const { loading } = this.state; 55 | const output = this.getOutput(); 56 | return ( 57 | 58 |
59 |           {output}
60 |         
61 |
62 | ); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /layout-web/src/pages/TaskOutput/index.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Spin } from 'antd'; 3 | import _ from 'lodash'; 4 | import request from '@pkgs/request'; 5 | import api from '@common/api'; 6 | 7 | export default class index extends Component { 8 | constructor(props) { 9 | super(props); 10 | this.state = { 11 | loading: false, 12 | data: [], 13 | }; 14 | } 15 | 16 | componentDidMount = () => { 17 | this.fetchData(); 18 | document.title = '任务输出'; 19 | document.body.style.backgroundColor = '#fff'; 20 | document.body.style.color = '#000'; 21 | } 22 | 23 | componentWillMount = () => { 24 | document.body.style.backgroundColor = '#f0f2f5'; 25 | document.body.style.color = 'rgba(0, 0, 0, 0.65)'; 26 | } 27 | 28 | getOutput() { 29 | const outputType = _.get(this.props, 'match.params.outputType'); 30 | const { data } = this.state; 31 | let output = ''; 32 | _.each(data, (item) => { 33 | output += `${item.host}\n`; 34 | output += `${item[outputType]}\n\n`; 35 | }); 36 | return output; 37 | } 38 | 39 | fetchData() { 40 | const taskId = _.get(this.props, 'match.params.taskId'); 41 | const outputType = _.get(this.props, 'match.params.outputType'); 42 | 43 | if (taskId !== undefined && outputType !== undefined) { 44 | this.setState({ loading: true }); 45 | request(`${api.task}/${taskId}/${outputType}`).then((data) => { 46 | this.setState({ data }); 47 | }).finally(() => { 48 | this.setState({ loading: false }); 49 | }); 50 | } 51 | } 52 | 53 | render() { 54 | const { loading } = this.state; 55 | const output = this.getOutput(); 56 | return ( 57 | 58 |
59 |           {output}
60 |         
61 |
62 | ); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /rdb-web/src/pages/ResourceGeneral/LiquCharts.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import 'echarts-liquidfill'; 3 | import ReactCharts from 'echarts-for-react' 4 | import './style.less'; 5 | 6 | interface ILiquCharts { 7 | color: [string, string], 8 | data: number, 9 | } 10 | const UsageStat = (props: ILiquCharts) => { 11 | 12 | const liquidoption = { 13 | series: [{ 14 | type: 'liquidFill', 15 | data: [{ 16 | value: props.data, 17 | itemStyle: { 18 | normal: { 19 | color: eval("if(props.data<0.5){'#16c45b'}else if(props.data<0.7){'#3370ff'}else if(props.data<0.9){'#ffab0a'}else{'#fb4e57'}") 20 | } 21 | } 22 | }], 23 | amplitude: '3%', 24 | radius: '80%', 25 | outline: { 26 | borderDistance: 2, 27 | itemStyle: { 28 | borderWidth: 3, 29 | borderColor: '#F5F7FA', 30 | shadowBlur: 0, 31 | shadowColor: 'rgba(0, 0, 0, 0)' 32 | }, 33 | }, 34 | itemStyle: { 35 | opacity: 0.95, 36 | shadowBlur: 0, 37 | shadowColor: 'rgba(0, 0, 0, 0)' 38 | }, 39 | backgroundStyle: { 40 | color: '#F5F7FA', 41 | borderWidth: 2, 42 | borderColor: '#F5F7FA', 43 | shadowBlur: 0, 44 | shadowColor: 'rgba(0, 0, 0, 0)' 45 | }, 46 | label: { 47 | normal: { 48 | color: '#333', 49 | fontSize: 28, 50 | formatter: function (params: any) { 51 | if(!params.value && params.value !== 0) { 52 | return '--%' 53 | }else{ 54 | return `${(params.value * 100).toFixed(0)} %`; 55 | } 56 | }, 57 | } 58 | }, 59 | }] 60 | } 61 | 62 | return (<> 63 | 66 | ) 67 | } 68 | 69 | export default UsageStat; 70 | -------------------------------------------------------------------------------- /rdb-web/config/webpack.build.config.js: -------------------------------------------------------------------------------- 1 | const StatsPlugin = require('stats-webpack-plugin'); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 4 | const webpackConfigResolveAlias = require('./webpackConfigResolveAlias'); 5 | const pkgJson = require('../package.json'); 6 | 7 | module.exports = function getwebpackConfig(webpackConfig) { 8 | webpackConfig.resolve.alias = webpackConfigResolveAlias; 9 | webpackConfig.output.library = pkgJson.systemName; 10 | webpackConfig.output.libraryTarget = 'amd'; 11 | webpackConfig.module.rules.unshift({ 12 | parser: { system: false }, 13 | }); 14 | 15 | webpackConfig.output.filename = '[name]-[chunkhash].js'; 16 | webpackConfig.output.publicPath = `/${pkgJson.systemName}/`; 17 | webpackConfig.externals = [ 18 | /^react$/, 19 | /^react\/lib.*/, 20 | /^react-dom$/, 21 | /.*react-dom.*/, 22 | /^single-spa$/, 23 | /^antd$/, 24 | /^d3$/, 25 | ]; 26 | webpackConfig.plugins = webpackConfig.plugins.filter((plugin) => { 27 | if (plugin instanceof HtmlWebpackPlugin || 28 | plugin instanceof MiniCssExtractPlugin) { 29 | return false; 30 | } 31 | return true; 32 | }); 33 | webpackConfig.plugins.push( 34 | new MiniCssExtractPlugin({ 35 | filename: '[name]-[chunkhash].css', 36 | chunkFilename: '[name]-[chunkhash].css', 37 | }), 38 | ); 39 | 40 | const manifestName = `manifest.json`; 41 | webpackConfig.plugins.push( 42 | new StatsPlugin( 43 | manifestName, 44 | { 45 | chunkModules: false, 46 | source: true, 47 | chunks: false, 48 | modules: false, 49 | assets: true, 50 | children: false, 51 | outputPath: false, 52 | exclude: [/node_modules/] 53 | }, { 54 | v: pkgJson.version, 55 | n: pkgJson.name, 56 | } 57 | ) 58 | ) 59 | return webpackConfig; 60 | }; 61 | -------------------------------------------------------------------------------- /mon-web/src/pages/Screen/ModifyModal.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Modal, Form, Input } from 'antd'; 4 | import _ from 'lodash'; 5 | import { FormattedMessage } from 'react-intl'; 6 | import ModalControl from '@pkgs/ModalControl'; 7 | 8 | const FormItem = Form.Item; 9 | 10 | class ModifyModal extends Component { 11 | static propTypes = { 12 | name: PropTypes.string.isRequired, 13 | title: PropTypes.string, 14 | visible: PropTypes.bool, 15 | onOk: PropTypes.func, 16 | onCancel: PropTypes.func, 17 | destroy: PropTypes.func, 18 | }; 19 | 20 | static defaultProps = { 21 | title: '', 22 | visible: true, 23 | onOk: _.noop, 24 | onCancel: _.noop, 25 | destroy: _.noop, 26 | }; 27 | 28 | handleOk = () => { 29 | this.props.form.validateFields((err, values) => { 30 | if (!err) { 31 | this.props.onOk(values); 32 | this.props.destroy(); 33 | } 34 | }); 35 | } 36 | 37 | handleCancel = () => { 38 | this.props.destroy(); 39 | } 40 | 41 | render() { 42 | const { title, visible } = this.props; 43 | const { getFieldDecorator } = this.props.form; 44 | 45 | return ( 46 | 52 |
{ 53 | e.preventDefault(); 54 | this.handleOk(); 55 | }}> 56 | }> 57 | {getFieldDecorator('name', { 58 | initialValue: this.props.name, 59 | rules: [{ required: true, message: '请填写大盘名称!' }], 60 | })( 61 | , 62 | )} 63 | 64 |
65 |
66 | ); 67 | } 68 | } 69 | 70 | export default ModalControl(Form.create()(ModifyModal)); 71 | -------------------------------------------------------------------------------- /layout-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "layout", 3 | "systemName": "layout", 4 | "version": "3.3.1", 5 | "description": "", 6 | "engines": { 7 | "node": ">= 8.0.0", 8 | "npm": ">= 6.0.0" 9 | }, 10 | "scripts": { 11 | "dev": "npm run start", 12 | "start": "fetk run devServer", 13 | "build": "rm -rf ../pub/layout & fetk run build", 14 | "lint": "fetk run lint" 15 | }, 16 | "dependencies": { 17 | "@hot-loader/react-dom": "16.8.6", 18 | "@umijs/hooks": "^1.9.0", 19 | "antd": "^3.26.18", 20 | "array-move": "^3.0.1", 21 | "bowser": "^2.11.0", 22 | "classnames": "^2.2.6", 23 | "d3": "^6.2.0", 24 | "d3-scale-chromatic": "^2.0.0", 25 | "jquery": "^3.4.1", 26 | "less": "^2.7.3", 27 | "lodash": "^4.17.11", 28 | "moment": "^2.24.0", 29 | "query-string": "^5.0.1", 30 | "rc-notification": "^3.3.1", 31 | "react": "16.8.6", 32 | "react-dom": "16.8.6", 33 | "react-highlight-words": "^0.16.0", 34 | "react-hot-loader": "^4.8.7", 35 | "react-intl": "^3.2.1", 36 | "react-router-dom": "4.x", 37 | "react-sortable-hoc": "^1.11.0", 38 | "single-spa": "^5.5.5", 39 | "single-spa-react": "^2.14.0" 40 | }, 41 | "devDependencies": { 42 | "@babel/core": "^7.5.5", 43 | "@babel/plugin-transform-object-assign": "^7.12.1", 44 | "@types/classnames": "^2.2.9", 45 | "@types/d3": "^5.7.2", 46 | "@types/d3-scale-chromatic": "^1.5.0", 47 | "@types/lodash": "^4.14.138", 48 | "@types/node": "^12.12.25", 49 | "@types/pubsub-js": "^1.5.18", 50 | "@types/query-string": "^6.3.0", 51 | "@types/react": "^16.9.17", 52 | "@types/react-dom": "^16.9.0", 53 | "@types/react-highlight-words": "^0.16.0", 54 | "@types/react-router-dom": "^4.3.5", 55 | "@types/react-transition-group": "^4.2.2", 56 | "@typescript-eslint/parser": "^2.17.0", 57 | "babel-plugin-import": "^1.12.0", 58 | "fetk": "0.5.1", 59 | "stats-webpack-plugin": "^0.7.0" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /mon-web/src/pages/Screen/ScreenDetail/ModifyModal.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Modal, Form, Input } from 'antd'; 4 | import _ from 'lodash'; 5 | import { FormattedMessage } from 'react-intl'; 6 | import ModalControl from '@pkgs/ModalControl'; 7 | 8 | const FormItem = Form.Item; 9 | 10 | class ModifyModal extends Component { 11 | static propTypes = { 12 | name: PropTypes.string.isRequired, 13 | title: PropTypes.string, 14 | visible: PropTypes.bool, 15 | onOk: PropTypes.func, 16 | onCancel: PropTypes.func, 17 | destroy: PropTypes.func, 18 | }; 19 | 20 | static defaultProps = { 21 | title: '', 22 | visible: true, 23 | onOk: _.noop, 24 | onCancel: _.noop, 25 | destroy: _.noop, 26 | }; 27 | 28 | handleOk = () => { 29 | this.props.form.validateFields((err, values) => { 30 | if (!err) { 31 | this.props.onOk(values); 32 | this.props.destroy(); 33 | } 34 | }); 35 | } 36 | 37 | handleCancel = () => { 38 | this.props.destroy(); 39 | } 40 | 41 | render() { 42 | const { title, visible } = this.props; 43 | const { getFieldDecorator } = this.props.form; 44 | 45 | return ( 46 | 52 |
{ 53 | e.preventDefault(); 54 | this.handleOk(); 55 | }}> 56 | }> 57 | {getFieldDecorator('name', { 58 | initialValue: this.props.name, 59 | rules: [{ required: true, message: '必填项!' }], 60 | })( 61 | , 62 | )} 63 | 64 |
65 |
66 | ); 67 | } 68 | } 69 | 70 | export default ModalControl(Form.create()(ModifyModal)); 71 | -------------------------------------------------------------------------------- /ams-web/config/webpack.build.config.js: -------------------------------------------------------------------------------- 1 | const StatsPlugin = require('stats-webpack-plugin'); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 4 | const webpackConfigResolveAlias = require('./webpackConfigResolveAlias'); 5 | const pkgJson = require('../package.json'); 6 | 7 | module.exports = function getwebpackConfig(webpackConfig) { 8 | webpackConfig.resolve.alias = webpackConfigResolveAlias; 9 | webpackConfig.output.library = pkgJson.systemName; 10 | webpackConfig.output.libraryTarget = 'amd'; 11 | webpackConfig.module.rules.unshift({ 12 | parser: { system: false }, 13 | }); 14 | 15 | webpackConfig.output.filename = '[name]-[chunkhash].js'; 16 | webpackConfig.output.publicPath = `/${pkgJson.systemName}/`; 17 | webpackConfig.externals = [ 18 | /^react$/, 19 | /^react\/lib.*/, 20 | /^react-dom$/, 21 | /.*react-dom.*/, 22 | /^single-spa$/, 23 | /^antd$/, 24 | /^moment$/, 25 | /^d3$/ 26 | ]; 27 | webpackConfig.plugins = webpackConfig.plugins.filter((plugin) => { 28 | if (plugin instanceof HtmlWebpackPlugin || 29 | plugin instanceof MiniCssExtractPlugin) { 30 | return false; 31 | } 32 | return true; 33 | }); 34 | webpackConfig.plugins.push( 35 | new MiniCssExtractPlugin({ 36 | filename: '[name]-[chunkhash].css', 37 | chunkFilename: '[name]-[chunkhash].css', 38 | }), 39 | ); 40 | 41 | const manifestName = `manifest.json`; 42 | webpackConfig.plugins.push( 43 | new StatsPlugin( 44 | manifestName, 45 | { 46 | chunkModules: false, 47 | source: true, 48 | chunks: false, 49 | modules: false, 50 | assets: true, 51 | children: false, 52 | outputPath: false, 53 | exclude: [/node_modules/] 54 | }, { 55 | v: pkgJson.version, 56 | n: pkgJson.name, 57 | } 58 | ) 59 | ); 60 | return webpackConfig; 61 | }; 62 | -------------------------------------------------------------------------------- /job-web/config/webpack.build.config.js: -------------------------------------------------------------------------------- 1 | const StatsPlugin = require('stats-webpack-plugin'); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 4 | const webpackConfigResolveAlias = require('./webpackConfigResolveAlias'); 5 | const pkgJson = require('../package.json'); 6 | 7 | module.exports = function getwebpackConfig(webpackConfig) { 8 | webpackConfig.resolve.alias = webpackConfigResolveAlias; 9 | webpackConfig.output.library = pkgJson.systemName; 10 | webpackConfig.output.libraryTarget = 'amd'; 11 | webpackConfig.module.rules.unshift({ 12 | parser: { system: false }, 13 | }); 14 | 15 | webpackConfig.output.filename = '[name]-[chunkhash].js'; 16 | webpackConfig.output.publicPath = `/${pkgJson.systemName}/`; 17 | webpackConfig.externals = [ 18 | /^react$/, 19 | /^react\/lib.*/, 20 | /^react-dom$/, 21 | /.*react-dom.*/, 22 | /^single-spa$/, 23 | /^antd$/, 24 | /^moment$/, 25 | /^d3$/ 26 | ]; 27 | webpackConfig.plugins = webpackConfig.plugins.filter((plugin) => { 28 | if (plugin instanceof HtmlWebpackPlugin || 29 | plugin instanceof MiniCssExtractPlugin) { 30 | return false; 31 | } 32 | return true; 33 | }); 34 | webpackConfig.plugins.push( 35 | new MiniCssExtractPlugin({ 36 | filename: '[name]-[chunkhash].css', 37 | chunkFilename: '[name]-[chunkhash].css', 38 | }), 39 | ); 40 | 41 | const manifestName = `manifest.json`; 42 | webpackConfig.plugins.push( 43 | new StatsPlugin( 44 | manifestName, 45 | { 46 | chunkModules: false, 47 | source: true, 48 | chunks: false, 49 | modules: false, 50 | assets: true, 51 | children: false, 52 | outputPath: false, 53 | exclude: [/node_modules/] 54 | }, { 55 | v: pkgJson.version, 56 | n: pkgJson.name, 57 | } 58 | ) 59 | ); 60 | return webpackConfig; 61 | }; 62 | -------------------------------------------------------------------------------- /mon-web/config/webpack.build.config.js: -------------------------------------------------------------------------------- 1 | const StatsPlugin = require('stats-webpack-plugin'); 2 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 3 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 4 | const webpackConfigResolveAlias = require('./webpackConfigResolveAlias'); 5 | const pkgJson = require('../package.json'); 6 | 7 | 8 | module.exports = function getwebpackConfig(webpackConfig) { 9 | webpackConfig.resolve.alias = webpackConfigResolveAlias; 10 | webpackConfig.output.library = pkgJson.systemName; 11 | webpackConfig.output.libraryTarget = 'amd'; 12 | webpackConfig.module.rules.unshift({ 13 | parser: { system: false }, 14 | }); 15 | 16 | webpackConfig.output.filename = '[name]-[chunkhash].js'; 17 | webpackConfig.output.publicPath = `/${pkgJson.systemName}/`; 18 | webpackConfig.externals = [ 19 | /^react$/, 20 | /^react\/lib.*/, 21 | /^react-dom$/, 22 | /.*react-dom.*/, 23 | /^single-spa$/, 24 | /^antd$/, 25 | /^d3$/ 26 | ]; 27 | webpackConfig.plugins = webpackConfig.plugins.filter((plugin) => { 28 | if (plugin instanceof HtmlWebpackPlugin || 29 | plugin instanceof MiniCssExtractPlugin) { 30 | return false; 31 | } 32 | return true; 33 | }); 34 | webpackConfig.plugins.push( 35 | new MiniCssExtractPlugin({ 36 | filename: '[name]-[chunkhash].css', 37 | chunkFilename: '[name]-[chunkhash].css', 38 | }), 39 | ); 40 | 41 | const manifestName = `manifest.json`; 42 | webpackConfig.plugins.push( 43 | new StatsPlugin( 44 | manifestName, 45 | { 46 | chunkModules: false, 47 | source: true, 48 | chunks: false, 49 | modules: false, 50 | assets: true, 51 | children: false, 52 | outputPath: false, 53 | exclude: [/node_modules/] 54 | }, 55 | { 56 | v: pkgJson.version, 57 | n: pkgJson.name, 58 | } 59 | ) 60 | ); 61 | return webpackConfig; 62 | }; 63 | -------------------------------------------------------------------------------- /rdb-web/src/pages/TreenodeManagement/RecycleBin/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useRef } from 'react'; 2 | import { FormattedMessage } from 'react-intl'; 3 | import { Button } from 'antd'; 4 | import FetchTable from '@pkgs/FetchTable'; 5 | import api from '@pkgs/api'; 6 | import request from '@pkgs/request'; 7 | 8 | export default function index() { 9 | const table = useRef(); 10 | const [selectedRowKeys, setSelectedRowKeys] = useState([]); 11 | const onRecycle = () => { 12 | request(`${api.nodes}/trash/recycle`, { 13 | method: 'PUT', 14 | body: JSON.stringify({ 15 | ids: selectedRowKeys, 16 | }), 17 | }).then(() => { 18 | if (table && table.current) { 19 | table.current.reload(); 20 | } 21 | }); 22 | }; 23 | 24 | return ( 25 |
26 |
27 | 33 |
34 | , 43 | dataIndex: 'name', 44 | }, { 45 | title: , 46 | dataIndex: 'cate', 47 | }, { 48 | title: , 49 | dataIndex: 'path', 50 | }, { 51 | title: , 52 | dataIndex: 'note', 53 | }], 54 | rowSelection: { 55 | selectedRowKeys, 56 | onChange: (newSelectedRowKeys) => { 57 | setSelectedRowKeys(newSelectedRowKeys); 58 | } 59 | } 60 | }} 61 | /> 62 |
63 | ) 64 | } 65 | -------------------------------------------------------------------------------- /rdb-web/src/pages/RoleManagement/SiderList/style.less: -------------------------------------------------------------------------------- 1 | @import '~antd/es/style/themes/default.less'; 2 | @siderlist-cls: rdb-user-siderlist; 3 | 4 | .@{siderlist-cls} { 5 | .ant-pagination-simple .ant-pagination-prev, .ant-pagination-simple .ant-pagination-next { 6 | height: 32px; 7 | line-height: 32px; 8 | background-color: #fff; 9 | border: 1px solid #d9d9d9; 10 | border-radius: 4px; 11 | } 12 | .ant-pagination-simple .ant-pagination-simple-pager { 13 | height: 32px; 14 | } 15 | .ant-pagination-simple .ant-pagination-simple-pager input { 16 | padding: 0; 17 | } 18 | } 19 | 20 | .@{siderlist-cls}-header { 21 | overflow: hidden; 22 | .ant-btn-icon-only.ant-btn-sm { 23 | width: 18px; 24 | height: 18px; 25 | min-width: 18px; 26 | } 27 | .anticon-plus { 28 | vertical-align: baseline; 29 | } 30 | } 31 | 32 | .@{siderlist-cls}-header-title { 33 | float: left; 34 | } 35 | 36 | .@{siderlist-cls}-header-extra { 37 | float: right; 38 | } 39 | 40 | .@{siderlist-cls}-search { 41 | margin: 10px 0; 42 | } 43 | 44 | .@{siderlist-cls}-main { 45 | li { 46 | list-style: none; 47 | position: relative; 48 | height: 40px; 49 | line-height: 40px; 50 | } 51 | li > div { 52 | position: absolute; 53 | width: 100%; 54 | height: 40px; 55 | border: 1px solid #e8e8e8; 56 | border-top: 0 none; 57 | border-bottom: 0 none; 58 | text-align: center; 59 | cursor: pointer; 60 | white-space: nowrap; 61 | text-overflow: ellipsis; 62 | overflow: hidden; 63 | word-break: break-all; 64 | padding: 0 10px; 65 | } 66 | li.active > div:first-child { 67 | border: 2px solid @primary-color; 68 | } 69 | li.active > div:nth-child(2) { 70 | border-left: 0 none; 71 | border-right: 0 none; 72 | border-top: 1px solid #e8e8e8; 73 | border-bottom: 1px solid #e8e8e8; 74 | top: 0; 75 | background-color: #fff; 76 | position: absolute; 77 | width: 90%; 78 | left: 5%; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /rdb-web/src/pages/TeamManagement/SiderList/style.less: -------------------------------------------------------------------------------- 1 | @import '~antd/es/style/themes/default.less'; 2 | @siderlist-cls: rdb-user-siderlist; 3 | 4 | .@{siderlist-cls} { 5 | .ant-pagination-simple .ant-pagination-prev, .ant-pagination-simple .ant-pagination-next { 6 | height: 32px; 7 | line-height: 32px; 8 | background-color: #fff; 9 | border: 1px solid #d9d9d9; 10 | border-radius: 4px; 11 | } 12 | .ant-pagination-simple .ant-pagination-simple-pager { 13 | height: 32px; 14 | } 15 | .ant-pagination-simple .ant-pagination-simple-pager input { 16 | padding: 0; 17 | } 18 | } 19 | 20 | .@{siderlist-cls}-header { 21 | overflow: hidden; 22 | .ant-btn-icon-only.ant-btn-sm { 23 | width: 18px; 24 | height: 18px; 25 | min-width: 18px; 26 | } 27 | .anticon-plus { 28 | vertical-align: baseline; 29 | } 30 | } 31 | 32 | .@{siderlist-cls}-header-title { 33 | float: left; 34 | } 35 | 36 | .@{siderlist-cls}-header-extra { 37 | float: right; 38 | } 39 | 40 | .@{siderlist-cls}-search { 41 | margin: 10px 0; 42 | } 43 | 44 | .@{siderlist-cls}-main { 45 | li { 46 | list-style: none; 47 | position: relative; 48 | height: 40px; 49 | line-height: 40px; 50 | } 51 | li > div { 52 | position: absolute; 53 | width: 100%; 54 | height: 40px; 55 | border: 1px solid #e8e8e8; 56 | border-top: 0 none; 57 | border-bottom: 0 none; 58 | text-align: center; 59 | cursor: pointer; 60 | white-space: nowrap; 61 | text-overflow: ellipsis; 62 | overflow: hidden; 63 | word-break: break-all; 64 | padding: 0 10px; 65 | } 66 | li.active > div:first-child { 67 | border: 2px solid @primary-color; 68 | } 69 | li.active > div:nth-child(2) { 70 | border-left: 0 none; 71 | border-right: 0 none; 72 | border-top: 1px solid #e8e8e8; 73 | border-bottom: 1px solid #e8e8e8; 74 | top: 0; 75 | background-color: #fff; 76 | position: absolute; 77 | width: 90%; 78 | left: 5%; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /rdb-web/src/pages/PersonnelInfo/Teams/SiderList/style.less: -------------------------------------------------------------------------------- 1 | @import '~antd/es/style/themes/default.less'; 2 | @siderlist-cls: rdb-user-siderlist; 3 | 4 | .@{siderlist-cls} { 5 | .ant-pagination-simple .ant-pagination-prev, .ant-pagination-simple .ant-pagination-next { 6 | height: 32px; 7 | line-height: 32px; 8 | background-color: #fff; 9 | border: 1px solid #d9d9d9; 10 | border-radius: 4px; 11 | } 12 | .ant-pagination-simple .ant-pagination-simple-pager { 13 | height: 32px; 14 | } 15 | .ant-pagination-simple .ant-pagination-simple-pager input { 16 | padding: 0; 17 | } 18 | } 19 | 20 | .@{siderlist-cls}-header { 21 | overflow: hidden; 22 | .ant-btn-icon-only.ant-btn-sm { 23 | width: 18px; 24 | height: 18px; 25 | min-width: 18px; 26 | } 27 | .anticon-plus { 28 | vertical-align: baseline; 29 | } 30 | } 31 | 32 | .@{siderlist-cls}-header-title { 33 | float: left; 34 | } 35 | 36 | .@{siderlist-cls}-header-extra { 37 | float: right; 38 | } 39 | 40 | .@{siderlist-cls}-search { 41 | margin: 10px 0; 42 | } 43 | 44 | .@{siderlist-cls}-main { 45 | li { 46 | list-style: none; 47 | position: relative; 48 | height: 40px; 49 | line-height: 40px; 50 | } 51 | li > div { 52 | position: absolute; 53 | width: 100%; 54 | height: 40px; 55 | border: 1px solid #e8e8e8; 56 | border-top: 0 none; 57 | border-bottom: 0 none; 58 | text-align: center; 59 | cursor: pointer; 60 | white-space: nowrap; 61 | text-overflow: ellipsis; 62 | overflow: hidden; 63 | word-break: break-all; 64 | padding: 0 10px; 65 | } 66 | li.active > div:first-child { 67 | border: 2px solid @primary-color; 68 | } 69 | li.active > div:nth-child(2) { 70 | border-left: 0 none; 71 | border-right: 0 none; 72 | border-top: 1px solid #e8e8e8; 73 | border-bottom: 1px solid #e8e8e8; 74 | top: 0; 75 | background-color: #fff; 76 | position: absolute; 77 | width: 90%; 78 | left: 5%; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /rdb-web/src/pages/UserManagement/ModifyUser.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Modal, message } from 'antd'; 3 | import _ from 'lodash'; 4 | import { injectIntl, WrappedComponentProps } from 'react-intl'; 5 | import ModalControl, { ModalWrapProps } from '@pkgs/ModalControl'; 6 | import ProfileForm from '@pkgs/ProfileForm'; 7 | import { auth } from '@pkgs/Auth'; 8 | import request from '@pkgs/request'; 9 | import api from '@pkgs/api'; 10 | 11 | class ModifyUser extends Component { 12 | static defaultProps = { 13 | title: '', 14 | visible: true, 15 | onOk: _.noop, 16 | onCancel: _.noop, 17 | destroy: _.noop, 18 | }; 19 | 20 | private profileForm: any; 21 | 22 | handleOk = () => { 23 | this.profileForm.validateFields((err: any, values: any) => { 24 | if (!err) { 25 | request(`${api.user}/${this.props.data.id}/profile`, { 26 | method: 'PUT', 27 | body: JSON.stringify({ 28 | ...values, 29 | is_root: values.is_root ? 1: 0, 30 | }), 31 | }).then(() => { 32 | message.success(this.props.intl.formatMessage({ id: 'msg.modify.success' })); 33 | this.props.onOk(); 34 | this.props.destroy(); 35 | }); 36 | } 37 | }); 38 | } 39 | 40 | handleCancel = () => { 41 | this.props.destroy(); 42 | } 43 | 44 | render() { 45 | const { title, visible, data } = this.props; 46 | const { isroot } = auth.getSelftProfile(); 47 | 48 | return ( 49 | 55 | { this.profileForm = ref; }} 60 | /> 61 | 62 | ); 63 | } 64 | } 65 | 66 | export default ModalControl(injectIntl(ModifyUser) as any); 67 | -------------------------------------------------------------------------------- /mon-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mon-web", 3 | "systemName": "mon", 4 | "version": "3.4.2", 5 | "description": "", 6 | "engines": { 7 | "node": ">= 8.0.0", 8 | "npm": ">= 6.0.0" 9 | }, 10 | "scripts": { 11 | "dev": "Mode=headless fetk run devServer", 12 | "start": "fetk run devServer", 13 | "build": "rm -rf ../pub/mon & fetk run build", 14 | "lint": "fetk run lint" 15 | }, 16 | "dependencies": { 17 | "@d3-charts/ts-graph": "0.3.2", 18 | "@hot-loader/react-dom": "16.8.6", 19 | "@umijs/hooks": "^1.2.0", 20 | "ace-builds": "^1.4.11", 21 | "antd": "^3.26.0", 22 | "bowser": "^2.11.0", 23 | "classnames": "^2.2.6", 24 | "color": "^3.1.0", 25 | "d3": "^4.13.0", 26 | "d3-scale-chromatic": "^1.5.0", 27 | "immutability-helper": "^2.9.0", 28 | "jquery": "^3.4.1", 29 | "less": "^2.7.3", 30 | "lodash": "^4.17.11", 31 | "moment": "^2.24.0", 32 | "numeral": "^2.0.6", 33 | "prop-types": "15.x", 34 | "pubsub-js": "^1.7.0", 35 | "query-string": "5.0.1", 36 | "rc-calendar": "^9.6.2", 37 | "rc-notification": "^3.3.1", 38 | "react": "16.8.6", 39 | "react-ace": "^8.1.0", 40 | "react-addons-update": "^15.6.2", 41 | "react-copy-to-clipboard": "^5.0.1", 42 | "react-dnd": "^7.4.5", 43 | "react-dnd-html5-backend": "^7.4.4", 44 | "react-dom": "16.8.6", 45 | "react-hot-loader": "^4.8.7", 46 | "react-intl": "^3.2.1", 47 | "react-router-dom": "4.x", 48 | "react-sortable-hoc": "^1.8.3", 49 | "single-spa": "^5.5.5", 50 | "single-spa-react": "^2.14.0" 51 | }, 52 | "devDependencies": { 53 | "@babel/core": "^7.5.5", 54 | "@types/classnames": "^2.2.9", 55 | "@types/lodash": "^4.14.138", 56 | "@types/pubsub-js": "^1.5.18", 57 | "@types/query-string": "^6.3.0", 58 | "@types/react-dom": "^16.9.0", 59 | "@types/react-router-dom": "^4.3.5", 60 | "@types/single-spa-react": "^2.12.0", 61 | "babel-plugin-import": "^1.12.0", 62 | "fetk": "0.5.1", 63 | "stats-webpack-plugin": "^0.7.0" 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /job-web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "job-web", 3 | "systemName": "job", 4 | "version": "0.1.0", 5 | "description": "", 6 | "engines": { 7 | "node": ">= 8.0.0", 8 | "npm": ">= 6.0.0" 9 | }, 10 | "scripts": { 11 | "start": "fetk run devServer", 12 | "build": "rm -rf ../pub/job & fetk run build", 13 | "lint": "fetk run lint" 14 | }, 15 | "dependencies": { 16 | "@d3-charts/ts-graph": "^0.1.9", 17 | "@hot-loader/react-dom": "16.8.6", 18 | "@umijs/hooks": "^1.2.0", 19 | "ace-builds": "^1.4.11", 20 | "antd": "^3.19.2", 21 | "bowser": "^2.11.0", 22 | "classnames": "^2.2.6", 23 | "color": "^3.1.0", 24 | "d3": "^4.13.0", 25 | "highlight.js": "^9.16.1", 26 | "immutability-helper": "^2.9.0", 27 | "jquery": "^3.4.1", 28 | "less": "^2.7.3", 29 | "lodash": "^4.17.11", 30 | "moment": "^2.24.0", 31 | "numeral": "^2.0.6", 32 | "prop-types": "15.x", 33 | "pubsub-js": "^1.7.0", 34 | "query-string": "^5.0.1", 35 | "rc-calendar": "^9.6.2", 36 | "rc-notification": "^3.3.1", 37 | "react": "16.8.6", 38 | "react-ace": "^8.1.0", 39 | "react-addons-update": "^15.6.2", 40 | "react-copy-to-clipboard": "^5.0.1", 41 | "react-dnd": "^7.4.5", 42 | "react-dnd-html5-backend": "^7.4.4", 43 | "react-dom": "16.8.6", 44 | "react-highlight": "^0.12.0", 45 | "react-hot-loader": "^4.8.7", 46 | "react-intl": "^3.2.1", 47 | "react-router-dom": "4.x", 48 | "react-sortable-hoc": "^1.8.3", 49 | "react-syntax-highlighter": "^7.0.4", 50 | "single-spa": "^5.8.2", 51 | "single-spa-react": "^2.14.0" 52 | }, 53 | "devDependencies": { 54 | "@babel/core": "^7.5.5", 55 | "@types/classnames": "^2.2.9", 56 | "@types/lodash": "^4.14.138", 57 | "@types/pubsub-js": "^1.5.18", 58 | "@types/query-string": "^6.3.0", 59 | "@types/react-dom": "^16.9.0", 60 | "@types/react-router-dom": "^4.3.5", 61 | "@types/single-spa-react": "^2.12.0", 62 | "babel-plugin-import": "^1.12.0", 63 | "fetk": "0.5.1", 64 | "stats-webpack-plugin": "^0.7.0" 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /mon-web/config/webpack.dev.config.js: -------------------------------------------------------------------------------- 1 | const process = require('process'); 2 | const StatsPlugin = require('stats-webpack-plugin'); 3 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 5 | const webpackConfigResolveAlias = require('./webpackConfigResolveAlias'); 6 | const fetkJson = require('../fetk.config'); 7 | const pkgJson = require('../package.json'); 8 | 9 | module.exports = function getwebpackConfig(webpackConfig) { 10 | webpackConfig.resolve.alias = webpackConfigResolveAlias; 11 | 12 | if (!process.env.Mode) { 13 | webpackConfig.output.library = pkgJson.systemName; 14 | webpackConfig.output.libraryTarget = 'amd'; 15 | webpackConfig.module.rules.unshift({ 16 | parser: { system: false }, 17 | }); 18 | webpackConfig.output.publicPath = `http://0.0.0.0:${fetkJson.port}/${pkgJson.systemName}/`; 19 | webpackConfig.output.filename = '[name]-[chunkhash].js'; 20 | webpackConfig.externals = [ 21 | /^react$/, 22 | /^react\/lib.*/, 23 | /^react-dom$/, 24 | /.*react-dom.*/, 25 | /^single-spa$/, 26 | /^antd$/, 27 | /^d3$/ 28 | ]; 29 | webpackConfig.plugins = webpackConfig.plugins.filter((plugin) => { 30 | if (plugin instanceof HtmlWebpackPlugin || 31 | plugin instanceof MiniCssExtractPlugin) { 32 | return false; 33 | } 34 | return true; 35 | }); 36 | webpackConfig.plugins.push( 37 | new MiniCssExtractPlugin({ 38 | filename: '[name]-[chunkhash].css', 39 | chunkFilename: '[name]-[chunkhash].css', 40 | }), 41 | ); 42 | 43 | const manifestName = `manifest.json`; 44 | webpackConfig.plugins.push( 45 | new StatsPlugin( 46 | manifestName, 47 | { 48 | chunkModules: false, 49 | source: true, 50 | chunks: false, 51 | modules: false, 52 | assets: true, 53 | children: false, 54 | exclude: [/node_modules/] 55 | } 56 | ) 57 | ); 58 | } 59 | return webpackConfig; 60 | }; 61 | -------------------------------------------------------------------------------- /rdb-web/config/webpack.dev.config.js: -------------------------------------------------------------------------------- 1 | const process = require('process'); 2 | const StatsPlugin = require('stats-webpack-plugin'); 3 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 5 | const webpackConfigResolveAlias = require('./webpackConfigResolveAlias'); 6 | const fetkJson = require('../fetk.config'); 7 | const pkgJson = require('../package.json'); 8 | 9 | 10 | module.exports = function getwebpackConfig(webpackConfig) { 11 | webpackConfig.resolve.alias = webpackConfigResolveAlias; 12 | 13 | if (!process.env.Mode) { 14 | webpackConfig.output.library = pkgJson.systemName; 15 | webpackConfig.output.libraryTarget = 'amd'; 16 | webpackConfig.module.rules.unshift({ 17 | parser: { system: false }, 18 | }); 19 | webpackConfig.output.publicPath = `http://0.0.0.0:${fetkJson.port}/${pkgJson.systemName}/`; 20 | webpackConfig.output.filename = '[name]-[chunkhash].js'; 21 | webpackConfig.externals = [ 22 | /^react$/, 23 | /^react\/lib.*/, 24 | /^react-dom$/, 25 | /.*react-dom.*/, 26 | /^single-spa$/, 27 | /^antd$/, 28 | /^d3$/, 29 | ]; 30 | webpackConfig.plugins = webpackConfig.plugins.filter((plugin) => { 31 | if (plugin instanceof HtmlWebpackPlugin || 32 | plugin instanceof MiniCssExtractPlugin) { 33 | return false; 34 | } 35 | return true; 36 | }); 37 | webpackConfig.plugins.push( 38 | new MiniCssExtractPlugin({ 39 | filename: '[name]-[chunkhash].css', 40 | chunkFilename: '[name]-[chunkhash].css', 41 | }), 42 | ); 43 | const manifestName = `manifest.json`; 44 | 45 | webpackConfig.plugins.push( 46 | new StatsPlugin( 47 | manifestName, 48 | { 49 | chunkModules: false, 50 | source: true, 51 | chunks: false, 52 | modules: false, 53 | assets: true, 54 | children: false, 55 | exclude: [/node_modules/] 56 | } 57 | ) 58 | ) 59 | } 60 | return webpackConfig; 61 | }; 62 | -------------------------------------------------------------------------------- /ams-web/config/webpack.dev.config.js: -------------------------------------------------------------------------------- 1 | const process = require('process'); 2 | const StatsPlugin = require('stats-webpack-plugin'); 3 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 5 | const webpackConfigResolveAlias = require('./webpackConfigResolveAlias'); 6 | const fetkJson = require('../fetk.config'); 7 | const pkgJson = require('../package.json'); 8 | 9 | 10 | module.exports = function getwebpackConfig(webpackConfig) { 11 | webpackConfig.resolve.alias = webpackConfigResolveAlias; 12 | 13 | if (!process.env.Mode) { 14 | webpackConfig.output.library = pkgJson.systemName; 15 | webpackConfig.output.libraryTarget = 'amd'; 16 | webpackConfig.module.rules.unshift({ 17 | parser: { system: false }, 18 | }); 19 | webpackConfig.output.publicPath = `http://0.0.0.0:${fetkJson.port}/${pkgJson.systemName}/`; 20 | webpackConfig.output.filename = '[name]-[chunkhash].js'; 21 | webpackConfig.externals = [ 22 | /^react$/, 23 | /^react\/lib.*/, 24 | /^react-dom$/, 25 | /.*react-dom.*/, 26 | /^single-spa$/, 27 | /^antd$/, 28 | /^moment$/, 29 | /^d3$/ 30 | ]; 31 | webpackConfig.plugins = webpackConfig.plugins.filter((plugin) => { 32 | if (plugin instanceof HtmlWebpackPlugin || 33 | plugin instanceof MiniCssExtractPlugin) { 34 | return false; 35 | } 36 | return true; 37 | }); 38 | webpackConfig.plugins.push( 39 | new MiniCssExtractPlugin({ 40 | filename: '[name]-[chunkhash].css', 41 | chunkFilename: '[name]-[chunkhash].css', 42 | }), 43 | ); 44 | 45 | const manifestName = `manifest.json`; 46 | webpackConfig.plugins.push( 47 | new StatsPlugin( 48 | manifestName, 49 | { 50 | chunkModules: false, 51 | source: true, 52 | chunks: false, 53 | modules: false, 54 | assets: true, 55 | children: false, 56 | exclude: [/node_modules/] 57 | } 58 | ) 59 | ); 60 | } 61 | return webpackConfig; 62 | }; 63 | -------------------------------------------------------------------------------- /ams-web/src/pages/Hosts/Management/Dashboard/utils.tsx: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | 3 | export function filterMetrics(filterType, filterValue, alls) { 4 | if (!(filterType && filterValue)) { 5 | return []; 6 | } 7 | 8 | const filters = _.split(filterValue, ','); 9 | switch (filterType) { 10 | case 'prefix': 11 | return _.filter(alls, (m) => { 12 | for (let i = 0; i < filters.length; i++) { 13 | if (m && m.indexOf(filters[i]) === 0) { 14 | return true; 15 | } 16 | } 17 | return false; 18 | }); 19 | case 'substring': 20 | return _.filter(alls, (m) => { 21 | for (let i = 0; i < filters.length; i++) { 22 | if (m && m.indexOf(filters[i]) !== -1) { 23 | return true; 24 | } 25 | } 26 | return false; 27 | }); 28 | case 'suffix': 29 | return _.filter(alls, (m) => { 30 | for (let i = 0; i < filters.length; i++) { 31 | if (m && m.indexOf(filters[i], m.length - filters[i].length) !== -1) { 32 | return true; 33 | } 34 | } 35 | return false; 36 | }); 37 | default: 38 | return []; 39 | } 40 | } 41 | 42 | export function matchMetrics(matches, alls) { 43 | if (!matches || matches.length === 0) { 44 | return []; 45 | } 46 | if (!alls || alls.length === 0) { 47 | return []; 48 | } 49 | 50 | return _.filter(matches, o => _.indexOf(alls, o) > -1); 51 | } 52 | 53 | export function getClusterNs(allNsData, query) { 54 | const { ns, category } = query; 55 | if (category === 'service') { 56 | return _.filter(allNsData, (item) => { 57 | const nsSplit = item.split('.'); 58 | nsSplit.splice(0, 2); 59 | return nsSplit.join('.') === ns; 60 | }); 61 | } 62 | return [`collect.${ns}`]; 63 | } 64 | 65 | export function normalizeGraphData(data) { 66 | const cloneData = _.cloneDeep(data); 67 | _.each(cloneData.metrics, (item) => { 68 | delete item.key; 69 | delete item.metrics; 70 | delete item.tagkv; 71 | delete item.counterList; 72 | }); 73 | return cloneData; 74 | } 75 | -------------------------------------------------------------------------------- /job-web/src/components/FieldCopy/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { 3 | Modal, Input, Icon, message, 4 | } from 'antd'; 5 | import _ from 'lodash'; 6 | import { WrappedComponentProps, injectIntl } from 'react-intl'; 7 | import clipboard from '@pkgs/clipboard'; 8 | 9 | interface Props { 10 | dataIndex: string, 11 | data: any[], 12 | hasSelected?: boolean, 13 | } 14 | type CopyType = 'all' | 'selected' | 'currentPage'; 15 | type HandleCopyBtnClick = (dataIndex: string, copyType: CopyType) => void; 16 | 17 | class HostCopyTitle extends Component { 18 | static defaultProps = { 19 | data: [], 20 | selected: [], 21 | hasSelected: true, 22 | }; 23 | 24 | handleCopyBtnClick: HandleCopyBtnClick = async (dataIndex, copyType) => { 25 | const { data } = this.props; 26 | let tobeCopy = []; 27 | 28 | if (copyType === 'all') { 29 | tobeCopy = _.map(data, (item) => item[dataIndex]); 30 | } 31 | 32 | if (_.isEmpty(tobeCopy)) { 33 | message.warning(this.props.intl.formatMessage({ id: 'host.copy.empty' })); 34 | return; 35 | } 36 | 37 | const tobeCopyStr = _.join(tobeCopy, '\n'); 38 | const copySucceeded = clipboard(tobeCopyStr); 39 | 40 | if (copySucceeded) { 41 | if (this.props.intl.locale === 'zh') { 42 | message.success(`复制成功${tobeCopy.length}条记录`); 43 | } else if (this.props.intl.locale === 'en') { 44 | message.success(`Successful copy ${tobeCopy.length} items`); 45 | } 46 | } else { 47 | Modal.warning({ 48 | title: this.props.intl.formatMessage({ id: 'host.copy.error' }), 49 | content: , 50 | }); 51 | } 52 | } 53 | 54 | render() { 55 | const { dataIndex } = this.props; 56 | 57 | return ( 58 | 59 | Host 60 | this.handleCopyBtnClick(dataIndex, 'all')} 65 | /> 66 | 67 | ); 68 | } 69 | } 70 | 71 | export default injectIntl(HostCopyTitle); 72 | -------------------------------------------------------------------------------- /rdb-web/src/pages/ResourcesTree/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { useLayoutEffect, useContext, useState, useEffect } from 'react'; 2 | import { Tabs } from 'antd'; 3 | import { FormattedMessage } from 'react-intl'; 4 | import { NsTreeContext } from '@pkgs/Layout/Provider'; 5 | import Info from './Info'; 6 | import Role from './Role'; 7 | import Resources from './Resources' 8 | import Usages from './Usages'; 9 | 10 | 11 | const { TabPane } = Tabs; 12 | const defaultActiveKey = window.localStorage.getItem('resources-tree-active-key') || 'role'; 13 | 14 | function index() { 15 | const [feConf, setFeConf] = useState({} as any); 16 | const [isPublic, setIsPublic] = useState(true); 17 | const nsTreeContext = useContext(NsTreeContext); 18 | useLayoutEffect(() => { 19 | nsTreeContext.nsTreeVisibleChange(true, true, true); 20 | return () => { 21 | nsTreeContext.nsTreeVisibleChange(false, true, false); 22 | }; 23 | }, []); 24 | 25 | useEffect(() => { 26 | fetch('/static/feConfig.json') 27 | .then((res) => { 28 | return res.json(); 29 | }) 30 | .then((res) => { 31 | setFeConf(res); 32 | }); 33 | }, []) 34 | 35 | useEffect(() => { 36 | if (feConf.header?.mode === 'complicated') { 37 | setIsPublic(false); 38 | } else { 39 | setIsPublic(true); 40 | } 41 | }, [feConf]); 42 | return ( 43 | { 47 | window.localStorage.setItem('resources-tree-active-key', key); 48 | }} 49 | > 50 | } key="info"> 51 | 52 | 53 | } key="role"> 54 | 55 | 56 | } key="resource"> 57 | 58 | 59 | { 60 | isPublic ? null : 61 | 62 | 63 | } 64 | 65 | ) 66 | } 67 | 68 | export default index; 69 | -------------------------------------------------------------------------------- /mon-web/src/pages/Dashboard/utils.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable no-plusplus */ 2 | import _ from 'lodash'; 3 | 4 | export function filterMetrics(filterType, filterValue, alls) { 5 | if (!(filterType && filterValue)) { 6 | return []; 7 | } 8 | 9 | const filters = _.split(filterValue, ','); 10 | switch (filterType) { 11 | case 'prefix': 12 | return _.filter(alls, (m) => { 13 | for (let i = 0; i < filters.length; i++) { 14 | if (m && m.indexOf(filters[i]) === 0) { 15 | return true; 16 | } 17 | } 18 | return false; 19 | }); 20 | case 'substring': 21 | return _.filter(alls, (m) => { 22 | for (let i = 0; i < filters.length; i++) { 23 | if (m && m.indexOf(filters[i]) !== -1) { 24 | return true; 25 | } 26 | } 27 | return false; 28 | }); 29 | case 'suffix': 30 | return _.filter(alls, (m) => { 31 | for (let i = 0; i < filters.length; i++) { 32 | if (m && m.indexOf(filters[i], m.length - filters[i].length) !== -1) { 33 | return true; 34 | } 35 | } 36 | return false; 37 | }); 38 | default: 39 | return []; 40 | } 41 | } 42 | 43 | export function matchMetrics(matches, alls) { 44 | if (!matches || matches.length === 0) { 45 | return []; 46 | } 47 | if (!alls || alls.length === 0) { 48 | return []; 49 | } 50 | 51 | return _.filter(matches, o => _.indexOf(alls, o) > -1); 52 | } 53 | 54 | export function getClusterNs(allNsData, query) { 55 | const { ns, category } = query; 56 | if (category === 'service') { 57 | return _.filter(allNsData, (item) => { 58 | const nsSplit = item.split('.'); 59 | nsSplit.splice(0, 2); 60 | return nsSplit.join('.') === ns; 61 | }); 62 | } 63 | return [`collect.${ns}`]; 64 | } 65 | 66 | export function normalizeGraphData(data) { 67 | const cloneData = _.cloneDeep(data); 68 | _.each(cloneData.metrics, (item) => { 69 | delete item.key; 70 | delete item.metrics; 71 | delete item.tagkv; 72 | delete item.counterList; 73 | delete item.endpoints; 74 | }); 75 | return cloneData; 76 | } 77 | -------------------------------------------------------------------------------- /job-web/config/webpack.dev.config.js: -------------------------------------------------------------------------------- 1 | const process = require('process'); 2 | const StatsPlugin = require('stats-webpack-plugin'); 3 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 4 | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); 5 | const webpackConfigResolveAlias = require('./webpackConfigResolveAlias'); 6 | const fetkJson = require('../fetk.config'); 7 | const pkgJson = require('../package.json'); 8 | 9 | 10 | module.exports = function getwebpackConfig(webpackConfig) { 11 | webpackConfig.resolve.alias = webpackConfigResolveAlias; 12 | // webpackConfig.resolve.mainFields = ['browser', 'main', 'module']; 13 | 14 | if (!process.env.Mode) { 15 | webpackConfig.output.library = pkgJson.systemName; 16 | webpackConfig.output.libraryTarget = 'amd'; 17 | webpackConfig.module.rules.unshift({ 18 | parser: { system: false }, 19 | }); 20 | webpackConfig.output.publicPath = `http://0.0.0.0:${fetkJson.port}/${pkgJson.systemName}/`; 21 | webpackConfig.output.filename = '[name]-[chunkhash].js'; 22 | webpackConfig.externals = [ 23 | /^react$/, 24 | /^react\/lib.*/, 25 | /^react-dom$/, 26 | /.*react-dom.*/, 27 | /^single-spa$/, 28 | /^antd$/, 29 | /^moment$/, 30 | /^d3$/ 31 | ]; 32 | webpackConfig.plugins = webpackConfig.plugins.filter((plugin) => { 33 | if (plugin instanceof HtmlWebpackPlugin || 34 | plugin instanceof MiniCssExtractPlugin) { 35 | return false; 36 | } 37 | return true; 38 | }); 39 | webpackConfig.plugins.push( 40 | new MiniCssExtractPlugin({ 41 | filename: '[name]-[chunkhash].css', 42 | chunkFilename: '[name]-[chunkhash].css', 43 | }), 44 | ); 45 | 46 | const manifestName = `manifest.json`; 47 | webpackConfig.plugins.push( 48 | new StatsPlugin( 49 | manifestName, 50 | { 51 | chunkModules: false, 52 | source: true, 53 | chunks: false, 54 | modules: false, 55 | assets: true, 56 | children: false, 57 | exclude: [/node_modules/] 58 | } 59 | ) 60 | ); 61 | } 62 | return webpackConfig; 63 | }; 64 | -------------------------------------------------------------------------------- /job-web/src/pages/TaskTpl/BindTags.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Modal, Form, Select, message } from 'antd'; 3 | import { injectIntl } from 'react-intl'; 4 | import _ from 'lodash'; 5 | import ModalControl from '@pkgs/ModalControl'; 6 | import request from '@pkgs/request'; 7 | import api from '@common/api'; 8 | 9 | const FormItem = Form.Item; 10 | 11 | class BindTags extends Component { 12 | // static propTypes = { 13 | // selectedIds: PropTypes.array.isRequired, 14 | // visible: PropTypes.bool, 15 | // onOk: PropTypes.func, 16 | // destroy: PropTypes.func, 17 | // }; 18 | 19 | static defaultProps = { 20 | visible: true, 21 | onOk: _.noop, 22 | destroy: _.noop, 23 | }; 24 | 25 | handleOk = () => { 26 | const { selectedIds } = this.props; 27 | this.props.form.validateFields((err: any, values: any) => { 28 | if (!err) { 29 | request(`${api.tasktpls}/tags`, { 30 | method: 'PUT', 31 | body: JSON.stringify({ 32 | tags: _.join(values.tags, ','), 33 | ids: selectedIds, 34 | act: 'bind', 35 | }), 36 | }).then(() => { 37 | message.success(this.props.intl.formatMessage({ id: 'tpl.tag.bind.success' })); 38 | this.props.onOk(); 39 | this.props.destroy(); 40 | }); 41 | } 42 | }); 43 | } 44 | 45 | handleCancel = () => { 46 | this.props.destroy(); 47 | } 48 | 49 | render() { 50 | const { visible } = this.props; 51 | const { getFieldDecorator } = this.props.form; 52 | 53 | return ( 54 | 60 |
61 | 62 | {getFieldDecorator('tags', { 63 | rules: [{ required: true , message: '请选择!'}], 64 | })( 65 | , 37 | )} 38 | 39 | }> 40 | {getFieldDecorator('name', { 41 | initialValue: initialValue.name, 42 | })( 43 | , 44 | )} 45 | 46 | }> 47 | {getFieldDecorator('note', { 48 | initialValue: initialValue.note, 49 | })( 50 | , 51 | )} 52 | 53 | } required> 54 | {getFieldDecorator('mgmt', { 55 | initialValue: initialValue.mgmt || 0, 56 | rules: [{ required: true, message:"必选项!" }], 57 | })( 58 | 59 | 60 | 61 | , 62 | )} 63 | 64 |
65 | ); 66 | } 67 | } 68 | 69 | export default Form.create()(TeamForm) as any; 70 | -------------------------------------------------------------------------------- /rdb-web/src/pages/PersonnelInfo/Teams/TeamForm.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { Form, Input, Radio } from 'antd'; 3 | import { FormattedMessage } from 'react-intl'; 4 | import { FormProps } from 'antd/lib/form'; 5 | 6 | interface Props { 7 | type: 'post' | 'put', 8 | isrootVsible: boolean, 9 | initialValue: any, 10 | } 11 | 12 | const FormItem = Form.Item; 13 | const RadioGroup = Radio.Group; 14 | 15 | class TeamForm extends Component { 16 | static defaultProps: Props = { 17 | type: 'post', 18 | isrootVsible: false, 19 | initialValue: {}, 20 | }; 21 | 22 | validateFields() { 23 | return this.props.form!.validateFields; 24 | } 25 | 26 | render() { 27 | const { initialValue, type } = this.props; 28 | const { getFieldDecorator } = this.props.form!; 29 | return ( 30 |
31 | }> 32 | {getFieldDecorator('ident', { 33 | initialValue: initialValue.ident, 34 | rules: [{ required: true, message:"必填项!" }], 35 | })( 36 | , 37 | )} 38 | 39 | }> 40 | {getFieldDecorator('name', { 41 | initialValue: initialValue.name, 42 | })( 43 | , 44 | )} 45 | 46 | }> 47 | {getFieldDecorator('note', { 48 | initialValue: initialValue.note, 49 | })( 50 | , 51 | )} 52 | 53 | } required> 54 | {getFieldDecorator('mgmt', { 55 | initialValue: initialValue.mgmt || 0, 56 | rules: [{ required: true, message:"必填项!" }], 57 | })( 58 | 59 | 60 | 61 | , 62 | )} 63 | 64 |
65 | ); 66 | } 67 | } 68 | 69 | export default Form.create()(TeamForm) as any; 70 | -------------------------------------------------------------------------------- /rdb-web/src/components/Resources/BatchSearch.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { 3 | Modal, Form, Input, Radio, 4 | } from 'antd'; 5 | import { FormProps } from 'antd/lib/form'; 6 | import _ from 'lodash'; 7 | import { FormattedMessage, injectIntl, WrappedComponentProps } from 'react-intl'; 8 | import ModalControl, { ModalWrapProps } from '@pkgs/ModalControl'; 9 | 10 | interface Props { 11 | field: 'uuid' | 'ident', 12 | batch: string, 13 | } 14 | 15 | const FormItem = Form.Item; 16 | const RadioGroup = Radio.Group; 17 | 18 | class BatchSearch extends Component { 19 | handleOk = () => { 20 | this.props.form!.validateFields((err, values) => { 21 | if (!err) { 22 | const batch = _.replace(values.batch, /\n/g, ','); 23 | this.props.onOk(values.field, batch); 24 | this.props.destroy(); 25 | } 26 | }); 27 | } 28 | 29 | handleCancel = () => { 30 | this.props.destroy(); 31 | } 32 | 33 | render() { 34 | const { 35 | title, visible, field, batch, 36 | } = this.props; 37 | const { getFieldDecorator } = this.props.form!; 38 | 39 | return ( 40 | 46 |
47 | }> 48 | {getFieldDecorator('field', { 49 | initialValue: field || 'ident', 50 | })( 51 | 52 | UUID 53 | 54 | , 55 | )} 56 | 57 | }> 58 | {getFieldDecorator('batch', { 59 | initialValue: _.replace(batch, /,/g, '\n'), 60 | })( 61 | , 64 | )} 65 | 66 |
67 |
68 | ); 69 | } 70 | } 71 | 72 | export default ModalControl(injectIntl(Form.create()(BatchSearch)) as any); 73 | -------------------------------------------------------------------------------- /ams-web/src/pages/Nethws/Management/Batch.tsx: -------------------------------------------------------------------------------- 1 | /* eslint-disable react/jsx-wrap-multilines */ 2 | /* eslint-disable operator-linebreak */ 3 | import React from 'react'; 4 | import { 5 | Form, Modal, Input, 6 | } from 'antd'; 7 | import { FormProps } from 'antd/lib/form'; 8 | import useFormatMessage from '@pkgs/hooks/useFormatMessage'; 9 | import ModalControl, { ModalWrapProps } from '@pkgs/ModalControl'; 10 | import TenantSelect from '@pkgs/TenantSelect'; 11 | 12 | const FormItem = Form.Item; 13 | 14 | interface Props { 15 | field: 'cate' | 'note' | 'tenant'; 16 | onOk: (value: any) => void 17 | } 18 | 19 | function Batch(props: Props & ModalWrapProps &FormProps) { 20 | const intlFmtMsg = useFormatMessage(); 21 | const { 22 | title, visible, destroy, field, onOk, 23 | } = props; 24 | const { getFieldDecorator, validateFields } = props.form!; 25 | const handleOk = () => { 26 | validateFields((err, values) => { 27 | if (!err) { 28 | onOk(values); 29 | destroy(); 30 | } 31 | }); 32 | }; 33 | 34 | return ( 35 | { handleOk(); }} 39 | onCancel={() => { destroy(); }} 40 | > 41 |
{ 44 | e.preventDefault(); 45 | handleOk(); 46 | }} 47 | > 48 | { 49 | field === 'cate' ? 50 | 51 | {getFieldDecorator('cate', { 52 | })( 53 | , 54 | )} 55 | : null 56 | } 57 | { 58 | field === 'tenant' ? 59 | 60 | {getFieldDecorator('tenant', { 61 | })( 62 | , 63 | )} 64 | : null 65 | } 66 | { 67 | field === 'note' ? 68 | 69 | {getFieldDecorator('note', { 70 | })( 71 | , 72 | )} 73 | : null 74 | } 75 |
76 |
77 | ); 78 | } 79 | 80 | export default ModalControl(Form.create()(Batch) as any); 81 | -------------------------------------------------------------------------------- /ams-web/src/pages/Nethws/Management/BatchSearch.tsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { 3 | Modal, Form, Input, Radio, 4 | } from 'antd'; 5 | import { FormProps } from 'antd/lib/form'; 6 | import _ from 'lodash'; 7 | import { FormattedMessage, injectIntl, WrappedComponentProps } from 'react-intl'; 8 | import ModalControl, { ModalWrapProps } from '@pkgs/ModalControl'; 9 | 10 | interface Props { 11 | field: 'id' | 'uuid' | 'ident', 12 | batch: string, 13 | } 14 | 15 | const FormItem = Form.Item; 16 | const RadioGroup = Radio.Group; 17 | 18 | class BatchSearch extends Component { 19 | handleOk = () => { 20 | this.props.form!.validateFields((err, values) => { 21 | if (!err) { 22 | const batch = _.replace(values.batch, /\n/g, ','); 23 | this.props.onOk(values.field, batch); 24 | this.props.destroy(); 25 | } 26 | }); 27 | } 28 | 29 | handleCancel = () => { 30 | this.props.destroy(); 31 | } 32 | 33 | render() { 34 | const { 35 | title, visible, field, batch, 36 | } = this.props; 37 | const { getFieldDecorator } = this.props.form!; 38 | 39 | return ( 40 | 46 |
47 | }> 48 | {getFieldDecorator('field', { 49 | initialValue: field || 'ident', 50 | })( 51 | 52 | SN 53 | IP 54 | 55 | , 56 | )} 57 | 58 | }> 59 | {getFieldDecorator('batch', { 60 | initialValue: _.replace(batch, /,/g, '\n'), 61 | })( 62 | , 65 | )} 66 | 67 |
68 |
69 | ); 70 | } 71 | } 72 | 73 | export default ModalControl(injectIntl(Form.create()(BatchSearch)) as any); 74 | --------------------------------------------------------------------------------