Browse Source

[feature][ui]Alert plugin design (#3734)

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* [Feature-3682][ui]Add form-create plug-in and alarm group management add sample demo (#3683)

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix

* [feature][ui] Add alarm instance page

* [feature-3665][ui]Add element-ui (#3666)

* [feature-3665][ui]Add element-ui

* add license

* Add form-create plug-in and alarm group management add sample demo

* Modify node version

* fix

* fix
pull/3/MERGE
break60 4 years ago committed by gaojun2048
parent
commit
1618b98c1c
  1. 145
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/alarmPluginExample/_source/createWarning.vue
  2. 224
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/alarmPluginExample/_source/list.vue
  3. 161
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/alarmPluginExample/index.vue
  4. 8
      dolphinscheduler-ui/src/js/conf/home/router/index.js
  5. 9
      dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js
  6. 2
      dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
  7. 2
      dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
  8. 3
      dolphinscheduler-ui/src/sass/common/_table.scss

145
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/alarmPluginExample/_source/createWarning.vue

@ -0,0 +1,145 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
<template>
<m-popup
ref="popup"
:ok-text="item ? $t('Edit') : $t('Submit')"
:nameText="item ? $t('Edit alarm group') : $t('Create alarm group')"
@ok="_ok">
<template slot="content">
<div class="create-warning-model">
<m-list-box-f>
<template slot="name"><strong>*</strong>{{$t('Group Name')}}</template>
<template slot="content">
<x-input
type="input"
v-model="groupName"
maxlength="60"
:placeholder="$t('Please enter group name')">
</x-input>
</template>
</m-list-box-f>
<m-list-box-f>
<template slot="name"><strong>*</strong>{{$t('Group Type')}}</template>
<template slot="content">
<x-select v-model="groupType">
<x-option
v-for="city in options"
:key="city.id"
:value="city.id"
:label="city.code">
</x-option>
</x-select>
</template>
</m-list-box-f>
<m-list-box-f>
<template slot="name">{{$t('Remarks')}}</template>
<template slot="content">
<x-input
type="textarea"
v-model="description"
:placeholder="$t('Please enter description')">
</x-input>
</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,
groupName: '',
groupType: 'EMAIL',
description: '',
options: [{ code: `${i18n.$t('Email')}`, id: 'EMAIL' }, { code: `${i18n.$t('SMS')}`, id: 'SMS' }]
}
},
props: {
item: Object
},
methods: {
_ok () {
if (this._verification()) {
// The name is not verified
if (this.item && this.item.groupName === this.groupName) {
this._submit()
return
}
// Verify username
this.store.dispatch(`security/verifyName`, {
type: 'alertgroup',
groupName: this.groupName
}).then(res => {
this._submit()
}).catch(e => {
this.$message.error(e.msg || '')
})
}
},
_verification () {
// group name
if (!this.groupName.replace(/\s*/g,"")) {
this.$message.warning(`${i18n.$t('Please enter group name')}`)
return false
}
return true
},
_submit () {
let param = {
groupName: this.groupName,
groupType: this.groupType,
description: this.description
}
if (this.item) {
param.id = this.item.id
}
this.$refs['popup'].spinnerLoading = true
this.store.dispatch(`security/${this.item ? 'updateAlertgrou' : 'createAlertgrou'}`, 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.groupName = this.item.groupName
this.groupType = this.item.groupType
this.description = this.item.description
}
},
mounted () {
},
components: { mPopup, mListBoxF }
}
</script>

224
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/alarmPluginExample/_source/list.vue

@ -0,0 +1,224 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
<template>
<div class="list-model">
<!-- <div class="table-box">
<table>
<tr>
<th>
<span>{{$t('#')}}</span>
</th>
<th>
<span>{{$t('Instance type')}}</span>
</th>
<th>
<span>{{$t('name')}}</span>
</th>
<th>
<span>{{$t('Create Time')}}</span>
</th>
<th>
<span>{{$t('Update Time')}}</span>
</th>
<th width="120">
<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>
{{item.groupName}}
</span>
</td>
<td><span>{{item.groupType === 'EMAIL' ? `${$t('Email')}` : `${$t('SMS')}`}}</span></td>
<td>
<span v-if="item.createTime">{{item.createTime | formatDate}}</span>
<span v-else>-</span>
</td>
<td>
<span v-if="item.updateTime">{{item.updateTime | formatDate}}</span>
<span v-else>-</span>
</td>
<td>
<x-button type="info" shape="circle" size="xsmall" data-toggle="tooltip" icon="ans-icon-user-empty" :title="$t('Managing Users')" @click="_mangeUser(item)">
</x-button>
<x-button type="info" shape="circle" size="xsmall" data-toggle="tooltip" icon="ans-icon-edit" :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="ans-icon-trash" :title="$t('delete')" :disabled="item.id==1?true: false"></x-button>
</template>
</x-poptip>
</td>
</tr>
</table>
</div> -->
<div class="table-box">
<el-table :data="list" size="mini" style="width: 100%">
<el-table-column prop="groupName" :label="$t('Instance type')" width="180"></el-table-column>
<el-table-column prop="Remarks" :label="$t('name')" width="180"></el-table-column>
<el-table-column :label="$t('Create Time')">
<template slot-scope="scope">
<span>{{scope.row.createTime | formatDate}}</span>
</template>
</el-table-column>
<el-table-column :label="$t('Update Time')">
<template slot-scope="scope">
<span>{{scope.row.updateTime | formatDate}}</span>
</template>
</el-table-column>
<el-table-column :label="$t('Operation')" width="100">
<template slot-scope="scope">
<el-tooltip :content="$t('Edit')" placement="top">
<el-button type="primary" size="mini" icon="el-icon-edit" circle></el-button>
</el-tooltip>
<el-tooltip :content="$t('delete')" placement="top">
<el-button type="danger" size="mini" icon="el-icon-delete" circle></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>
<script>
import _ from 'lodash'
import i18n from '@/module/i18n'
import { mapActions } from 'vuex'
import mTransfer from '@/module/components/transfer/transfer'
export default {
name: 'user-list',
data () {
return {
list: []
}
},
props: {
alertgroupList: Array,
pageNo: Number,
pageSize: Number
},
methods: {
...mapActions('security', ['deleteAlertgrou', 'getAuthList', 'grantAuthorization']),
_closeDelete (i) {
this.$refs[`poptip-delete-${i}`][0].doClose()
},
_delete (item, i) {
this.deleteAlertgrou({
id: item.id
}).then(res => {
this.$refs[`poptip-delete-${i}`][0].doClose()
this.$emit('on-update')
this.$message.success(res.msg)
}).catch(e => {
this.$refs[`poptip-delete-${i}`][0].doClose()
this.$message.error(e.msg || '')
})
},
_edit (item) {
this.$emit('on-edit', item)
},
_mangeUser (item, i) {
this.getAuthList({
id: item.id,
type: 'user',
category: 'users'
}).then(data => {
let sourceListPrs = _.map(data[0], v => {
return {
id: v.id,
name: v.userName
}
})
let targetListPrs = _.map(data[1], v => {
return {
id: v.id,
name: v.userName
}
})
let self = this
let modal = this.$modal.dialog({
closable: false,
showMask: true,
escClose: true,
className: 'v-modal-custom',
transitionName: 'opacityp',
render (h) {
return h(mTransfer, {
on: {
onUpdate (userIds) {
self._grantAuthorization('alert-group/grant-user', {
userIds: userIds,
alertgroupId: item.id
})
modal.remove()
},
close () {
modal.remove()
}
},
props: {
sourceListPrs: sourceListPrs,
targetListPrs: targetListPrs,
type: {
name: `${i18n.$t('Managing Users')}`
}
}
})
}
})
})
},
_grantAuthorization (api, param) {
this.grantAuthorization({
api: api,
param: param
}).then(res => {
this.$message.success(res.msg)
}).catch(e => {
this.$message.error(e.msg || '')
})
}
},
watch: {
alertgroupList (a) {
this.list = []
setTimeout(() => {
this.list = a
})
}
},
created () {
this.list = this.alertgroupList
},
mounted () {
},
components: { }
}
</script>

161
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/alarmPluginExample/index.vue

@ -0,0 +1,161 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
<template>
<m-list-construction :title="$t('Alarm plugin example')">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<!-- <template slot="button-group" v-if="isADMIN">
<x-button type="ghost" size="small" @click="_create('')">{{$t('Create alarm group')}}</x-button>
</template> -->
</m-conditions>
</template>
<template slot="content">
<template v-if="alertgroupList.length || total>0">
<m-list @on-edit="_onEdit"
@on-update="_onUpdate"
:alertgroup-list="alertgroupList"
: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" show-sizer :page-size-options="[10,30,50]" @on-size-change="_pageSize"></x-page>
</div>
</template>
<template v-if="!alertgroupList.length && total<=0">
<m-no-data></m-no-data>
</template>
<m-spin :is-spin="isLoading" :is-left="isLeft"></m-spin>
</template>
</m-list-construction>
</template>
<script>
import _ from 'lodash'
import { mapActions } from 'vuex'
import mList from './_source/list'
import store from '@/conf/home/store'
import mSpin from '@/module/components/spin/spin'
import mCreateWarning from './_source/createWarning'
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: 'warning-groups-index',
data () {
return {
total: null,
isLoading: false,
alertgroupList: [],
searchParams: {
pageSize: 10,
pageNo: 1,
searchVal: ''
},
isLeft: true,
isADMIN: store.state.user.userInfo.userType === 'ADMIN_USER'
}
},
mixins: [listUrlParamHandle],
props: {},
methods: {
...mapActions('security', ['getAlertgroupP']),
/**
* Inquire
*/
_onConditions (o) {
this.searchParams = _.assign(this.searchParams, o)
this.searchParams.pageNo = 1
},
_page (val) {
this.searchParams.pageNo = val
},
_pageSize (val) {
this.searchParams.pageSize = val
},
_onUpdate () {
this._debounceGET()
},
_onEdit (item) {
this._create(item)
},
_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(mCreateWarning, {
on: {
onUpdate () {
self._debounceGET('false')
modal.remove()
},
close () {
modal.remove()
}
},
props: {
item: item
}
})
}
})
},
_getList (flag) {
if(sessionStorage.getItem('isLeft')==0) {
this.isLeft = false
} else {
this.isLeft = true
}
this.isLoading = !flag
this.getAlertgroupP(this.searchParams).then(res => {
if(this.searchParams.pageNo>1 && res.totalList.length == 0) {
this.searchParams.pageNo = this.searchParams.pageNo -1
} else {
this.alertgroupList = []
this.alertgroupList = 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 () {
this.$modal.destroy()
},
beforeDestroy () {
sessionStorage.setItem('isLeft',1)
},
components: { mList, mListConstruction, mConditions, mSpin, mNoData }
}
</script>

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

@ -397,6 +397,14 @@ const router = new Router({
meta: {
title: `${i18n.$t('Token manage')}`
}
},
{
path: '/security/Alarm-plugin-example',
name: 'Alarm-plugin-example',
component: resolve => require(['../pages/security/pages/alarmPluginExample/index'], resolve),
meta: {
title: `${i18n.$t('Alarm plugin example')}`
}
}
]
},

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

@ -135,6 +135,15 @@ const menu = {
icon: 'ans-icon-document',
children: [],
disabled: true
},
{
name: `${i18n.$t('Alarm plugin example')}`,
id: 2,
path: 'Alarm-plugin-example',
isOpen: true,
icon: 'ans-icon-document',
children: [],
disabled: true
}
],
resource: [

2
dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js

@ -480,6 +480,7 @@ export default {
'Create worker group': 'Create worker group',
'Edit worker group': 'Edit worker group',
'Token manage': 'Token manage',
'Alarm plugin example': 'Alarm plugin example',
'Create token': 'Create token',
'Edit token': 'Edit token',
'Please enter the IP address separated by commas': 'Please enter the IP address separated by commas',
@ -645,6 +646,7 @@ export default {
'Current connection settings': 'Current connection settings',
'Please save the DAG before formatting': 'Please save the DAG before formatting',
'Batch copy': 'Batch copy',
'Instance type': 'Instance type',
'Related items': 'Related items',
'Project name is required': 'Project name is required',
'Batch move': 'Batch move',

2
dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js

@ -475,6 +475,7 @@ export default {
'Create worker group': '创建Worker分组',
'Edit worker group': '编辑Worker分组',
'Token manage': '令牌管理',
'Alarm plugin example': '告警插件实例',
'Create token': '创建令牌',
'Edit token': '编辑令牌',
'Please enter the IP address separated by commas': '请输入IP地址多个用英文逗号隔开',
@ -645,6 +646,7 @@ export default {
'Current connection settings': '当前连线设置',
'Please save the DAG before formatting': '格式化前请先保存DAG',
'Batch copy': '批量复制',
'Instance type': '实例类型',
'Related items': '关联项目',
'Project name is required': '项目名称必填',
'Batch move': '批量移动',

3
dolphinscheduler-ui/src/sass/common/_table.scss

@ -171,3 +171,6 @@
}
}
}
.el-table--enable-row-hover .el-table__body tr:hover>td {
background-color: #ddecff;
}

Loading…
Cancel
Save