Browse Source

[Feature-#3826][UI]Alert SPI (#4441)

* [Improvement-3878]Tenant list delete user name

* [Improvement-3878][ui]Fix the list style

* [Improvement][ui] List vacancy optimization and icon icon repair

* Add font-awesome license and delete ans-ui license

* Introduce remixicon

* Plug-in front-end function


* optimization
pull/3/MERGE
break60 3 years ago committed by GitHub
parent
commit
500147fa7e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 21
      dolphinscheduler-dist/release-docs/licenses/ui-licenses/LICENSE-@form-create-element-ui
  2. 1
      dolphinscheduler-ui/package.json
  3. 2
      dolphinscheduler-ui/src/js/conf/home/index.js
  4. 55
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/sql.vue
  5. 1
      dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/sqoop.vue
  6. 27
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/list.vue
  7. 31
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/start.vue
  8. 26
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/timing.vue
  9. 27
      dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/timing/_source/list.vue
  10. 32
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/createWarning.vue
  11. 55
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/list.vue
  12. 14
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/index.vue
  13. 197
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/_source/createWarningInstance.vue
  14. 107
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/_source/list.vue
  15. 169
      dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/index.vue
  16. 11
      dolphinscheduler-ui/src/js/conf/home/router/index.js
  17. 94
      dolphinscheduler-ui/src/js/conf/home/store/security/actions.js
  18. 9
      dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js
  19. 9
      dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
  20. 6
      dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js

21
dolphinscheduler-dist/release-docs/licenses/ui-licenses/LICENSE-@form-create-element-ui vendored

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018 xaboy
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

1
dolphinscheduler-ui/package.json

@ -13,6 +13,7 @@
"build:release": "npm run clean && cross-env NODE_ENV=production PUBLIC_PATH=/dolphinscheduler/ui webpack --config ./build/webpack.config.release.js"
},
"dependencies": {
"@form-create/element-ui": "^1.0.18",
"@riophae/vue-treeselect": "^0.4.0",
"axios": "^0.16.2",
"bootstrap": "3.3.7",

2
dolphinscheduler-ui/src/js/conf/home/index.js

@ -38,6 +38,7 @@ import 'bootstrap/dist/css/bootstrap.min.css'
import 'bootstrap/dist/js/bootstrap.min.js'
import 'canvg/dist/browser/canvg.min.js'
import 'remixicon/fonts/remixicon.css'
import formCreate from '@form-create/element-ui'
// Component internationalization
const useOpt = i18n.globalScope.LOCALE === 'en_US' ? { locale: locale } : {}
@ -46,6 +47,7 @@ i18n.globalScope.LOCALE === 'en_US' ? Vue.use(ElementUI, { locale }) : Vue.use(E
// Vue.use(ans)
Vue.use(useOpt)
Vue.use(formCreate)
sync(store, router)

55
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/sql.vue

@ -55,18 +55,6 @@
</el-input>
</div>
</m-list-box>
<m-list-box>
<div slot="text"><strong class='requiredIcon'>*</strong>{{$t('Recipient')}}</div>
<div slot="content">
<m-email ref="refEmail" v-model="receivers" :disabled="isDetails" :repeat-data="receiversCc"></m-email>
</div>
</m-list-box>
<m-list-box>
<div slot="text">{{$t('Cc')}}</div>
<div slot="content">
<m-email ref="refCc" v-model="receiversCc" :disabled="isDetails" :repeat-data="receivers"></m-email>
</div>
</m-list-box>
</template>
<m-list-box v-show="type === 'HIVE'">
<div slot="text">{{$t('SQL Parameter')}}</div>
@ -155,7 +143,6 @@
import mLocalParams from './_source/localParams'
import mStatementList from './_source/statementList'
import disabledState from '@/module/mixin/disabledState'
import mEmail from '@/conf/home/pages/projects/pages/definition/pages/list/_source/email'
import codemirror from '@/conf/home/pages/resource/pages/file/pages/_source/codemirror'
let editor
@ -188,10 +175,6 @@
preStatements: [],
// Post statements
postStatements: [],
// recipients
receivers: [],
// copy to
receiversCc: [],
item: '',
scriptBoxDialog: false
}
@ -274,14 +257,6 @@
this.$message.warning(`${i18n.$t('Recipient required')}`)
return false
}
// receivers Subcomponent verification
if (this.sqlType === 0 && !this.$refs.refEmail._manualEmail()) {
return false
}
// receiversCc Subcomponent verification
if (this.sqlType === 0 && !this.$refs.refCc._manualEmail()) {
return false
}
// udfs Subcomponent verification Verification only if the data type is HIVE
if (this.type === 'HIVE') {
if (!this.$refs.refUdfs._verifUdfs()) {
@ -312,8 +287,6 @@
udfs: this.udfs,
sqlType: this.sqlType,
title: this.title,
receivers: this.receivers.join(','),
receiversCc: this.receiversCc.join(','),
showType: (() => {
/**
* Special processing return order TABLE,ATTACHMENT
@ -366,19 +339,6 @@
return editor
},
_getReceiver () {
let param = {}
let current = this.router.history.current
if (current.name === 'projects-definition-details') {
param.processDefinitionId = current.params.id
} else {
param.processInstanceId = current.params.id
}
this.store.dispatch('dag/getReceiver', param).then(res => {
this.receivers = res.receivers && res.receivers.split(',') || []
this.receiversCc = res.receiversCc && res.receiversCc.split(',') || []
})
},
_cacheParams () {
this.$emit('on-cache-params', {
type: this.type,
@ -387,8 +347,6 @@
udfs: this.udfs,
sqlType: this.sqlType,
title: this.title,
receivers: this.receivers.join(','),
receiversCc: this.receiversCc.join(','),
showType: (() => {
let showType = this.showType
if (showType.length === 2 && showType[0] === 'ATTACHMENT') {
@ -419,8 +377,6 @@
}
if (val !== 0) {
this.title = ''
this.receivers = []
this.receiversCc = []
}
},
// Listening data source
@ -455,13 +411,6 @@
this.preStatements = o.params.preStatements || []
this.postStatements = o.params.postStatements || []
this.title = o.params.title || ''
this.receivers = o.params.receivers && o.params.receivers.split(',') || []
this.receiversCc = o.params.receiversCc && o.params.receiversCc.split(',') || []
}
// read tasks from cache
if (!_.some(this.store.state.dag.cacheTasks, { id: this.createNodeId }) &&
this.router.history.current.name !== 'definition-create') {
this._getReceiver()
}
},
mounted () {
@ -487,8 +436,6 @@
udfs: this.udfs,
sqlType: this.sqlType,
title: this.title,
receivers: this.receivers.join(','),
receiversCc: this.receiversCc.join(','),
showType: (() => {
let showType = this.showType
if (showType.length === 2 && showType[0] === 'ATTACHMENT') {
@ -504,6 +451,6 @@
}
}
},
components: { mListBox, mDatasource, mLocalParams, mUdfs, mSqlType, mStatementList, mEmail, mScriptBox }
components: { mListBox, mDatasource, mLocalParams, mUdfs, mSqlType, mStatementList, mScriptBox }
}
</script>

1
dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/sqoop.vue

@ -1175,7 +1175,6 @@
}
if (val !== 0) {
this.title = ''
this.receivers = []
}
},
// Listening data source

27
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/list.vue

@ -177,8 +177,6 @@
timingDialog: false,
timingData: {
item: {},
receiversD: [],
receiversCcD: [],
type: ''
},
relatedItemsDialog: false,
@ -191,7 +189,7 @@
pageSize: Number
},
methods: {
...mapActions('dag', ['editProcessState', 'getStartCheck', 'getReceiver', 'deleteDefinition', 'batchDeleteDefinition', 'exportDefinition', 'getProcessDefinitionVersionsPage', 'copyProcess', 'switchProcessDefinitionVersion', 'deleteProcessDefinitionVersion', 'moveProcess']),
...mapActions('dag', ['editProcessState', 'getStartCheck', 'deleteDefinition', 'batchDeleteDefinition', 'exportDefinition', 'getProcessDefinitionVersionsPage', 'copyProcess', 'switchProcessDefinitionVersion', 'deleteProcessDefinitionVersion', 'moveProcess']),
...mapActions('security', ['getWorkerGroupsAll']),
selectable (row, index) {
@ -226,30 +224,13 @@
closeStart () {
this.startDialog = false
},
/**
* get emial
*/
_getReceiver (id) {
return new Promise((resolve, reject) => {
this.getReceiver({ processDefinitionId: id }).then(res => {
resolve({
receivers: res.receivers && res.receivers.split(',') || [],
receiversCc: res.receiversCc && res.receiversCc.split(',') || []
})
})
})
},
/**
* timing
*/
_timing (item) {
this._getReceiver(item.id).then(res => {
this.timingData.item = item
this.timingData.receiversD = res.receivers
this.timingData.receiversCcD = res.receiversCc
this.timingData.type = 'timing'
this.timingDialog = true
})
this.timingData.item = item
this.timingData.type = 'timing'
this.timingDialog = true
},
onUpdateTiming () {
this._onUpdate()

31
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/start.vue

@ -99,22 +99,6 @@
</el-select>
</div>
</div>
<div class="clearfix list">
<div class="text">
{{$t('Recipient')}}
</div>
<div class="cont" style="width: 688px;">
<m-email v-model="receivers" :repeat-data="receiversCc"></m-email>
</div>
</div>
<div class="clearfix list">
<div class="text">
{{$t('Cc')}}
</div>
<div class="cont" style="width: 688px;">
<m-email v-model="receiversCc" :repeat-data="receivers"></m-email>
</div>
</div>
<div class="clearfix list">
<div class="text">
{{$t('Complement Data')}}
@ -181,7 +165,6 @@
<script>
import _ from 'lodash'
import dayjs from 'dayjs'
import mEmail from './email.vue'
import store from '@/conf/home/store'
import { warningTypeList } from './util'
import mPriority from '@/module/components/priority/priority'
@ -206,8 +189,6 @@
spinnerLoading: false,
execType: false,
taskDependType: 'TASK_POST',
receivers: [],
receiversCc: [],
runMode: 'RUN_MODE_SERIAL',
processInstancePriority: 'MEDIUM',
workerGroup: 'default',
@ -252,8 +233,6 @@
taskDependType: this.taskDependType,
runMode: this.runMode,
processInstancePriority: this.processInstancePriority,
receivers: this.receivers.join(',') || '',
receiversCc: this.receiversCc.join(',') || '',
workerGroup: this.workerGroup,
startParams: !_.isEmpty(startParams) ? JSON.stringify(startParams) : ''
}
@ -283,12 +262,6 @@
})
})
},
_getReceiver () {
this.store.dispatch('dag/getReceiver', { processDefinitionId: this.startData.id }).then(res => {
this.receivers = res.receivers && res.receivers.split(',') || []
this.receiversCc = res.receiversCc && res.receiversCc.split(',') || []
})
},
_getGlobalParams () {
this.setIsDetails(true)
this.store.dispatch('dag/getProcessDetails', this.startData.id).then(res => {
@ -311,8 +284,6 @@
created () {
this.warningType = this.warningTypeList[0].id
this.workflowName = this.startData.name
this._getReceiver()
this._getGlobalParams()
let stateWorkerGroupsList = this.store.state.security.workerGroupsListAll || []
if (stateWorkerGroupsList.length) {
@ -336,7 +307,7 @@
this.workflowName = this.startData.name
},
computed: {},
components: { mEmail, mPriority, mWorkerGroups, mLocalParams }
components: { mPriority, mWorkerGroups, mLocalParams }
}
</script>

26
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/timing.vue

@ -136,22 +136,6 @@
</el-select>
</div>
</div>
<div class="clearfix list">
<div class="text">
{{$t('Recipient')}}
</div>
<div class="cont" style="width: 680px;">
<m-email v-model="receivers" :repeat-data="receiversCc"></m-email>
</div>
</div>
<div class="clearfix list">
<div class="text">
{{$t('Cc')}}
</div>
<div class="cont" style="width: 680px;">
<m-email v-model="receiversCc" :repeat-data="receivers"></m-email>
</div>
</div>
<div class="submit">
<el-button type="text" size="small" @click="close()"> {{$t('Cancel')}} </el-button>
<el-button type="primary" size="small" round :loading="spinnerLoading" @click="ok()">{{spinnerLoading ? 'Loading...' : (timingData.item.crontab ? $t('Edit') : $t('Create'))}} </el-button>
@ -159,9 +143,7 @@
</div>
</template>
<script>
import _ from 'lodash'
import i18n from '@/module/i18n'
import mEmail from './email.vue'
import store from '@/conf/home/store'
import { warningTypeList } from './util'
import { vCrontab } from '@/module/components/crontab/index'
@ -184,8 +166,6 @@
scheduleTime: '',
crontab: '0 0 * * * ? *',
cronPopover: false,
receivers: [],
receiversCc: [],
i18n: i18n.globalScope.LOCALE,
processInstancePriority: 'MEDIUM',
workerGroup: '',
@ -229,8 +209,6 @@
warningType: this.warningType,
processInstancePriority: this.processInstancePriority,
warningGroupId: this.warningGroupId === '' ? 0 : this.warningGroupId,
receivers: this.receivers.join(',') || '',
receiversCc: this.receiversCc.join(',') || '',
workerGroup: this.workerGroup
}
let msg = ''
@ -337,8 +315,6 @@
this.crontab = '0 0 * * * ? *'
this.scheduleTime = times
}
this.receivers = _.cloneDeep(this.timingData.receiversD)
this.receiversCc = _.cloneDeep(this.timingData.receiversCcD)
},
mounted () {
let item = this.timingData.item
@ -363,7 +339,7 @@
}).catch(() => { this.warningGroupId = '' })
}
},
components: { vCrontab, mEmail, mPriority, mWorkerGroups }
components: { vCrontab, mPriority, mWorkerGroups }
}
</script>

