Browse Source

Merge pull request #99 from millionfor/dev-20190415

增加worker
pull/2/head
millionfor 5 years ago committed by GitHub
parent
commit
28c370e349
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      escheduler-ui/src/js/conf/home/pages/dag/_source/dag.vue
  2. 2
      escheduler-ui/src/js/conf/home/pages/dag/_source/formModel/_source/selectInput.vue
  3. 2
      escheduler-ui/src/js/conf/home/pages/dag/_source/formModel/_source/timeoutAlarm.vue
  4. 46
      escheduler-ui/src/js/conf/home/pages/dag/_source/formModel/_source/workerGroups.vue
  5. 109
      escheduler-ui/src/js/conf/home/pages/dag/_source/formModel/formModel.scss
  6. 134
      escheduler-ui/src/js/conf/home/pages/dag/_source/formModel/formModel.vue
  7. 5
      escheduler-ui/src/js/conf/home/pages/dag/definitionDetails.vue
  8. 5
      escheduler-ui/src/js/conf/home/pages/dag/index.vue
  9. 5
      escheduler-ui/src/js/conf/home/pages/dag/instanceDetails.vue
  10. 118
      escheduler-ui/src/js/conf/home/pages/security/pages/workerGroups/_source/createWorker.vue
  11. 119
      escheduler-ui/src/js/conf/home/pages/security/pages/workerGroups/_source/list.vue
  12. 114
      escheduler-ui/src/js/conf/home/pages/security/pages/workerGroups/index.vue
  13. 8
      escheduler-ui/src/js/conf/home/router/index.js
  14. 43
      escheduler-ui/src/js/conf/home/store/security/actions.js
  15. 2
      escheduler-ui/src/js/conf/home/store/security/state.js
  16. 1
      escheduler-ui/src/js/module/components/priority/priority.vue
  17. 9
      escheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js
  18. 1
      escheduler-ui/src/js/module/permissions/index.js

2
escheduler-ui/src/js/conf/home/pages/dag/_source/dag.vue

@ -474,5 +474,5 @@
</script>
<style lang="scss" rel="stylesheet/scss">
@import "dag";
@import "./dag";
</style>

2
escheduler-ui/src/js/conf/home/pages/dag/_source/formModel/_source/selectInput.vue

