You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by ga...@apache.org on 2020/10/12 07:32:01 UTC

[incubator-dolphinscheduler] 06/07: [feature][ui]Alert plugin design (#3734)

This is an automated email from the ASF dual-hosted git repository.

gaojun2048 pushed a commit to branch alert_plugin_design
in repository https://gitbox.apache.org/repos/asf/incubator-dolphinscheduler.git

commit 1618b98c1c2c6615dbcf4ccee15cf0cb66ad51ac
Author: break60 <79...@qq.com>
AuthorDate: Tue Sep 22 17:43:55 2020 +0800

    [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
---
 .../alarmPluginExample/_source/createWarning.vue   | 145 +++++++++++++
 .../pages/alarmPluginExample/_source/list.vue      | 224 +++++++++++++++++++++
 .../security/pages/alarmPluginExample/index.vue    | 161 +++++++++++++++
 .../src/js/conf/home/router/index.js               |   8 +
 .../components/secondaryMenu/_source/menu.js       |   9 +
 .../src/js/module/i18n/locale/en_US.js             |   2 +
 .../src/js/module/i18n/locale/zh_CN.js             |   2 +
 dolphinscheduler-ui/src/sass/common/_table.scss    |   3 +
 8 files changed, 554 insertions(+)

diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/alarmPluginExample/_source/createWarning.vue b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/alarmPluginExample/_source/createWarning.vue
new file mode 100644
index 0000000..28d53c5
--- /dev/null
+++ b/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>
\ No newline at end of file
diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/alarmPluginExample/_source/list.vue b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/alarmPluginExample/_source/list.vue
new file mode 100644
index 0000000..965f941
--- /dev/null
+++ b/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>
\ No newline at end of file
diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/alarmPluginExample/index.vue b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/alarmPluginExample/index.vue
new file mode 100644
index 0000000..50a1473
--- /dev/null
+++ b/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>
diff --git a/dolphinscheduler-ui/src/js/conf/home/router/index.js b/dolphinscheduler-ui/src/js/conf/home/router/index.js
index b65586c..5f6f20b 100644
--- a/dolphinscheduler-ui/src/js/conf/home/router/index.js
+++ b/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')}`
+          }
         }
       ]
     },
diff --git a/dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js b/dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js
index 56834a2..34d3ce3 100644
--- a/dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js
+++ b/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: [
diff --git a/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js b/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
index 0f59aec..f1295da 100755
--- a/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
+++ b/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',
diff --git a/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js b/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
index 0481cd0..148bc33 100755
--- a/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
+++ b/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': '批量移动',
diff --git a/dolphinscheduler-ui/src/sass/common/_table.scss b/dolphinscheduler-ui/src/sass/common/_table.scss
index 688f8e3..d643053 100644
--- a/dolphinscheduler-ui/src/sass/common/_table.scss
+++ b/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;
+}