27
dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/timing/_source/list.vue

@ -124,16 +124,14 @@
list: [],
timingDialog: false,
timingData: {
item: {},
receiversD: [],
receiversCcD: []
item: {}
}
}
},
props: {
},
methods: {
...mapActions('dag', ['getScheduleList', 'scheduleOffline', 'scheduleOnline', 'getReceiver', 'deleteTiming']),
...mapActions('dag', ['getScheduleList', 'scheduleOffline', 'scheduleOnline', 'deleteTiming']),
/**
* delete
*/
@ -228,29 +226,12 @@
this.$message.error(e.msg || '')
})
},
/**
* get email
*/
_getReceiver (id) {
return new Promise((resolve, reject) => {
this.getReceiver({ processDefinitionId: id }).then(res => {
resolve({
receivers: res.receivers && res.receivers.split(',') || [],
receiversCc: res.receiversCc && res.receiversCc.split(',') || []
})
})
})
},
/**
* timing
*/
_editTiming (item) {
this._getReceiver(item.processDefinitionId).then(res => {
this.timingData.item = item
this.timingData.receiversD = res.receivers
this.timingData.receiversCcD = res.receiversCc
this.timingDialog = true
})
this.timingData.item = item
this.timingDialog = true
},
onUpdateTiming () {
this.pageNo = 1

32
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/createWarning.vue

@ -36,14 +36,14 @@
</template>
</m-list-box-f>
<m-list-box-f>
<template slot="name"><strong>*</strong>{{$t('Group Type')}}</template>
<template slot="name"><strong>*</strong>{{$t('Alarm plugin instance')}}</template>
<template slot="content">
<el-select v-model="groupType" size="small">
<el-select v-model="alertInstanceIds" size="small" style="width: 100%" multiple>
<el-option
v-for="city in options"
:key="city.id"
:value="city.id"
:label="city.code">
v-for="items in allAlertPluginInstance"
:key="items.id"
:value="items.id"
:label="items.instanceName">
</el-option>
</el-select>
</template>
@ -64,6 +64,7 @@
</m-popup>
</template>
<script>
import _ from 'lodash'
import i18n from '@/module/i18n'
import store from '@/conf/home/store'
import mPopup from '@/module/components/popup/popup'
@ -75,13 +76,13 @@
return {
store,
groupName: '',
groupType: 'EMAIL',
description: '',
options: [{ code: `${i18n.$t('Email')}`, id: 'EMAIL' }, { code: `${i18n.$t('SMS')}`, id: 'SMS' }]
alertInstanceIds: [],
description: ''
}
},
props: {
item: Object
item: Object,
allAlertPluginInstance: Array
},
methods: {
_ok () {
@ -114,7 +115,7 @@
_submit () {
let param = {
groupName: this.groupName,
groupType: this.groupType,
alertInstanceIds: this.alertInstanceIds.join(','),
description: this.description
}
if (this.item) {
@ -124,9 +125,7 @@
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)
this.$refs.popup.spinnerLoading = false
}).catch(e => {
this.$message.error(e.msg || '')
this.$refs.popup.spinnerLoading = false
@ -140,7 +139,10 @@
created () {
if (this.item) {
this.groupName = this.item.groupName
this.groupType = this.item.groupType
let dataStrArr = this.item.alertInstanceIds.split(',')
this.alertInstanceIds = _.map(dataStrArr, v => {
return +v
})
this.description = this.item.description
}
},

55
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/list.vue

@ -20,11 +20,6 @@
<el-table :data="list" size="mini" style="width: 100%">
<el-table-column type="index" :label="$t('#')" width="50"></el-table-column>
<el-table-column prop="groupName" :label="$t('Group Name')"></el-table-column>
<el-table-column :label="$t('Group Type')" width="100">
<template slot-scope="scope">
{{scope.row.groupType === 'EMAIL' ? `${$t('Email')}` : `${$t('SMS')}`}}
</template>
</el-table-column>
<el-table-column prop="description" :label="$t('Remarks')" width="200"></el-table-column>
<el-table-column :label="$t('Create Time')" width="140">
<template slot-scope="scope">
@ -38,9 +33,6 @@
</el-table-column>
<el-table-column :label="$t('Operation')" width="130">
<template slot-scope="scope">
<el-tooltip :content="$t('Managing Users')" placement="top">
<el-button type="primary" size="mini" icon="el-icon-user" @click="_mangeUser(scope.row, scope.$index)" circle></el-button>
</el-tooltip>
<el-tooltip :content="$t('Edit')" placement="top">
<span><el-button type="primary" size="mini" icon="el-icon-edit-outline" @click="_edit(scope.row)" circle></el-button></span>
</el-tooltip>
@ -53,25 +45,17 @@
:title="$t('Delete?')"
@onConfirm="_delete(scope.row,scope.row.id)"
>
<el-button type="danger" size="mini" icon="el-icon-delete" circle slot="reference" :disabled="scope.row.id==1?true: false"></el-button>
<el-button type="danger" size="mini" icon="el-icon-delete" circle slot="reference"></el-button>
</el-popconfirm>
</el-tooltip>
</template>
</el-table-column>
</el-table>
</div>
<el-dialog
:visible.sync="transferDialog"
width="auto">
<m-transfer :transferData="transferData" @onUpdate="onUpdate" @close="close"></m-transfer>
</el-dialog>
</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',
@ -79,14 +63,7 @@
return {
list: [],
transferDialog: false,
item: {},
transferData: {
sourceListPrs: [],
targetListPrs: [],
type: {
name: `${i18n.$t('Managing Users')}`
}
}
item: {}
}
},
props: {
@ -95,7 +72,7 @@
pageSize: Number
},
methods: {
...mapActions('security', ['deleteAlertgrou', 'getAuthList', 'grantAuthorization']),
...mapActions('security', ['deleteAlertgrou', 'grantAuthorization']),
_delete (item, i) {
this.deleteAlertgrou({
id: item.id
@ -109,30 +86,6 @@
_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
}
})
this.item = item
this.transferData.sourceListPrs = sourceListPrs
this.transferData.targetListPrs = targetListPrs
this.transferDialog = true
})
},
onUpdate (userIds) {
this._grantAuthorization('alert-group/grant-user', {
userIds: userIds,
@ -168,6 +121,6 @@
},
mounted () {
},
components: { mTransfer }
components: {}
}
</script>

14
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/index.vue

@ -23,7 +23,7 @@
<el-dialog
:visible.sync="createWarningDialog"
width="auto">
<m-create-warning :item="item" @onUpdate="onUpdate" @close="close"></m-create-warning>
<m-create-warning :item="item" :allAlertPluginInstance="allAlertPluginInstance" @onUpdate="onUpdate" @close="close"></m-create-warning>
</el-dialog>
</template>
</m-conditions>
@ -83,13 +83,14 @@
isLeft: true,
isADMIN: store.state.user.userInfo.userType === 'ADMIN_USER',
createWarningDialog: false,
item: {}
item: {},
allAlertPluginInstance: []
}
},
mixins: [listUrlParamHandle],
props: {},
methods: {
...mapActions('security', ['getAlertgroupP']),
...mapActions('security', ['queryAlertGroupListPaging', 'queryAllAlertPluginInstance']),
/**
* Inquire
*/
@ -110,6 +111,11 @@
this._create(item)
},
_create (item) {
this.queryAllAlertPluginInstance().then(res => {
this.allAlertPluginInstance = res
}).catch(e => {
this.$message.error(e.msg)
})
this.item = item
this.createWarningDialog = true
},
@ -130,7 +136,7 @@
this.isLeft = true
}
this.isLoading = !flag
this.getAlertgroupP(this.searchParams).then(res => {
this.queryAlertGroupListPaging(this.searchParams).then(res => {
if (this.searchParams.pageNo > 1 && res.totalList.length === 0) {
this.searchParams.pageNo = this.searchParams.pageNo - 1
} else {

197
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/_source/createWarningInstance.vue

@ -0,0 +1,197 @@
/*
* 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 Instance') : $t('Create Alarm Instance')"
@ok="_ok"
@close="close">
<template slot="content">
<div class="create-warning-model">
<m-list-box-f>
<template slot="name"><strong>*</strong>{{$t('Alarm instance name')}}</template>
<template slot="content">
<el-input
type="input"
v-model="instanceName"
maxlength="60"
size="small"
:placeholder="$t('Please enter group name')">
</el-input>
</template>
</m-list-box-f>
<m-list-box-f>
<template slot="name"><strong>*</strong>{{$t('Select plugin')}}</template>
<template slot="content">
<el-select v-model="pluginDefineId" size="small" style="width: 100%" @change="changePlugin" disabled="true" v-if="item.id">
<el-option
v-for="items in pulginInstance"
:key="items.id"
:value="items.id"
:label="items.pluginName">
</el-option>
</el-select>
<el-select v-model="pluginDefineId" size="small" style="width: 100%" @change="changePlugin" v-else>
<el-option
v-for="items in pulginInstance"
:key="items.id"
:value="items.id"
:label="items.pluginName">
</el-option>
</el-select>
</template>
</m-list-box-f>
<div>
<template>
<div class="alertForm"><form-create v-model="$f" :rule="rule" :option="{submitBtn:false}" size="mini"></form-create></div>
</template>
</div>
</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,
instanceName: '',
pluginDefineId: null,
$f: {},
rule: []
}
},
props: {
item: Object,
pulginInstance: Array
},
methods: {
_ok () {
if (this._verification()) {
// The name is not verified
if (this.item && this.item.instanceName === this.instanceName) {
this._submit()
return
}
// Verify username
this.store.dispatch('security/verifyName', {
type: 'alarmInstance',
instanceName: this.instanceName
}).then(res => {
this._submit()
}).catch(e => {
this.$message.error(e.msg || '')
})
}
},
_verification () {
// group name
if (!this.instanceName.replace(/\s*/g, '')) {
this.$message.warning(`${i18n.$t('Please enter group name')}`)
return false
}
return true
},
// Select plugin
changePlugin () {
this.store.dispatch('security/getUiPluginById', {
pluginId: this.pluginDefineId
}).then(res => {
this.rule = JSON.parse(res.pluginParams)
this.rule.forEach(item => {
if (item.title.indexOf('$t') !== -1) {
item.title = $t(item.field)
}
})
}).catch(e => {
this.$message.error(e.msg || '')
})
},
_submit () {
this.$f.rule.forEach(item => {
item.title = item.name
})
let param = {
instanceName: this.instanceName,
pluginDefineId: this.pluginDefineId,
pluginInstanceParams: JSON.stringify(this.$f.rule)
}
if (this.item) {
param.alertPluginInstanceId = this.item.id
param.pluginDefineId = null
}
this.$refs.popup.spinnerLoading = true
this.store.dispatch(`security/${this.item ? 'updateAlertPluginInstance' : 'createAlertPluginInstance'}`, 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
})
},
close () {
this.$emit('close')
}
},
watch: {},
created () {
let pluginInstanceParams = []
if (this.item) {
this.instanceName = this.item.instanceName
this.pluginDefineId = this.item.pluginDefineId
JSON.parse(this.item.pluginInstanceParams).forEach(item => {
if (item.title.indexOf('$t') !== -1) {
item.title = $t(item.field)
}
pluginInstanceParams.push(item)
})
this.rule = pluginInstanceParams
}
},
mounted () {
},
components: { mPopup, mListBoxF }
}
</script>
<style lang="scss" rel="stylesheet/scss">
.alertForm {
label {
span {
font-weight: 10!important;
}
}
.el-form-item__label {
width: 144px!important;
color: #606266!important;
}
.el-form-item__content {
margin-left: 144px!important;
width: calc(100% - 162px);
}
}
</style>

