You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by ki...@apache.org on 2021/01/22 13:56:47 UTC

[incubator-dolphinscheduler] branch dev updated: [Feature-#3826][UI]Alert SPI (#4441)

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

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


The following commit(s) were added to refs/heads/dev by this push:
     new 500147f  [Feature-#3826][UI]Alert SPI (#4441)
500147f is described below

commit 500147fa7e2279e8069c531fc163a07a85629446
Author: break60 <79...@qq.com>
AuthorDate: Fri Jan 22 21:56:21 2021 +0800

    [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
---
 .../ui-licenses/LICENSE-@form-create-element-ui    |  21 ++++
 dolphinscheduler-ui/package.json                   |   1 +
 dolphinscheduler-ui/src/js/conf/home/index.js      |   2 +
 .../home/pages/dag/_source/formModel/tasks/sql.vue |  55 +---------
 .../pages/dag/_source/formModel/tasks/sqoop.vue    |   1 -
 .../pages/definition/pages/list/_source/list.vue   |  27 +----
 .../pages/definition/pages/list/_source/start.vue  |  31 +-----
 .../pages/definition/pages/list/_source/timing.vue |  26 +----
 .../pages/definition/timing/_source/list.vue       |  27 +----
 .../pages/warningGroups/_source/createWarning.vue  |  32 +++---
 .../security/pages/warningGroups/_source/list.vue  |  55 +---------
 .../pages/security/pages/warningGroups/index.vue   |  14 ++-
 .../_source/createWarningInstance.vue}             | 118 ++++++++++++++-------
 .../_source/list.vue                               |  82 ++------------
 .../{warningGroups => warningInstance}/index.vue   |  30 +++---
 .../src/js/conf/home/router/index.js               |  11 +-
 .../src/js/conf/home/store/security/actions.js     |  94 +++++++++++++++-
 .../components/secondaryMenu/_source/menu.js       |   9 ++
 .../src/js/module/i18n/locale/en_US.js             |   9 +-
 .../src/js/module/i18n/locale/zh_CN.js             |   6 ++
 20 files changed, 298 insertions(+), 353 deletions(-)

diff --git a/dolphinscheduler-dist/release-docs/licenses/ui-licenses/LICENSE-@form-create-element-ui  b/dolphinscheduler-dist/release-docs/licenses/ui-licenses/LICENSE-@form-create-element-ui 
new file mode 100644
index 0000000..468a05f
--- /dev/null
+++ b/dolphinscheduler-dist/release-docs/licenses/ui-licenses/LICENSE-@form-create-element-ui 	
@@ -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. 
diff --git a/dolphinscheduler-ui/package.json b/dolphinscheduler-ui/package.json
index acc40b6..74558c8 100644
--- a/dolphinscheduler-ui/package.json
+++ b/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",
diff --git a/dolphinscheduler-ui/src/js/conf/home/index.js b/dolphinscheduler-ui/src/js/conf/home/index.js
index 42295b2..c1bcdff 100644
--- a/dolphinscheduler-ui/src/js/conf/home/index.js
+++ b/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)
 
diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/sql.vue b/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/sql.vue
index 7e3ae46..706edcd 100644
--- a/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/sql.vue
+++ b/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>
diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/sqoop.vue b/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/sqoop.vue
index 2513393..7819b23 100644
--- a/dolphinscheduler-ui/src/js/conf/home/pages/dag/_source/formModel/tasks/sqoop.vue
+++ b/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
diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/list.vue b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/list.vue
index c3b7799..1aee167 100644
--- a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/list.vue
+++ b/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) {
@@ -227,29 +225,12 @@
         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()
diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/start.vue b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/start.vue
index 0cf2391..e2ab711 100644
--- a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/start.vue
+++ b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/start.vue
@@ -101,22 +101,6 @@
     </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')}}
       </div>
       <div class="cont">
@@ -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>
 
diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/timing.vue b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/timing.vue
index 51c2787..526abfb 100644
--- a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/pages/list/_source/timing.vue
+++ b/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>
 
diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/timing/_source/list.vue b/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/timing/_source/list.vue
index b566976..7081e30 100644
--- a/dolphinscheduler-ui/src/js/conf/home/pages/projects/pages/definition/timing/_source/list.vue
+++ b/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
        */
@@ -229,28 +227,11 @@
         })
       },
       /**
-       * 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
diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/createWarning.vue b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/createWarning.vue
index 184fe8a..6ae8c51 100644
--- a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/createWarning.vue
+++ b/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
       }
     },
diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/list.vue b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/list.vue
index a4fd982..c3c0a9e 100644
--- a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/list.vue
+++ b/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>
diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/index.vue b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/index.vue
index 8368a04..53b4783 100644
--- a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/index.vue
+++ b/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 {
diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/createWarning.vue b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/_source/createWarningInstance.vue
similarity index 50%
copy from dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/createWarning.vue
copy to dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/_source/createWarningInstance.vue
index 184fe8a..73ef61f 100644
--- a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/createWarning.vue
+++ b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/_source/createWarningInstance.vue
@@ -18,17 +18,17 @@
   <m-popup
           ref="popup"
           :ok-text="item ? $t('Edit') : $t('Submit')"
-          :nameText="item ? $t('Edit alarm group') : $t('Create alarm group')"
+          :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('Group Name')}}</template>
+          <template slot="name"><strong>*</strong>{{$t('Alarm instance name')}}</template>
           <template slot="content">
             <el-input
                     type="input"
-                    v-model="groupName"
+                    v-model="instanceName"
                     maxlength="60"
                     size="small"
                     :placeholder="$t('Please enter group name')">
@@ -36,29 +36,31 @@
           </template>
         </m-list-box-f>
         <m-list-box-f>
-          <template slot="name"><strong>*</strong>{{$t('Group Type')}}</template>
+          <template slot="name"><strong>*</strong>{{$t('Select plugin')}}</template>
           <template slot="content">
-            <el-select v-model="groupType" size="small">
+            <el-select v-model="pluginDefineId" size="small" style="width: 100%" @change="changePlugin" disabled="true" v-if="item.id">
               <el-option
-                      v-for="city in options"
-                      :key="city.id"
-                      :value="city.id"
-                      :label="city.code">
+                      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>
-        <m-list-box-f>
-          <template slot="name">{{$t('Remarks')}}</template>
-          <template slot="content">
-            <el-input
-                type="textarea"
-                v-model="description"
-                size="small"
-                :placeholder="$t('Please enter description')">
-            </el-input>
+        <div>
+          <template>
+            <div class="alertForm"><form-create v-model="$f" :rule="rule" :option="{submitBtn:false}" size="mini"></form-create></div>
           </template>
-        </m-list-box-f>
+        </div>
       </div>
     </template>
   </m-popup>
@@ -74,28 +76,29 @@
     data () {
       return {
         store,
-        groupName: '',
-        groupType: 'EMAIL',
-        description: '',
-        options: [{ code: `${i18n.$t('Email')}`, id: 'EMAIL' }, { code: `${i18n.$t('SMS')}`, id: 'SMS' }]
+        instanceName: '',
+        pluginDefineId: null,
+        $f: {},
+        rule: []
       }
     },
     props: {
-      item: Object
+      item: Object,
+      pulginInstance: Array
     },
     methods: {
       _ok () {
         if (this._verification()) {
           // The name is not verified
-          if (this.item && this.item.groupName === this.groupName) {
+          if (this.item && this.item.instanceName === this.instanceName) {
             this._submit()
             return
           }
 
           // Verify username
           this.store.dispatch('security/verifyName', {
-            type: 'alertgroup',
-            groupName: this.groupName
+            type: 'alarmInstance',
+            instanceName: this.instanceName
           }).then(res => {
             this._submit()
           }).catch(e => {
@@ -105,23 +108,42 @@
       },
       _verification () {
         // group name
-        if (!this.groupName.replace(/\s*/g, '')) {
+        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 = {
-          groupName: this.groupName,
-          groupType: this.groupType,
-          description: this.description
+          instanceName: this.instanceName,
+          pluginDefineId: this.pluginDefineId,
+          pluginInstanceParams: JSON.stringify(this.$f.rule)
         }
         if (this.item) {
-          param.id = this.item.id
+          param.alertPluginInstanceId = this.item.id
+          param.pluginDefineId = null
         }
         this.$refs.popup.spinnerLoading = true
-        this.store.dispatch(`security/${this.item ? 'updateAlertgrou' : 'createAlertgrou'}`, param).then(res => {
+        this.store.dispatch(`security/${this.item ? 'updateAlertPluginInstance' : 'createAlertPluginInstance'}`, param).then(res => {
           this.$emit('onUpdate')
           this.$message.success(res.msg)
           setTimeout(() => {
@@ -138,10 +160,17 @@
     },
     watch: {},
     created () {
+      let pluginInstanceParams = []
       if (this.item) {
-        this.groupName = this.item.groupName
-        this.groupType = this.item.groupType
-        this.description = this.item.description
+        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 () {
@@ -149,3 +178,20 @@
     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>
diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/list.vue b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/_source/list.vue
similarity index 54%
copy from dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/list.vue
copy to dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/_source/list.vue
index a4fd982..5a8cf2a 100644
--- a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/_source/list.vue
+++ b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/_source/list.vue
@@ -19,28 +19,19 @@
     <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="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">
+        <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')" width="140">
+        <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('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 +44,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 +62,7 @@
       return {
         list: [],
         transferDialog: false,
-        item: {},
-        transferData: {
-          sourceListPrs: [],
-          targetListPrs: [],
-          type: {
-            name: `${i18n.$t('Managing Users')}`
-          }
-        }
+        item: {}
       }
     },
     props: {
@@ -95,9 +71,9 @@
       pageSize: Number
     },
     methods: {
-      ...mapActions('security', ['deleteAlertgrou', 'getAuthList', 'grantAuthorization']),
+      ...mapActions('security', ['deletAelertPluginInstance']),
       _delete (item, i) {
-        this.deleteAlertgrou({
+        this.deletAelertPluginInstance({
           id: item.id
         }).then(res => {
           this.$emit('on-update')
@@ -109,50 +85,8 @@
       _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,
-          alertgroupId: this.item.id
-        })
-        this.transferDialog = false
-      },
       close () {
         this.transferDialog = false
-      },
-
-      _grantAuthorization (api, param) {
-        this.grantAuthorization({
-          api: api,
-          param: param
-        }).then(res => {
-          this.$message.success(res.msg)
-        }).catch(e => {
-          this.$message.error(e.msg || '')
-        })
       }
     },
     watch: {
@@ -168,6 +102,6 @@
     },
     mounted () {
     },
-    components: { mTransfer }
+    components: {}
   }
 </script>
diff --git a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/index.vue b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/index.vue
similarity index 83%
copy from dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/index.vue
copy to dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/index.vue
index 8368a04..54a8177 100644
--- a/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningGroups/index.vue
+++ b/dolphinscheduler-ui/src/js/conf/home/pages/security/pages/warningInstance/index.vue
@@ -15,21 +15,21 @@
  * limitations under the License.
  */
 <template>
-  <m-list-construction :title="$t('Warning group manage')">
+  <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 group')}}</el-button>
+          <el-button size="mini" @click="_create('')">{{$t('Create Alarm Instance')}}</el-button>
           <el-dialog
             :visible.sync="createWarningDialog"
-            width="auto">
-            <m-create-warning :item="item" @onUpdate="onUpdate" @close="close"></m-create-warning>
+            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.length || total>0">
+      <template v-if="alertgroupList!==null || total>0 ">
         <m-list @on-edit="_onEdit"
                 @on-update="_onUpdate"
                 :alertgroup-list="alertgroupList"
@@ -49,7 +49,7 @@
           </el-pagination>
         </div>
       </template>
-      <template v-if="!alertgroupList.length && total<=0">
+      <template v-if="alertgroupList===null && total<=0">
         <m-no-data></m-no-data>
       </template>
       <m-spin :is-spin="isLoading" :is-left="isLeft"></m-spin>
@@ -62,14 +62,14 @@
   import mList from './_source/list'
   import store from '@/conf/home/store'
   import mSpin from '@/module/components/spin/spin'
-  import mCreateWarning from './_source/createWarning'
+  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-groups-index',
+    name: 'warning-instance-index',
     data () {
       return {
         total: null,
@@ -83,13 +83,14 @@
         isLeft: true,
         isADMIN: store.state.user.userInfo.userType === 'ADMIN_USER',
         createWarningDialog: false,
-        item: {}
+        item: {},
+        pulginInstance: []
       }
     },
     mixins: [listUrlParamHandle],
     props: {},
     methods: {
-      ...mapActions('security', ['getAlertgroupP']),
+      ...mapActions('security', ['queryAlertPluginInstanceListPaging', 'getPlugins']),
       /**
        * Inquire
        */
@@ -110,6 +111,11 @@
         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
       },
@@ -130,7 +136,7 @@
           this.isLeft = true
         }
         this.isLoading = !flag
-        this.getAlertgroupP(this.searchParams).then(res => {
+        this.queryAlertPluginInstanceListPaging(this.searchParams).then(res => {
           if (this.searchParams.pageNo > 1 && res.totalList.length === 0) {
             this.searchParams.pageNo = this.searchParams.pageNo - 1
           } else {
@@ -158,6 +164,6 @@
     beforeDestroy () {
       sessionStorage.setItem('isLeft', 1)
     },
-    components: { mList, mListConstruction, mConditions, mSpin, mNoData, mCreateWarning }
+    components: { mList, mListConstruction, mConditions, mSpin, mNoData, mCreateWarningInstance }
   }
 </script>
diff --git a/dolphinscheduler-ui/src/js/conf/home/router/index.js b/dolphinscheduler-ui/src/js/conf/home/router/index.js
index 6b81526..8d205b8 100644
--- a/dolphinscheduler-ui/src/js/conf/home/router/index.js
+++ b/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
           }
         },
         {
@@ -399,6 +400,14 @@ const router = new Router({
           }
         },
         {
+          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',
           component: resolve => require(['../pages/security/pages/queue/index'], resolve),
diff --git a/dolphinscheduler-ui/src/js/conf/home/store/security/actions.js b/dolphinscheduler-ui/src/js/conf/home/store/security/actions.js
index 363dee7..9405d26 100644
--- a/dolphinscheduler-ui/src/js/conf/home/store/security/actions.js
+++ b/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)
@@ -352,6 +358,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
    */
   getAlertgroup ({ state }, payload) {
@@ -376,6 +430,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.
    */
   updateAlertgrou ({ state }, payload) {
@@ -400,6 +478,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
    */
   getProcessMasterList ({ state }, payload) {
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 2ce1a3c..daaf918 100644
--- a/dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js
+++ b/dolphinscheduler-ui/src/js/module/components/secondaryMenu/_source/menu.js
@@ -110,6 +110,15 @@ const menu = {
       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,
       path: 'worker-groups-manage',
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 c8216d4..168258a 100755
--- a/dolphinscheduler-ui/src/js/module/i18n/locale/en_US.js
+++ b/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',
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 2aa94cc..fb3bd3f 100755
--- a/dolphinscheduler-ui/src/js/module/i18n/locale/zh_CN.js
+++ b/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': '资源管理',