@ -33,7 +33,7 @@
import disabledState from '@/module/mixin/disabledState'
export default {
name: 'select-input',
name: 'form-select-input',
data () {
return {
isIconState: false,

2
escheduler-ui/src/js/conf/home/pages/dag/_source/formModel/_source/timeoutAlarm.vue

@ -46,7 +46,7 @@
import disabledState from '@/module/mixin/disabledState'
export default {
name: 'timeout-alarm',
name: 'form-timeout-alarm',
data () {
return {
// Timeout display hiding

46
escheduler-ui/src/js/conf/home/pages/dag/_source/formModel/_source/workerGroups.vue

@ -0,0 +1,46 @@
<template>
<x-select
@on-change="_onChange"
v-model="value"
style="width: 180px">
<x-option
v-for="item in workerGroupsList"
:key="item.id"
:value="item.id"
:label="item.name">
</x-option>
</x-select>
</template>
<script>
import disabledState from '@/module/mixin/disabledState'
export default {
name: 'form-worker-group',
data () {
return {
workerGroupsList: []
}
},
mixins: [disabledState],
props: {
value: Number
},
model: {
prop: 'value',
event: 'workerGroupsEvent'
},
methods: {
_onChange (o) {
this.value = o.value
this.$emit('workerGroupsEvent', o.value)
}
},
watch: {
},
created () {
this.workerGroupsList = this.store.state.security.workerGroupsListAll || []
if (!this.value) {
this.$emit('workerGroupsEvent', this.workerGroupsList[0].id)
}
}
}
</script>

109
escheduler-ui/src/js/conf/home/pages/dag/_source/formModel/formModel.scss

@ -0,0 +1,109 @@
.form-model-model {
width: 720px;
position: relative;
.title-box {
height: 61px;
border-bottom: 1px solid #DCDEDC;
position: relative;
.name {
position: absolute;
left: 24px;
top: 18px;
font-size: 16px;
}
.go-subtask {
position: absolute;
right: 30px;
top: 17px;
a {
font-size: 14px;
color: #0097e0;
margin-left: 10px;
i.iconfont {
font-size: 18px;
vertical-align: middle;
}
em {
color: #333;
vertical-align: middle;
font-style: normal;
vertical-align: middle;
padding-left: 2px;
}
&:hover {
em {
text-decoration: underline;
}
}
}
}
}
.bottom-box {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
text-align: right;
height: 60px;
line-height: 60px;
border-top: 1px solid #DCDEDC;
background: #fff;
.submit {
padding-right: 20px;
position: relative;
z-index: 9;
}
}
.content-box {
overflow-y: scroll;
height: calc(100vh - 61px);
padding-bottom: 60px;
}
}
.from-model {
padding-top: 26px;
>div {
clear: both;
}
.list {
position: relative;
margin-bottom: 10px;
.text-box {
width: 112px;
float: left;
text-align: right;
margin-right: 8px;
>span {
font-size: 14px;
color: #777;
display: inline-block;
padding-top: 6px;
}
}
.cont-box {
width: 580px;
float: left;
.label-box {
width: 100%;
}
.text-b {
font-size: 14px;
color: #777;
display: inline-block;
padding:0 6px 0 20px;
}
}
.add {
line-height: 32px;
a {
color: #0097e0;
}
}
&:hover {
}
.list-t {
width: 50%;
float: left;
}
}
}

134
escheduler-ui/src/js/conf/home/pages/dag/_source/formModel/formModel.vue

@ -13,7 +13,6 @@
</div>
<div class="content-box" v-if="isContentBox">
<div class="from-model">
<!-- Node name -->
<div class="clearfix list">
<div class="text-box"><span>{{$t('Node name')}}</span></div>
@ -51,7 +50,6 @@
<span>{{$t('Description')}}</span>
</div>
<div class="cont-box">
<label class="label-box">
<x-input
resize
@ -72,9 +70,11 @@
<span>{{$t('Task priority')}}</span>
</div>
<div class="cont-box">
<label class="label-box">
<m-priority v-model="taskInstancePriority" style="width: 180px;"></m-priority>
</label>
<span class="label-box" style="width: 193px;display: inline-block;">
<m-priority v-model="taskInstancePriority"></m-priority>
</span>
<span class="text-b">Worker分组</span>
<m-worker-groups v-model="workerGroupId"></m-worker-groups>
</div>
</div>
@ -178,15 +178,16 @@
import mShell from './tasks/shell'
import mSpark from './tasks/spark'
import mPython from './tasks/python'
import { isNameExDag, rtBantpl } from './../plugIn/util'
import JSP from './../plugIn/jsPlumbHandle'
import mProcedure from './tasks/procedure'
import mDependent from './tasks/dependent'
import mSubProcess from './tasks/sub_process'
import mSelectInput from './_source/selectInput'
import mTimeoutAlarm from './_source/timeoutAlarm'
import mWorkerGroups from './_source/workerGroups'
import clickoutside from '@/module/util/clickoutside'
import disabledState from '@/module/mixin/disabledState'
import { isNameExDag, rtBantpl } from './../plugIn/util'
import mPriority from '@/module/components/priority/priority'
export default {
@ -218,7 +219,9 @@
// Task timeout alarm
timeout: {},
// Task priority
taskInstancePriority: 'MEDIUM'
taskInstancePriority: 'MEDIUM',
// worker group id
workerGroupId: null
}
},
/**
@ -349,7 +352,8 @@
maxRetryTimes: this.maxRetryTimes,
retryInterval: this.retryInterval,
timeout: this.timeout,
taskInstancePriority: this.taskInstancePriority
taskInstancePriority: this.taskInstancePriority,
workerGroupId: this.workerGroupId
},
fromThis: this
})
@ -420,6 +424,7 @@
this.desc = o.desc
this.maxRetryTimes = o.maxRetryTimes
this.retryInterval = o.retryInterval
this.workerGroupId = o.workerGroupId
}
}
this.isContentBox = true
@ -451,119 +456,12 @@
mDependent,
mSelectInput,
mTimeoutAlarm,
mPriority
mPriority,
mWorkerGroups
}
}
</script>
<style lang="scss" rel="stylesheet/scss">
.form-model-model {
width: 720px;
position: relative;
.title-box {
height: 61px;
border-bottom: 1px solid #DCDEDC;
position: relative;
.name {
position: absolute;
left: 24px;
top: 18px;
font-size: 16px;
}
.go-subtask {
position: absolute;
right: 30px;
top: 17px;
a {
font-size: 14px;
color: #0097e0;
margin-left: 10px;
i.iconfont {
font-size: 18px;
vertical-align: middle;
}
em {
color: #333;
vertical-align: middle;
font-style: normal;
vertical-align: middle;
padding-left: 2px;
}
&:hover {
em {
text-decoration: underline;
}
}
}
}
}
.bottom-box {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
text-align: right;
height: 60px;
line-height: 60px;
border-top: 1px solid #DCDEDC;
background: #fff;
.submit {
padding-right: 20px;
position: relative;
z-index: 9;
}
}
.content-box {
overflow-y: scroll;
height: calc(100vh - 61px);
padding-bottom: 60px;
}
}
.from-model {
padding-top: 26px;
>div {
clear: both;
}
.list {
position: relative;
margin-bottom: 10px;
.text-box {
width: 112px;
float: left;
text-align: right;
margin-right: 8px;
>span {
font-size: 14px;
color: #777;
display: inline-block;
padding-top: 6px;
}
}
.cont-box {
width: 580px;
float: left;
.label-box {
width: 100%;
}
.text-b {
font-size: 14px;
color: #777;
display: inline-block;
padding:0 6px 0 20px;
}
}
.add {
line-height: 32px;
a {
color: #0097e0;
}
}
&:hover {
}
.list-t {
width: 50%;
float: left;
}
}
}
@import "./formModel";
</style>

5
escheduler-ui/src/js/conf/home/pages/dag/definitionDetails.vue

@ -26,6 +26,7 @@
methods: {
...mapMutations('dag', ['resetParams', 'setIsDetails']),
...mapActions('dag', ['getProcessList', 'getResourcesList', 'getProcessDetails']),
...mapActions('security', ['getWorkerGroupsAll']),
/**
* init
*/
@ -40,7 +41,9 @@
// get process definition
this.getProcessList(),
// get resource
this.getResourcesList()
this.getResourcesList(),
// get worker group list
this.getWorkerGroupsAll()
]).then((data) => {
let item = data[0]
this.setIsDetails(item.releaseState === 'ONLINE')

5
escheduler-ui/src/js/conf/home/pages/dag/index.vue

@ -25,6 +25,7 @@
methods: {
...mapMutations('dag', ['resetParams']),
...mapActions('dag', ['getProcessList', 'getResourcesList']),
...mapActions('security', ['getWorkerGroupsAll']),
/**
* init
*/
@ -37,7 +38,9 @@
// get process definition
this.getProcessList(),
// get resource
this.getResourcesList()
this.getResourcesList(),
// get worker group list
this.getWorkerGroupsAll()
]).then((data) => {
this.isLoading = false
// Whether to pop up the box?

5
escheduler-ui/src/js/conf/home/pages/dag/instanceDetails.vue

@ -26,6 +26,7 @@
methods: {
...mapMutations('dag', ['setIsDetails', 'resetParams']),
...mapActions('dag', ['getProcessList', 'getResourcesList', 'getInstancedetail']),
...mapActions('security', ['getWorkerGroupsAll']),
/**
* init
*/
@ -40,7 +41,9 @@
// get process definition
this.getProcessList(),
// get resources
this.getResourcesList()
this.getResourcesList(),
// get worker group list
this.getWorkerGroupsAll()
]).then((data) => {
let item = data[0]
let flag = false

118
escheduler-ui/src/js/conf/home/pages/security/pages/workerGroups/_source/createWorker.vue

@ -0,0 +1,118 @@
<template>
<m-popup
ref="popup"
:ok-text="item ? $t('Edit') : $t('Submit')"
:nameText="item ? '编辑Worker分组' : '创建Worker分组'"
@ok="_ok">
<template slot="content">
<div class="create-worker-model">
<m-list-box-f>
<template slot="name"><b>*</b>{{$t('Group Name')}}</template>
<template slot="content">
<x-input
type="input"
v-model="name"
:placeholder="$t('Please enter group name')">
</x-input>
</template>
</m-list-box-f>
<m-list-box-f>
<template slot="name">IP</template>
<template slot="content">
<x-input
:autosize="{ minRows: 4, maxRows: 6 }"
type="textarea"
v-model="ipList"
:placeholder="'请输入IP地址多个用逗号隔开'">
</x-input>
<div class="ipt-tip">
<span>注意多个IP地址已逗号分割</span>
</div>
</template>
</m-list-box-f>
</div>
</template>
</m-popup>
</template>
<script>
import i18n from '@/module/i18n'
import store from '@/conf/home/store'
import mPopup from '@/module/components/popup/popup'
import mListBoxF from '@/module/components/listBoxF/listBoxF'
export default {
name: 'create-warning',
data () {
return {
store,
id: 0,
name: '',
ipList: ''
}
},
props: {
item: Object
},
methods: {
_ok () {
if (this._verification()) {
// Verify username
this._submit()
}
},
_verification () {
// group name
if (!this.name) {
this.$message.warning(`${i18n.$t('Please enter group name')}`)
return false
}
if (!this.ipList) {
this.$message.warning(`IP地址不能为空`)
return false
}
return true
},
_submit () {
let param = {
id: this.id,
name: this.name,
ipList: this.ipList
}
if (this.item) {
param.id = this.item.id
}
this.$refs['popup'].spinnerLoading = true
this.store.dispatch(`security/saveWorkerGroups`, param).then(res => {
this.$emit('onUpdate')
this.$message.success(res.msg)
setTimeout(() => {
this.$refs['popup'].spinnerLoading = false
}, 800)
}).catch(e => {
this.$message.error(e.msg || '')
this.$refs['popup'].spinnerLoading = false
})
}
},
watch: {},
created () {
if (this.item) {
this.id = this.item.id
this.name = this.item.name
this.ipList = this.item.ipList
}
},
mounted () {
},
components: { mPopup, mListBoxF }
}
</script>
<style lang="scss" rel="stylesheet/scss">
.create-worker-model {
.ipt-tip {
color: #999;
padding-top: 4px;
display: block;
}
}
</style>

119
escheduler-ui/src/js/conf/home/pages/security/pages/workerGroups/_source/list.vue

@ -0,0 +1,119 @@
<template>
<div class="list-model">
<div class="table-box">
<table>
<tr>
<th>
<span>{{$t('#')}}</span>
</th>
<th>
<span>分组名称</span>
</th>
<th>
<span>IPList</span>
</th>
<th>
<span>{{$t('Create Time')}}</span>
</th>
<th>
<span>{{$t('Update Time')}}</span>
</th>
<th width="70">
<span>{{$t('Operation')}}</span>
</th>
</tr>
<tr v-for="(item, $index) in list" :key="$index">
<td>
<span>{{parseInt(pageNo === 1 ? ($index + 1) : (($index + 1) + (pageSize * (pageNo - 1))))}}</span>
</td>
<td>
<span>
<a href="javascript:" class="links">{{item.name}}</a>
</span>
</td>
<td>
<span>{{item.ipList}}</span>
</td>
<td>
<span>{{item.createTime | formatDate}}</span>
</td>
<td><span>{{item.updateTime | formatDate}}</span></td>
<td>
<x-button type="info" shape="circle" size="xsmall" data-toggle="tooltip" icon="iconfont icon-bianjixiugai" :title="$t('Edit')" @click="_edit(item)">
</x-button>
<x-poptip
:ref="'poptip-delete-' + $index"
placement="bottom-end"
width="90">
<p>{{$t('Delete?')}}</p>
<div style="text-align: right; margin: 0;padding-top: 4px;">
<x-button type="text" size="xsmall" shape="circle" @click="_closeDelete($index)">{{$t('Cancel')}}</x-button>
<x-button type="primary" size="xsmall" shape="circle" @click="_delete(item,$index)">{{$t('Confirm')}}</x-button>
</div>
<template slot="reference">
<x-button type="error" shape="circle" size="xsmall" data-toggle="tooltip" icon="iconfont icon-shanchu" :title="$t('delete')">
</x-button>
</template>
</x-poptip>
</td>
</tr>
</table>
</div>
</div>
</template>
<script>
// import _ from 'lodash'
// import i18n from '@/module/i18n'
import { mapActions } from 'vuex'
import '@/module/filter/formatDate'
import { findComponentDownward } from '@/module/util/'
export default {
name: 'user-list',
data () {
return {
list: []
}
},
props: {
workerGroupList: Array,
pageNo: Number,
pageSize: Number
},
methods: {
...mapActions('security', ['deleteWorkerGroups']),
_closeDelete (i) {
this.$refs[`poptip-delete-${i}`][0].doClose()
},
_delete (item, i) {
this.deleteWorkerGroups({
id: item.id
}).then(res => {
this.$refs[`poptip-delete-${i}`][0].doClose()
this.list.splice(i, 1)
this.$message.success(res.msg)
}).catch(e => {
this.$refs[`poptip-delete-${i}`][0].doClose()
this.$message.error(e.msg || '')
})
},
_edit (item) {
findComponentDownward(this.$root, 'worker-groups-index')._create(item)
}
},
watch: {
workerGroupList (a) {
this.list = []
setTimeout(() => {
this.list = a
})
}
},
created () {
this.list = this.workerGroupList
},
mounted () {
},
components: { }
}
</script>

114
escheduler-ui/src/js/conf/home/pages/security/pages/workerGroups/index.vue

@ -0,0 +1,114 @@
<template>
<m-list-construction :title="'worker分组管理'">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group">
<x-button type="ghost" size="small" @click="_create('')">创建worker分组</x-button>
</template>
</m-conditions>
</template>
<template slot="content">
<template v-if="workerGroupList.length">
<m-list :worker-group-list="workerGroupList" :page-no="searchParams.pageNo" :page-size="searchParams.pageSize"></m-list>
<div class="page-box">
<x-page :current="parseInt(searchParams.pageNo)" :total="total" :page-size="searchParams.pageSize" show-elevator @on-change="_page"></x-page>
</div>
</template>
<template v-if="!workerGroupList.length">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading"></m-spin>
</template>
</m-list-construction>
</template>
<script>
import _ from 'lodash'
import { mapActions } from 'vuex'
import mList from './_source/list'
import mSpin from '@/module/components/spin/spin'
import mCreateWorker from './_source/createWorker'
import mNoData from '@/module/components/noData/noData'
import listUrlParamHandle from '@/module/mixin/listUrlParamHandle'
import mConditions from '@/module/components/conditions/conditions'
import mListConstruction from '@/module/components/listConstruction/listConstruction'
export default {
name: 'worker-groups-index',
data () {
return {
total: null,
isLoading: false,
workerGroupList: [],
searchParams: {
pageSize: 10,
pageNo: 1,
searchVal: ''
}
}
},
mixins: [listUrlParamHandle],
props: {},
methods: {
...mapActions('security', ['getWorkerGroups']),
/**
* Inquire
*/
_onConditions (o) {
this.searchParams = _.assign(this.searchParams, o)
this.searchParams.pageNo = 1
},
_page (val) {
this.searchParams.pageNo = val
},
_create (item) {
let self = this
let modal = this.$modal.dialog({
closable: false,
showMask: true,
escClose: true,
className: 'v-modal-custom',
transitionName: 'opacityp',
render (h) {
return h(mCreateWorker, {
on: {
onUpdate () {
self._debounceGET('false')
modal.remove()
},
close () {
modal.remove()
}
},
props: {
item: item
}
})
}
})
},
_getList (flag) {
this.isLoading = !flag
this.getWorkerGroups(this.searchParams).then(res => {
this.workerGroupList = []
this.workerGroupList = res.totalList
this.total = res.total
this.isLoading = false
}).catch(e => {
this.isLoading = false
})
}
},
watch: {
// router
'$route' (a) {
// url no params get instance list
this.searchParams.pageNo = _.isEmpty(a.query) ? 1 : a.query.pageNo
}
},
created () {
},
mounted () {
},
components: { mList, mListConstruction, mConditions, mSpin, mNoData }
}
</script>

8
escheduler-ui/src/js/conf/home/router/index.js

@ -317,6 +317,14 @@ const router = new Router({
meta: {
title: `${i18n.$t('Queue manage')}`
}
},
{
path: '/security/worker-groups',
name: 'worker-groups-manage',
component: resolve => require(['../pages/security/pages/workerGroups/index'], resolve),
meta: {
title: `workerGroups`
}
}
]
},

43
escheduler-ui/src/js/conf/home/store/security/actions.js

@ -413,5 +413,48 @@ export default {
reject(e)
})
})
},
/**
* get worker groups
*/
getWorkerGroups ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get(`worker-group/list-paging`, payload, res => {
resolve(res.data)
}).catch(e => {
reject(e)
})
})
},
/**
* get worker groups all
*/
getWorkerGroupsAll ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get(`worker-group/all-groups`, payload, res => {
state.workerGroupsListAll = res.data
resolve(res.data)
}).catch(e => {
reject(e)
})
})
},
saveWorkerGroups ({ state }, payload) {
return new Promise((resolve, reject) => {
io.post(`worker-group/save`, payload, res => {
resolve(res)
}).catch(e => {
reject(e)
})
})
},
deleteWorkerGroups ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get(`worker-group/delete-by-id`, payload, res => {
resolve(res)
}).catch(e => {
reject(e)
})
})
}
}

2
escheduler-ui/src/js/conf/home/store/security/state.js

@ -15,5 +15,5 @@
* limitations under the License.
*/
export default {
workerGroupsListAll: []
}

1
escheduler-ui/src/js/module/components/priority/priority.vue

@ -91,6 +91,7 @@
<style lang="scss" rel="stylesheet/scss">
.priority-model {
display: inline-block;
.ans-option-listp {
>span {
font-weight: normal;

9
escheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js

@ -108,6 +108,15 @@ let menu = {
disabled: true,
icon: 'fa-recycle',
children: []
},
{
name: `worker分组管理`,
id: 4,
path: 'worker-groups-manage',
isOpen: true,
disabled: true,
icon: 'fa-address-book',
children: []
}
],
resource: [

1
escheduler-ui/src/js/module/permissions/index.js

@ -32,7 +32,6 @@ Permissions.prototype = {
this.isAuth = false
}
this.ps(res)
resolve()
})
})

Loading…
Cancel
Save