107
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/_source/list.vue

@ -0,0 +1,107 @@
/*
* 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">
<el-table :data="list" size="mini" style="width: 100%">
<el-table-column type="index" :label="$t('#')" width="50"></el-table-column>
<el-table-column prop="instanceName" :label="$t('Alarm instance name')"></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="130">
<template slot-scope="scope">
<el-tooltip :content="$t('Edit')" placement="top">
<span><el-button type="primary" size="mini" icon="el-icon-edit-outline" @click="_edit(scope.row)" circle></el-button></span>
</el-tooltip>
<el-tooltip :content="$t('delete')" placement="top">
<el-popconfirm
:confirmButtonText="$t('Confirm')"
:cancelButtonText="$t('Cancel')"
icon="el-icon-info"
iconColor="red"
:title="$t('Delete?')"
@onConfirm="_delete(scope.row,scope.row.id)"
>
<el-button type="danger" size="mini" icon="el-icon-delete" circle slot="reference"></el-button>
</el-popconfirm>
</el-tooltip>
</template>
</el-table-column>
</el-table>
</div>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
name: 'user-list',
data () {
return {
list: [],
transferDialog: false,
item: {}
}
},
props: {
alertgroupList: Array,
pageNo: Number,
pageSize: Number
},
methods: {
...mapActions('security', ['deletAelertPluginInstance']),
_delete (item, i) {
this.deletAelertPluginInstance({
id: item.id
}).then(res => {
this.$emit('on-update')
this.$message.success(res.msg)
}).catch(e => {
this.$message.error(e.msg || '')
})
},
_edit (item) {
this.$emit('on-edit', item)
},
close () {
this.transferDialog = false
}
},
watch: {
alertgroupList (a) {
this.list = []
setTimeout(() => {
this.list = a
})
}
},
created () {
this.list = this.alertgroupList
},
mounted () {
},
components: {}
}
</script>

169
dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/index.vue

@ -0,0 +1,169 @@
/*
* 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('Warning instance manage')">
<template slot="conditions">
<m-conditions @on-conditions="_onConditions">
<template slot="button-group" v-if="isADMIN">
<el-button size="mini" @click="_create('')">{{$t('Create Alarm Instance')}}</el-button>
<el-dialog
:visible.sync="createWarningDialog"
width="45%">
<m-create-warning-instance :item="item" :pulginInstance="pulginInstance" @onUpdate="onUpdate" @close="close"></m-create-warning-instance>
</el-dialog>
</template>
</m-conditions>
</template>
<template slot="content">
<template v-if="alertgroupList!==null || 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">
<el-pagination
background
@current-change="_page"
@size-change="_pageSize"
:page-size="searchParams.pageSize"
:current-page.sync="searchParams.pageNo"
:page-sizes="[10, 30, 50]"
layout="sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</template>
<template v-if="alertgroupList===null && 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 mCreateWarningInstance from './_source/createWarningInstance'
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-instance-index',
data () {
return {
total: null,
isLoading: false,
alertgroupList: [],
searchParams: {
pageSize: 10,
pageNo: 1,
searchVal: ''
},
isLeft: true,
isADMIN: store.state.user.userInfo.userType === 'ADMIN_USER',
createWarningDialog: false,
item: {},
pulginInstance: []
}
},
mixins: [listUrlParamHandle],
props: {},
methods: {
...mapActions('security', ['queryAlertPluginInstanceListPaging', 'getPlugins']),
/**
* 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) {
this.getPlugins({ pluginType: 'ALERT' }).then(res => {
this.pulginInstance = res
}).catch(e => {
this.$message.error(e.msg)
})
this.item = item
this.createWarningDialog = true
},
onUpdate () {
this._debounceGET('false')
this.createWarningDialog = false
},
close () {
this.createWarningDialog = false
},
_getList (flag) {
if (sessionStorage.getItem('isLeft') === 0) {
this.isLeft = false
} else {
this.isLeft = true
}
this.isLoading = !flag
this.queryAlertPluginInstanceListPaging(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 () {
},
beforeDestroy () {
sessionStorage.setItem('isLeft', 1)
},
components: { mList, mListConstruction, mConditions, mSpin, mNoData, mCreateWarningInstance }
}
</script>

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

@ -387,7 +387,8 @@ const router = new Router({
name: 'users-manage',
component: resolve => require(['../pages/security/pages/users/index'], resolve),
meta: {
title: `${i18n.$t('User Manage')}`
title: `${i18n.$t('User Manage')}`,
refresh_in_switched_tab: false
}
},
{
@ -398,6 +399,14 @@ const router = new Router({
title: `${i18n.$t('Warning group manage')}`
}
},
{
path: '/security/warning-instance',
name: 'warning-instance-manage',
component: resolve => require(['../pages/security/pages/warningInstance/index'], resolve),
meta: {
title: `${i18n.$t('Warning instance manage')}`
}
},
{
path: '/security/queue',
name: 'queue-manage',

94
dolphinscheduler-ui/src/js/conf/home/store/security/actions.js

@ -43,6 +43,12 @@ export default {
groupName: payload.groupName
},
api: 'alert-group/verify-group-name'
},
alarmInstance: {
param: {
alertInstanceName: payload.instanceName
},
api: 'alert-plugin-instance/verify-alert-instance-name'
}
}
@ -340,9 +346,9 @@ export default {
})
},
/**
* Paging query alarm group list
* queryAlertGroupListPaging
*/
getAlertgroupP ({ state }, payload) {
queryAlertGroupListPaging ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get('alert-group/list-paging', payload, res => {
resolve(res.data)
@ -351,6 +357,54 @@ export default {
})
})
},
/**
* queryAlertPluginInstanceListPaging
*/
queryAlertPluginInstanceListPaging ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get('alert-plugin-instance/list-paging', payload, res => {
resolve(res.data)
}).catch(e => {
reject(e)
})
})
},
/**
* queryUiPlugins
*/
getPlugins ({ state }, payload) {
return new Promise((resolve, reject) => {
io.post('ui-plugins/queryUiPluginsByType', payload, res => {
resolve(res.data)
}).catch(e => {
reject(e)
})
})
},
/**
* queryUiPluginById
*/
getUiPluginById ({ state }, payload) {
return new Promise((resolve, reject) => {
io.post('ui-plugins/queryUiPluginDetailById', payload, res => {
resolve(res.data)
}).catch(e => {
reject(e)
})
})
},
/**
* queryAll alert-plugin-instance
*/
queryAllAlertPluginInstance ({ state }, payload) {
return new Promise((resolve, reject) => {
io.post('alert-plugin-instance/queryAll', payload, res => {
resolve(res.data)
}).catch(e => {
reject(e)
})
})
},
/**
* Alarm group list
*/
@ -375,6 +429,30 @@ export default {
})
})
},
/**
* create alert plugin instance operation
*/
createAlertPluginInstance ({ state }, payload) {
return new Promise((resolve, reject) => {
io.post('alert-plugin-instance/create', payload, res => {
resolve(res)
}).catch(e => {
reject(e)
})
})
},
/**
* update alert plugin instance operation
*/
updateAlertPluginInstance ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get('alert-plugin-instance/update', payload, res => {
resolve(res)
}).catch(e => {
reject(e)
})
})
},
/**
* update an alarm group.
*/
@ -399,6 +477,18 @@ export default {
})
})
},
/**
* delete alert plugin instance operation
*/
deletAelertPluginInstance ({ state }, payload) {
return new Promise((resolve, reject) => {
io.get('alert-plugin-instance/delete', payload, res => {
resolve(res)
}).catch(e => {
reject(e)
})
})
},
/**
* Master list
*/

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

