diff --git a/nezha-fronted/src/assets/css/main.css b/nezha-fronted/src/assets/css/main.css index e12c91626..e12fbfa45 100644 --- a/nezha-fronted/src/assets/css/main.css +++ b/nezha-fronted/src/assets/css/main.css @@ -37,6 +37,11 @@ html { .margin-b-10 { margin-bottom: 10px !important; } +.line-100 { + width: 100%; + height: 1px; + background: #C0C4CC; +} /*侧滑文字*/ .el-form-item .el-form-item__label{ font-size: 10px; @@ -74,20 +79,24 @@ html { height: calc(90vh - 55px); width: 100%; } -.sidebar-info-top { +.sidebar-info-item:first-of-type { border-radius: 6px 6px 0 0; } .sidebar-info-item { -height: 39px; -line-height: 39px; -padding: 0 8px 0 32px; -border-bottom: 1px solid #cacaca; -cursor: pointer; -color: #5e5e5e; + height: 39px; + line-height: 39px; + padding: 0 8px 0 32px; + border-bottom: 1px solid #cacaca; + cursor: pointer; + color: #5e5e5e; +} +.side-bar-menu-edit { + line-height: 40px; + float: right; } .sidebar-info-item-active { -background-color: #5e5e5e; -color: white; + background-color: #5e5e5e; + color: white; } .sidebar-info-foot { border-radius: 6px 6px 0 0; @@ -240,10 +249,10 @@ color: white; display: inline-block; } .right-box-form { - margin-top: 35px; + margin-top: 30px; } .right-box-form-row { - margin-top: 20px; + margin-top: 16px; } .right-box-form-label { margin-bottom: 8px; @@ -257,6 +266,12 @@ color: white; .right-box-form-content-txt { padding-left: 11px; } +.right-box-form-tip { + color: #d0d4dC; + font-size: 14px; + line-height: 20px; + min-height: 64px; +} .right-box-form-content .el-select { width: 100%; } diff --git a/nezha-fronted/src/components/common/header.vue b/nezha-fronted/src/components/common/header.vue index fb2893d07..7876e0637 100644 --- a/nezha-fronted/src/components/common/header.vue +++ b/nezha-fronted/src/components/common/header.vue @@ -14,16 +14,24 @@ + @@ -46,7 +54,7 @@
{{$t('config.account.account')}}
-
Prometheus Server
+
{{$t('config.promServer.promServerList')}}
@@ -92,13 +100,12 @@ export default { data() { return { language: localStorage.getItem("language"), - assetData: [] + assetData: [], + projectData: [] } }, methods: { - jumpTo(data,id) { - this.$store.state.assetData.moduleData = data - this.$store.state.assetData.selectedData = id + jumpTo(data) { this.$router.push({ path: "/" + data, query: { @@ -106,6 +113,15 @@ export default { } }); }, + jumpToAsset(data, id) { + this.$store.state.assetData.moduleData = data; + this.$store.state.assetData.selectedData = id; + this.jumpTo(data); + }, + jumpToProject(data, p) { + this.$store.commit('setProject', p); + this.jumpTo(data); + }, changeLocal(lang) { localStorage.setItem("language", lang); window.location.reload(); @@ -117,9 +133,35 @@ export default { } }) }, + getProjectData() { + this.$get('project', this.pageObj).then(response => { + if (response.code == 200) { + this.projectData = response.data.list; + } + }) + }, + toEditProject(p) { + this.$store.commit('setProject', p); + this.$store.commit('projectRightBoxShow', true); + this.jumpTo('project'); + } }, mounted() { - this.getAssetData() + this.getAssetData(); + this.getProjectData(); + }, + computed: { + projectListReload() { + return this.$store.state.projectListReload; + } + }, + watch: { + projectListReloadWatch(n, o) { + if (n) { + this.getProjectData(); + this.$store.commit('projectListReload', false); + } + } } } @@ -224,4 +266,8 @@ export default { .header-name-jiantou { position: static !important; } +.menu-edit { + line-height: 36px; + float: right; +} diff --git a/nezha-fronted/src/components/common/language/en.js b/nezha-fronted/src/components/common/language/en.js index 6f6a15794..67790d7c0 100644 --- a/nezha-fronted/src/components/common/language/en.js +++ b/nezha-fronted/src/components/common/language/en.js @@ -105,10 +105,20 @@ const en = { }, project: { project: { - project: "Project" + project: "Project", + projectName: "Project Name", + editProject: "Edit Project", + description: "Description" }, module: { - module: "Module" + module: "Module", + moduleName: "Module Name", + editModule: "Edit Module", + description: "Description", + tip: { + defaultEndpointSet: "Default Endpoint Set", + relation: "Endpoints associated with Module will reference Port/Path/Param/Params by default" + } }, endpoint: { createEndpoint: "Create Endpoint", diff --git a/nezha-fronted/src/components/page/project/project.vue b/nezha-fronted/src/components/page/project/project.vue index c3e4247d0..4d61bbf3a 100644 --- a/nezha-fronted/src/components/page/project/project.vue +++ b/nezha-fronted/src/components/page/project/project.vue @@ -46,11 +46,16 @@ } .param-box { - height: 303px; border: 1px solid #DCDFE6; border-radius: 4px; padding: 0 10px; } +.param-box-endpoint { + height: 325px; +} +.param-box-module { + height: 227px; +} .param-box-row { padding: 7px 0 0 0; position: relative; @@ -92,18 +97,20 @@ /* begin--子弹框*/ .right-sub-box { - width: 330px; - height: calc(50%); + width: 380px; + height: 520px; position: absolute; top: 380px; right: 100px; z-index: 2; + padding: 0 10px; } .right-sub-box .el-input-group { - width: 60%; + width: 227px; float: right; margin: 7px 0 0 0; } + /* begin--搜索框*/ .endpoint-asset-prepend { border-radius: 4px 0 0 4px; } @@ -128,6 +135,7 @@ .endpoint-asset-label-txt { display: inline-block; width: 19px; + text-align: center; } .endpoint-asset-dropdown-item:first-of-type { border-radius: 4px 4px 0 0; @@ -138,15 +146,104 @@ .endpoint-asset-dropdown-item:hover { background-color: #3a8ee6; } + /* end--搜索框*/ + /* begin--table*/ +.endpoint-sub-table { + margin-top: 25px; +} +.line-100 { + margin-bottom: 3px; +} +.endpoint-sub-table-head { + line-height: 28px; + height: 30px; +} +.endpoint-sub-table-row { + line-height: 28px; + height: 30px; + color: #656565; +} +.endpoint-sub-table-row-active { + background-color: #dadada; +} +.endpoint-sub-table-col { + display: inline-block; + width: 45%; + padding-left: 10px; +} +.endpoint-sub-table-paginate-all { + position: absolute; + left: 10px; + bottom: 17px; + color: #5a5a5a; +} +.endpoint-sub-table-body { + font-size: 15px; +} + /* end--table*/ + /* end--子弹框*/ + + - + + + +
+
+
IP
+
SN
+
+
+
+
+
{{selectedAsset.host}}
+
{{selectedAsset.sn}}
+
+
+
{{item.host}}
+
{{item.sn}}
+
+
+
+
All: {{assetPageObj.total}}
+ + +
+
+ + + + +
+ +
+
+
+ +
+ {{$t('overall.esc')}} +
+
+
+ +
+ {{$t('overall.save')}} +
+
+
+ +
+ {{$t('overall.delete')}} +
+
+ + + +
{{projectRightBox.title}}
+ + + +
+ +
+
{{$t("project.project.projectName")}}
+
+ +
+
+ +
+
{{$t("project.project.description")}}
+
+ +
+
+
+ + +
+
{{$t('overall.cancel')}}
{{project.id == '' ? $t('overall.create') : $t('overall.save')}}
+
+ +
+
+ + + + +
+ +
+
+
+ +
+ {{$t('overall.esc')}} +
+
+
+ +
+ {{$t('overall.save')}} +
+
+
+ +
+ {{$t('overall.delete')}} +
+
+ + + +
{{moduleRightBox.title}}
+ + + +
+ +
+
{{$t("project.project.project")}}
+
+ + + +
+
+ +
+
{{$t("project.module.moduleName")}}
+
+ +
+
+ +
+
{{$t("project.module.description")}}
+
+ +
+
+ +
+
+
+ {{$t('project.module.tip.defaultEndpointSet')}} +
+ {{$t('project.module.tip.relation')}} +
+
+
+ +
+
{{$t("project.endpoint.port")}}
+
+ +
+
+ +
+
{{$t("project.endpoint.path")}}
+
+ +
+
+ +
+
+ {{$t("project.endpoint.param")}} + {{$t('overall.add')}} + {{$t('overall.clearAll')}} +
+
+
+
+ + = + + +
+
+
+
+
+ + +
+
{{$t('overall.cancel')}}
{{currentModule.id == '' ? $t('overall.create') : $t('overall.save')}}
+
+ +
+
+ @@ -362,6 +688,11 @@ export default { name: "project", data() { return { + projectRightBox: { + show: false, + title: '' + }, + project: {id: '', name: '', remark: ''}, rightBox: { //弹出框相关 show: false, isEdit: false, //false查看,true编辑 @@ -371,8 +702,8 @@ export default { show: false, title: this.$t("overall.asset") }, - assetSearch: { - ip: '', + assetSearch: { //侧滑框中asset的搜索相关 + host: '', sn: '', text: '', label: 'IP', @@ -383,6 +714,11 @@ export default { pageSize: 20, total:0 }, + assetPageObj: { + pageNo: 1, + pageSize: 11, + total: 0 + }, endpoint: { id: '', host: '', @@ -393,10 +729,23 @@ export default { project: {id: '', name: ''}, module: {id: '', name: '', param: '', paramObj: {}} }, - selectedModule: { + moduleRightBox: { + show: false, + title: '' + }, + currentModule: { //左侧列表当前选中的module id: '', name: '' }, + selectedModule: { //侧滑框中选中的module + id: '', + name: '' + }, + selectedAsset: { //侧滑框中选中的asset + id: '', + host: '', + sn: '' + }, tableTitle: [ { label: this.$t("project.endpoint.endpointId"), @@ -431,23 +780,30 @@ export default { } ], endPointTableData: [], - projectData: [], - moduleData: [], - paramObj: [] + projectData: [], //侧滑框中可选的project + moduleData: [], //左侧列表的module信息 + toSelectModuleData: [], //侧滑框中可选的module + paramObj: [], //侧滑框中的param信息 + assetData: [] //侧滑框中可选的asset } }, methods: { - showSubShow: function() { + // endpoint弹框中asset子弹框控制 + showSubBox: function() { this.rightSubBox.show = !this.rightSubBox.show; + this.selectedAsset = this.endpoint.asset; }, + // table数据 getEndPointTableData: function() { + this.$set(this.pageObj, 'moduleId', this.currentModule.id); this.$get('endpoint', this.pageObj).then(response => { if (response.code === 200) { for (var i = 0; i < response.data.list.length; i++) { try { var tempObj = JSON.parse(response.data.list[i].param); } catch (err) { - + console.info(response.data.list[i]); + console.info(err); } response.data.list[i].paramObj = []; for (let k in tempObj) { @@ -459,6 +815,7 @@ export default { } }); }, + // 获取module、endpoint弹框中project下拉框数据 getProjectData: function() { this.$get('project').then(response => { if (response.code === 200) { @@ -466,76 +823,204 @@ export default { } }); }, - getModuleData: function(projectId) { - // module选择改变时,记录旧module的id值(endpoint.moduleId)和对应的endpoint的param(endpoint.和对应的endpoint.param), - // 然后改变,改变后param用module的值,如果改回旧module,则恢复endpoint的param - this.selectedModule = {id: '', name: ''}; - this.$get('module', {projectId: projectId}).then(response => { + // 获取endpoint弹框中的asset子弹框里asset列表数据 + getAssetData: function(currentPage) { + if (currentPage) { + this.assetPageObj.pageNo = currentPage; + } else { + this.assetPageObj.pageNo = 1; + } + this.$get('asset', this.assetPageObj).then(response => { if (response.code === 200) { + this.assetData = response.data.list; + this.assetPageObj.total = response.data.total; + } + }); + }, + // endpoint弹框中的asset子弹框里asset选择事件 + selectAsset: function(obj) { + this.selectedAsset = obj; + }, + // endpoint弹框中的asset子弹框搜索 + searchAsset: function() { + if (this.assetSearch.label == 'IP') { + this.assetSearch.host = this.assetSearch.text; + this.assetSearch.sn = ''; + } else if (this.assetSearch.label == 'SN') { + this.assetSearch.sn = this.assetSearch.text; + this.assetSearch.host = ''; + } + this.assetPageObj = Object.assign({}, this.assetPageObj, this.assetSearch); + this.getAssetData(false); + }, + // 获取左侧module列表数据 + getModuleData: function() { + this.$get('module', {projectId: this.$store.state.projectData.id}).then(response => { + if (response.code === 200) { + this.moduleData = response.data.list; for (var i = 0; i < response.data.list.length; i++) { - var tempObj = JSON.parse(response.data.list[i].param); + try { + var tempObj = JSON.parse(response.data.list[i].param); + } catch (err) { + console.info(response.data.list[i]); + console.info(err); + } response.data.list[i].paramObj = []; for (let k in tempObj) { response.data.list[i].paramObj.push({key: k, value: tempObj[k]}) } } - this.moduleData = response.data.list; + if (this.moduleData.length > 0) { + this.currentModule = this.moduleData[0]; + this.getEndPointTableData(); + } else { + this.endPointTableData = []; + this.pageObj.total = 0; + } + } }); }, - changeModule: function(moduleId) { + // 获取endpoint弹框中module下拉框数据 + getToSelectModuleData: function(projectId) { + this.selectedModule = {id: '', name: ''}; + this.$get('module', {projectId: projectId}).then(response => { + if (response.code === 200) { + for (var i = 0; i < response.data.list.length; i++) { + try { + var tempObj = JSON.parse(response.data.list[i].param); + } catch(err) { + console.info(response.data.list[i]); + console.info(err); + } + response.data.list[i].paramObj = []; + for (let k in tempObj) { + response.data.list[i].paramObj.push({key: k, value: tempObj[k]}) + } + } + this.toSelectModuleData = response.data.list; + } + }); + }, + // 左侧module列表点击事件 + changeListModule: function(module) { + this.currentModule = Object.assign({}, module); + this.moduleRightBox.show = false; + this.getEndPointTableData(); + }, + // endpoint弹框中module下拉框点击事件 + changeSelectedModule: function(moduleId) { if (moduleId == this.endpoint.moduleId) { - this.paramObj = JSON.parse(JSON.stringify(this.endpoint.paramObj)); + try { + this.paramObj = JSON.parse(JSON.stringify(this.endpoint.paramObj)); + } catch(err) { + console.info(this.endpoint.paramObj); + console.info(err); + } } else { - this.paramObj = JSON.parse(JSON.stringify(this.selectedModule.paramObj)); + try { + this.paramObj = JSON.parse(JSON.stringify(this.selectedModule.paramObj)); + } catch(err) { + console.info(this.selectedModule.paramObj); + console.info(err); + } } }, - toEdit: function(u) { - this.getModuleData(u.project.id); - this.selectedModule = Object.assign({}, u.module); - this.endpoint = Object.assign({}, u); - //this.paramObj = this.endpoint.paramObj; - this.paramObj = JSON.parse(JSON.stringify(this.endpoint.paramObj)); + // 打开endpoint编辑页 + toEdit: function(endpoint) { + this.getToSelectModuleData(endpoint.project.id); + this.selectedModule = Object.assign({}, endpoint.module); + this.endpoint = Object.assign({}, endpoint); + try { + this.paramObj = JSON.parse(JSON.stringify(this.endpoint.paramObj)); + } catch(err) { + console.info(this.endpoint.paramObj); + console.info(err); + } + this.rightBox.isEdit = true; - this.rightBox.title = this.$t("project.endpoint.editEndpoint") + " ID:" + u.id; + this.rightBox.title = this.$t("project.endpoint.editEndpoint") + " ID:" + endpoint.id; this.rightBox.show = true; }, + // 打开module编辑页 + toEditModule: function(module) { + this.currentModule = Object.assign({}, module); + try { + this.paramObj = JSON.parse(JSON.stringify(this.currentModule.paramObj)); + } catch(err) { + console.info(this.currentModule.paramObj); + console.info(err); + } + this.moduleRightBox.show = true; + this.getEndPointTableData(); + this.moduleRightBox.title = this.$t('project.module.editModule') + " ID:" + module.id; + }, + // 删除endpoint del: function(u) { }, + // 打开endpoint新增页 toAdd: function() { this.cleanEndpoint(); this.paramObj = []; - this.moduleData = []; + this.toSelectModuleData = []; this.rightBox.isEdit = true; this.rightBox.title = this.$t("project.endpoint.createEndpoint"); this.rightBox.show = true; }, + // 打开endpoint详情页 detail: function(u) { this.endpoint = Object.assign({}, u); this.rightBox.isEdit = false; this.rightBox.title = this.$t("project.endpoint.endpoint") + " ID:" + u.id; this.rightBox.show = true; }, + // endpoint弹框保存或编辑 saveOrToEdit: function() { if (!this.rightBox.isEdit) { this.rightBox.isEdit = true; this.rightBox.title = this.$t("project.endpoint.editEndpoint") + " ID:" + this.endpoint.id; } }, + // 保存project + projectSave: function() { + this.$put('project', this.project).then(response => { + if (response.code === 200) { + this.$store.commit('projectListReload', true); + this.projectRightBox.show = false; + } + }); + }, + // 保存module + moduleSave: function() { + + }, + // 保存endpoint save: function() { }, + // 清除module、endpoint弹框中的param clearAllParam: function() { this.paramObj = []; }, + // 新增module、endpoint弹框中的param addParam: function() { this.paramObj.push({key: '', value: ''}); }, + // 移除单个module、endpoint弹框中的param removeParam: function(index) { this.paramObj.splice(index, 1); }, - esc: function() { - this.rightBox.show = false; + // 关闭右侧弹框 + esc: function(type) { + if (type == 1) { + this.rightBox.show = false; + } + if (type == 2) { + this.$store.commit('projectRightBoxShow', false); + } + if (type == 3) { + this.moduleRightBox.show = false; + } }, cleanEndpoint: function() { this.endpoint = { @@ -557,15 +1042,35 @@ export default { this.pageObj.pageSize = val; this.getEndPointTableData(); }, - + // endpoint弹框的子弹框顶部搜索条件选中事件 dropdownSelect: function(label) { this.assetSearch.label = label; this.assetSearch.dropdownShow = false; } }, mounted: function() { - this.getEndPointTableData(); + this.getModuleData(); this.getProjectData(); + this.getAssetData(); + }, + computed:{ + sProject() { + return this.$store.state.projectData; + }, + projectBoxShow() { + return this.$store.state.projectBoxShow; + } + }, + watch: { + sProject(n, o) { + this.project = Object.assign({}, n); + this.projectRightBox.title = this.$t("project.project.editProject") + " ID:" + n.id; + this.getModuleData(); + }, + projectBoxShow(n, o) { + console.info(n) + this.projectRightBox.show = n; + } } } diff --git a/nezha-fronted/src/store/index.js b/nezha-fronted/src/store/index.js index ec011bc1c..215bcc7f0 100644 --- a/nezha-fronted/src/store/index.js +++ b/nezha-fronted/src/store/index.js @@ -7,14 +7,30 @@ const store = new Vuex.Store({ assetData:{ selectedData:'', moduleData:'', - } + }, + projectData: { + id: '', + name: '' + }, + projectBoxShow: false, + projectListReload: false }, getters: { }, mutations: { + setProject(state, project) { + state.projectData = Object.assign({}, project); + state.projectBoxShow = false; + }, + projectRightBoxShow(state, show) { + state.projectBoxShow = show; + }, + projectListReload(state, reload) { + state.projectListReload = reload; + } }, actions: { } }); -export default store; \ No newline at end of file +export default store;