@ -109,6 +109,15 @@ const menu = {
icon: 'el-icon-warning',
children: []
},
{
name: `${i18n.$t('Warning instance manage')}`,
id: 2,
path: 'warning-instance-manage',
isOpen: true,
enabled: true,
icon: 'ri-spam-fill',
children: []
},
{
name: `${i18n.$t('Worker group manage')}`,
id: 4,

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

@ -184,15 +184,14 @@ export default {
'Last heartbeat time': 'Last heartbeat time',
'Edit Tenant': 'Edit Tenant',
'OS Tenant Code': 'OS Tenant Code',
Queue: 'Yarn Queue',
'Tenant Name': 'Tenant Name',
Queue: 'Yarn Queue',
'Please select a queue': 'default is tenant association queue',
'Please enter the os tenant code in English': 'Please enter the os tenant code in English',
'Please enter os tenant code in English': 'Please enter os tenant code in English',
'Please enter os tenant code': 'Please enter os tenant code',
'Please enter tenant Name': 'Please enter tenant Name',
'The os tenant code. Only letters or a combination of letters and numbers are allowed': 'The os tenant code. Only letters or a combination of letters and numbers are allowed',
'The os tenant code cannot be all numbers': 'The os tenant code cannot be all numbers',
'Edit User': 'Edit User',
Tenant: 'Tenant',
Email: 'Email',
@ -210,9 +209,14 @@ export default {
'Please select UDF resources directory': 'Please select UDF resources directory',
'Edit alarm group': 'Edit alarm group',
'Create alarm group': 'Create alarm group',
'Create Alarm Instance': 'Create Alarm Instance',
'Edit Alarm Instance': 'Edit Alarm Instance',
'Group Name': 'Group Name',
'Alarm instance name': 'Alarm instance name',
'Select plugin': 'Select plugin',
'Please enter group name': 'Please enter group name',
'Group Type': 'Group Type',
'Alarm plugin instance': 'Alarm plugin instance',
Remarks: 'Remarks',
SMS: 'SMS',
'Managing Users': 'Managing Users',
@ -370,6 +374,7 @@ export default {
'Process definition': 'Process definition',
'Task record': 'Task record',
'Warning group manage': 'Warning group manage',
'Warning instance manage': 'Warning instance manage',
'Servers manage': 'Servers manage',
'UDF manage': 'UDF manage',
'Resource manage': 'Resource manage',

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

@ -209,9 +209,14 @@ export default {
'Please select UDF resources directory': '请选择UDF资源目录',
'Edit alarm group': '编辑告警组',
'Create alarm group': '创建告警组',
'Create Alarm Instance': '创建告警实例',
'Edit Alarm Instance': '编辑告警实例',
'Group Name': '组名称',
'Alarm instance name': '告警实例名称',
'Select plugin': '选择插件',
'Please enter group name': '请输入组名称',
'Group Type': '组类型',
'Alarm plugin instance': '告警插件实例',
Remarks: '备注',
SMS: '短信',
'Managing Users': '管理用户',
@ -369,6 +374,7 @@ export default {
'Process definition': '工作流定义',
'Task record': '任务记录',
'Warning group manage': '告警组管理',
'Warning instance manage': '告警实例管理',
'Servers manage': '服务管理',
'UDF manage': 'UDF管理',
'Resource manage': '资源管理',

Loading…
Cancel
Save