feat: Support search and visualize alarms with tags (#483)

diff --git a/src/assets/lang/en.ts b/src/assets/lang/en.ts
index 574a51d..a218839 100644
--- a/src/assets/lang/en.ts
+++ b/src/assets/lang/en.ts
@@ -222,6 +222,8 @@
   hide: 'Hide',
   message: 'Message',
   tooltipsContent: 'Tooltip Content',
+  alarmDetail: 'Alarm Detail',
+  scope: 'Scope',
 };
 
 export default m;
diff --git a/src/assets/lang/zh.ts b/src/assets/lang/zh.ts
index e6d6594..9901404 100644
--- a/src/assets/lang/zh.ts
+++ b/src/assets/lang/zh.ts
@@ -220,6 +220,8 @@
   hide: '隐藏',
   message: '信息',
   tooltipsContent: '提示内容',
+  alarmDetail: '警告详情',
+  scope: '范围',
 };
 
 export default m;
diff --git a/src/graph/fragments/alarm.ts b/src/graph/fragments/alarm.ts
index 16878ec..1643676 100644
--- a/src/graph/fragments/alarm.ts
+++ b/src/graph/fragments/alarm.ts
@@ -16,15 +16,18 @@
  */
 
 export const Alarm = {
-  variable:
-    '$keyword: String, $scope: Scope, $duration:Duration!, $paging: Pagination!',
+  variable: '$keyword: String, $scope: Scope, $duration:Duration!, $tags:[AlarmTag], $paging: Pagination!',
   query: `
-    getAlarm(keyword: $keyword, scope: $scope, duration: $duration, paging: $paging) {
+    getAlarm(keyword: $keyword, scope: $scope, duration: $duration, paging: $paging, tags: $tags) {
       items: msgs {
         key: id
         message
         startTime
         scope
+        tags {
+          key
+          value
+        }
       }
       total
     }`,
diff --git a/src/types/alarm.d.ts b/src/types/alarm.d.ts
index b537e32..93b8cdc 100644
--- a/src/types/alarm.d.ts
+++ b/src/types/alarm.d.ts
@@ -24,4 +24,6 @@
   message: string;
   key: string;
   startTime: string;
+  scope: string;
+  tags: Array<{ key: string; value: string }>;
 }
diff --git a/src/views/components/alarm/alarm-table.vue b/src/views/components/alarm/alarm-table.vue
index 588757c..4cf62c1 100644
--- a/src/views/components/alarm/alarm-table.vue
+++ b/src/views/components/alarm/alarm-table.vue
@@ -14,7 +14,7 @@
 limitations under the License. -->
 <template>
   <div class="rk-alarm-table clear">
-    <div v-for="(i, index) in data" :key="index" class="mb-10 clear">
+    <div v-for="(i, index) in data" :key="index" class="mb-10 clear alarm-item" @click="showDetails(i)">
       <div class="g-sm-3 grey sm hide-xs rk-alarm-time-line tr">
         {{ parseInt(i.startTime) | dateformat }}
       </div>
@@ -37,16 +37,64 @@
         </div>
       </div>
     </div>
+    <rk-sidebox :width="'50%'" :show.sync="isShowDetails" :title="$t('alarmDetail')">
+      <div class="mb-10 clear rk-flex" v-for="(item, index) in AlarmDetailCol" :key="index">
+        <template>
+          <span class="g-sm-4 grey">{{ $t(item.value) }}:</span>
+          <span v-if="item.label === 'startTime'" class="g-sm-8">{{ currentDetail[item.label] | dateformat }}</span>
+          <span v-else-if="item.label === 'tags'" class="g-sm-8">
+            <div v-for="(d, index) in alarmTags" :key="index">{{ d }}</div>
+          </span>
+          <span v-else class="g-sm-8">{{ currentDetail[item.label] }}</span>
+        </template>
+      </div>
+    </rk-sidebox>
   </div>
 </template>
 
 <script lang="ts">
   import Vue from 'vue';
   import { Component, Prop } from 'vue-property-decorator';
+  import { Alarm } from '@/types/alarm';
 
   @Component
   export default class AlarmTable extends Vue {
-    @Prop({ default: () => [] }) private data: any;
+    @Prop({ default: () => [] }) private data!: Alarm[];
+    private isShowDetails: boolean = false;
+    private currentDetail: Alarm = {
+      tags: [],
+      scope: 'All',
+      message: '',
+      key: '',
+      startTime: '',
+    };
+    private alarmTags: string[] = [];
+    private AlarmDetailCol = [
+      {
+        label: 'scope',
+        value: 'scope',
+      },
+      {
+        label: 'startTime',
+        value: 'startTime',
+      },
+      {
+        label: 'tags',
+        value: 'tags',
+      },
+      {
+        label: 'message',
+        value: 'message',
+      },
+    ];
+
+    private showDetails(item: Alarm) {
+      this.currentDetail = item;
+      this.alarmTags = this.currentDetail.tags.map((d: { key: string; value: string }) => {
+        return `${d.key} = ${d.value}`;
+      });
+      this.isShowDetails = true;
+    }
   }
 </script>
 
@@ -96,4 +144,7 @@
     margin-top: -1px;
     border-radius: 4px;
   }
+  .alarm-item {
+    cursor: pointer;
+  }
 </style>
diff --git a/src/views/components/alarm/alarm-tool.vue b/src/views/components/alarm/alarm-tool.vue
index 04f13e1..306bc37 100644
--- a/src/views/components/alarm/alarm-tool.vue
+++ b/src/views/components/alarm/alarm-tool.vue
@@ -14,26 +14,28 @@
 limitations under the License. -->
 <template>
   <nav class="rk-alarm-tool flex-h">
-    <AlarmSelect
-      :title="$t('filterScope')"
-      :value="alarmOption"
-      @input="
-        (option) => {
-          alarmOption = option;
-          handleRefresh(1);
-        }
-      "
-      :data="alarmOptions"
-    />
-    <div class="mr-10" style="padding: 3px 15px 0">
-      <div class="sm grey">{{ $t('searchKeyword') }}</div>
-      <input type="text" v-model="keyword" class="rk-alarm-tool-input" @input="handleRefresh(1)" />
+    <div class="flex-h alarm-conditions">
+      <AlarmSelect
+        :title="$t('filterScope')"
+        :value="alarmOption"
+        @input="
+          (option) => {
+            alarmOption = option;
+            handleRefresh({ pageNum: 1 });
+          }
+        "
+        :data="alarmOptions"
+      />
+      <div class="mr-10 ml-10">
+        <span class="sm grey">{{ $t('searchKeyword') }}: </span>
+        <input type="text" v-model="keyword" class="rk-alarm-tool-input" @input="handleRefresh({ pageNum: 1 })" />
+      </div>
+      <ConditionTags :type="'ALARM'" @updateTags="(data) => handleRefresh({ pageNum: 1, tagsMap: data.tagsMap })" />
     </div>
     <RkPage
-      class="mt-15"
       :currentSize="20"
       :currentPage="pageNum"
-      @changePage="(pageNum) => handleRefresh(pageNum)"
+      @changePage="(pageNum) => handleRefresh({ pageNum })"
       :total="total"
     />
   </nav>
@@ -44,15 +46,12 @@
   import { Component, Prop } from 'vue-property-decorator';
   import { Action, Mutation, Getter } from 'vuex-class';
   import AlarmSelect from './alarm-select.vue';
+  import { Option, DurationTime } from '@/types/global';
+  import { ConditionTags } from '../common/index';
 
-  interface Option {
-    key: string | number;
-    label: string | number;
-  }
-
-  @Component({ components: { AlarmSelect } })
+  @Component({ components: { AlarmSelect, ConditionTags } })
   export default class AlarmTool extends Vue {
-    @Getter('durationTime') private durationTime: any;
+    @Getter('durationTime') private durationTime!: DurationTime;
     @Mutation('SET_EVENTS') private SET_EVENTS: any;
     @Action('rocketAlarm/GET_ALARM') private GET_ALARM: any;
     @Prop() private total!: number;
@@ -69,15 +68,24 @@
     ];
     private keyword: string = '';
 
-    private handleRefresh(pageNum: number) {
-      this.pageNum = pageNum;
+    private beforeMount() {
+      this.SET_EVENTS([
+        () => {
+          this.handleRefresh({ pageNum: 1 });
+        },
+      ]);
+      this.handleRefresh({ pageNum: 1 });
+    }
+    private handleRefresh(param: { pageNum: number; tagsMap?: Array<{ key: string; value: string }> }) {
+      this.pageNum = param.pageNum;
       const params: any = {
         duration: this.durationTime,
         paging: {
-          pageNum,
+          pageNum: param.pageNum,
           pageSize: 20,
           needTotal: true,
         },
+        tags: param.tagsMap,
       };
       if (this.alarmOption.key) {
         params.scope = this.alarmOption.key;
@@ -87,22 +95,13 @@
       }
       this.GET_ALARM(params);
     }
-
-    private beforeMount() {
-      this.SET_EVENTS([
-        () => {
-          this.handleRefresh(1);
-        },
-      ]);
-      this.handleRefresh(1);
-    }
     private beforeDestroy() {
       this.SET_EVENTS([]);
     }
   }
 </script>
 
-<style lang="scss">
+<style lang="scss" scoped>
   .rk-alarm-tool {
     border-bottom: 1px solid #c1c5ca41;
     height: 52px;
@@ -110,6 +109,7 @@
     padding: 0 15px;
     color: #efefef;
     flex-shrink: 0;
+    justify-content: space-between;
   }
 
   .rk-alarm-tool-input {
@@ -118,4 +118,7 @@
     padding: 2px 5px;
     border-radius: 3px;
   }
+  .alarm-conditions {
+    height: 100%;
+  }
 </style>
diff --git a/src/views/components/common/condition-tags.vue b/src/views/components/common/condition-tags.vue
new file mode 100644
index 0000000..b27fc18
--- /dev/null
+++ b/src/views/components/common/condition-tags.vue
@@ -0,0 +1,132 @@
+<!-- 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="flex-h">
+    <div class="mr-10 pt-5">
+      <span class="sm grey">{{ $t('tags') }}: </span>
+      <span class="rk-trace-tags">
+        <span class="selected" v-for="(item, index) in tagsList" :key="index">
+          <span>{{ item }}</span>
+          <span class="remove-icon" @click="removeTags(index)">×</span>
+        </span>
+      </span>
+      <input type="text" :placeholder="$t('addTag')" v-model="tags" class="rk-trace-new-tag" @keyup="addLabels" />
+      <span class="tags-tip" v-tooltip:bottom="{ content: $t('traceTagsTip') }">
+        <a
+          target="blank"
+          href="https://github.com/apache/skywalking/blob/master/docs/en/setup/backend/configuration-vocabulary.md"
+        >
+          {{ $t('tagsLink') }}
+        </a>
+        <rk-icon icon="help" class="mr-5" />
+      </span>
+    </div>
+  </div>
+</template>
+<script lang="ts">
+  import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
+  @Component
+  export default class ConditionTags extends Vue {
+    @Prop() private type!: string;
+    @Prop() private clearTags!: boolean;
+    private tagsList: string[] = [];
+    private tags: string = '';
+
+    private created() {
+      if (this.type === 'LOG') {
+        this.tagsList = localStorage.getItem('logTags') ? JSON.parse(localStorage.getItem('logTags') || '') : [];
+      } else if (this.type === 'TRACE') {
+        this.tagsList = localStorage.getItem('traceTags') ? JSON.parse(localStorage.getItem('traceTags') || '') : [];
+      }
+      // else { // ALARM
+      //   this.tagsList = localStorage.getItem('alarmTags') ? JSON.parse(localStorage.getItem('alarmTags') || '') : [];
+      // }
+
+      this.updateTags();
+    }
+    private removeTags(index: number) {
+      this.tagsList.splice(index, 1);
+      this.updateTags();
+      localStorage.setItem('traceTags', JSON.stringify(this.tagsList));
+    }
+    private addLabels(event: KeyboardEvent) {
+      if (event.keyCode !== 13 || !this.tags) {
+        return;
+      }
+      this.tagsList.push(this.tags);
+      this.tags = '';
+      this.updateTags();
+    }
+    private updateTags() {
+      const tagsMap = this.tagsList.map((item: string) => {
+        const key = item.substring(0, item.indexOf('='));
+        return {
+          key,
+          value: item.substring(item.indexOf('=') + 1, item.length),
+        };
+      });
+      this.$emit('updateTags', { tagsMap, tagsList: this.tagsList });
+    }
+    @Watch('clearTags')
+    private clearTagsWatch() {
+      if (this.clearTags) {
+        this.tagsList = [];
+      }
+    }
+  }
+</script>
+<style lang="scss" scoped>
+  .rk-trace-tags {
+    padding: 1px 5px 0 0;
+    border-radius: 3px;
+    height: 24px;
+    display: inline-block;
+    vertical-align: top;
+  }
+  .selected {
+    display: inline-block;
+    padding: 0 3px;
+    border-radius: 3px;
+    overflow: hidden;
+    color: rgba(0, 0, 0, 0.65);
+    border: 1px dashed #aaa;
+    color: #eee;
+    font-size: 12px;
+    margin: 0 2px;
+  }
+  .rk-trace-tags {
+    padding: 1px 5px 0 0;
+    border-radius: 3px;
+    height: 24px;
+    display: inline-block;
+    vertical-align: top;
+  }
+  .rk-trace-new-tag {
+    border-style: unset;
+    outline: 0;
+    padding: 2px 5px;
+    border-radius: 3px;
+    width: 175px;
+    margin-right: 3px;
+  }
+  .remove-icon {
+    display: inline-block;
+    margin-left: 3px;
+    cursor: pointer;
+  }
+  .tags-tip {
+    color: #a7aebb;
+  }
+</style>
diff --git a/src/views/components/common/index.ts b/src/views/components/common/index.ts
index 9a70b81..ae93b4f 100644
--- a/src/views/components/common/index.ts
+++ b/src/views/components/common/index.ts
@@ -16,5 +16,6 @@
  */
 
 import TraceDetailChartTable from './trace-detail-chart-table.vue';
+import ConditionTags from './condition-tags.vue';
 
-export { TraceDetailChartTable };
+export { TraceDetailChartTable, ConditionTags };
diff --git a/src/views/components/log/log-conditions.vue b/src/views/components/log/log-conditions.vue
index b497c8b..01c70dd 100644
--- a/src/views/components/log/log-conditions.vue
+++ b/src/views/components/log/log-conditions.vue
@@ -82,31 +82,7 @@
         </span>
       </div>
     </div>
-    <div class="mr-10" style="padding-top: 10px" v-show="rocketLog.type.key === cateGoryService">
-      <span class="sm grey">{{ $t('tags') }}: </span>
-      <span class="rk-log-tags">
-        <span class="selected" v-for="(item, index) in tagsList" :key="index">
-          <span>{{ item }}</span>
-          <span class="remove-icon" @click="removeTags(index)">×</span>
-        </span>
-      </span>
-      <input
-        type="text"
-        :placeholder="$t('addTag')"
-        v-model="tags"
-        class="rk-log-new-tag"
-        @keyup="addLabels($event, LogConditionsOpt.Tags)"
-      />
-      <span class="log-tips" v-tooltip:bottom="{ content: $t('logsTagsTip') }">
-        <a
-          target="blank"
-          href="https://github.com/apache/skywalking/blob/master/docs/en/setup/backend/configuration-vocabulary.md"
-        >
-          {{ $t('tagsLink') }}
-        </a>
-        <rk-icon icon="help" class="mr-5" />
-      </span>
-    </div>
+    <ConditionTags :type="'LOG'" :clearTags="clearAllTags" @updateTags="updateTags" />
   </div>
 </template>
 
@@ -116,9 +92,10 @@
   import { State as globalState } from '@/store/modules/global/index';
   import { State as logState } from '@/store/modules/log/index';
   import dateFormatStep from '@/utils/dateFormat';
+  import { ConditionTags } from '../common/index';
 
   @Component({
-    components: {},
+    components: { ConditionTags },
   })
   export default class LogConditions extends Vue {
     @State('rocketbot') private rocketbotGlobal!: globalState;
@@ -129,8 +106,6 @@
     @Mutation('SET_EXCLUDING_KEYWORDS_CONTENT') private SET_EXCLUDING_KEYWORDS_CONTENT: any;
     private keywordsOfContent: string = '';
     private excludingKeywordsOfContent: string = '';
-    private tagsList: string[] = [];
-    private tags: string = '';
     private searchTime: Date[] = [];
     private traceId: string = '';
     private LogConditionsOpt = {
@@ -141,10 +116,9 @@
       Date: 'date',
     };
     private cateGoryService = 'service';
+    private clearAllTags: boolean = false;
     private created() {
       this.searchTime = [this.rocketbotGlobal.durationRow.start, this.rocketbotGlobal.durationRow.end];
-      (this.tagsList = localStorage.getItem('logTags') ? JSON.parse(localStorage.getItem('logTags') || '') : []),
-        this.updateTags();
       this.traceId = localStorage.getItem('logTraceId') || '';
     }
     private changeConditions(item: any, type: string) {
@@ -159,20 +133,13 @@
       if (event.keyCode !== 13) {
         return;
       }
-      if (type === this.LogConditionsOpt.Tags && !this.tags) {
-        return;
-      }
       if (type === this.LogConditionsOpt.KeywordsOfContent && !this.keywordsOfContent) {
         return;
       }
       if (type === this.LogConditionsOpt.ExcludingKeywordsOfContent && !this.excludingKeywordsOfContent) {
         return;
       }
-      if (type === this.LogConditionsOpt.Tags) {
-        this.tagsList.push(this.tags);
-        this.tags = '';
-        this.updateTags();
-      } else if (type === this.LogConditionsOpt.KeywordsOfContent) {
+      if (type === this.LogConditionsOpt.KeywordsOfContent) {
         const keywordsOfContentList = this.rocketLog.conditions.keywordsOfContent || [];
         keywordsOfContentList.push(this.keywordsOfContent);
         this.SET_LOG_CONDITIONS({
@@ -212,24 +179,12 @@
       this.excludingKeywordsOfContent = '';
       this.updateContent(this.LogConditionsOpt.ExcludingKeywordsOfContent);
     }
-    private removeTags(index: number) {
-      this.tagsList.splice(index, 1);
-      this.updateTags();
-    }
-    private updateTags() {
-      const tagsMap = this.tagsList.map((item: string) => {
-        const key = item.substring(0, item.indexOf('='));
-
-        return {
-          key,
-          value: item.substring(item.indexOf('=') + 1, item.length),
-        };
-      });
+    private updateTags(data: { tagsMap: Array<{ key: string; value: string }>; tagsList: string[] }) {
       this.SET_LOG_CONDITIONS({
         label: this.LogConditionsOpt.Tags,
-        key: tagsMap,
+        key: data.tagsMap,
       });
-      localStorage.setItem('logTags', JSON.stringify(this.tagsList));
+      localStorage.setItem('logTags', JSON.stringify(data.tagsList));
     }
     private updateContent(type: string) {
       let list = [];
@@ -263,7 +218,8 @@
     @Watch('rocketLog.conditions')
     private clearTags() {
       if (!this.rocketLog.conditions.tags) {
-        this.tagsList = [];
+        localStorage.removeItem('logTags');
+        this.clearAllTags = true;
       }
       if (!this.rocketLog.conditions.traceId) {
         this.traceId = '';
diff --git a/src/views/components/log/log-service-detail.vue b/src/views/components/log/log-service-detail.vue
index 0a521a6..0c2e82e 100644
--- a/src/views/components/log/log-service-detail.vue
+++ b/src/views/components/log/log-service-detail.vue
@@ -44,7 +44,7 @@
   import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
   import LogTable from './log-table/log-table.vue';
   import { ServiceLogDetail } from './log-table/log-constant';
-  import { formatJson } from '../../../utils/formatJson';
+  import { formatJson } from '@/utils/formatJson';
 
   @Component({
     components: { LogTable },
diff --git a/src/views/components/trace/trace-search.vue b/src/views/components/trace/trace-search.vue
index 67aa4d7..75d8de4 100644
--- a/src/views/components/trace/trace-search.vue
+++ b/src/views/components/trace/trace-search.vue
@@ -15,7 +15,7 @@
 
 <template>
   <div class="rk-trace-search">
-    <div class="pb-5 pt-5">
+    <div>
       <a class="rk-trace-clear-btn r" @click="status = !status">
         <span class="mr-5 vm">{{ $t('more') }}</span>
         <svg class="icon trans vm" :style="`transform: rotate(${status ? 180 : 0}deg);`">
@@ -34,7 +34,7 @@
         </svg>
         <span class="vm">{{ $t('clear') }}</span>
       </a>
-      <div class="flex-h">
+      <div class="flex-h trace-select">
         <TraceSelect
           :hasSearch="true"
           :title="$t('service')"
@@ -81,27 +81,7 @@
           <RkDate class="sm" v-model="time" position="bottom" format="YYYY-MM-DD HH:mm" />
         </div>
       </div>
-      <div class="flex-h">
-        <div class="mr-10" style="padding-top: 5px">
-          <span class="sm grey">{{ $t('tags') }}: </span>
-          <span class="rk-trace-tags">
-            <span class="selected" v-for="(item, index) in tagsList" :key="index">
-              <span>{{ item }}</span>
-              <span class="remove-icon" @click="removeTags(index)">×</span>
-            </span>
-          </span>
-          <input type="text" :placeholder="$t('addTag')" v-model="tags" class="rk-trace-new-tag" @keyup="addLabels" />
-          <span class="trace-tips" v-tooltip:bottom="{ content: $t('traceTagsTip') }">
-            <a
-              target="blank"
-              href="https://github.com/apache/skywalking/blob/master/docs/en/setup/backend/configuration-vocabulary.md"
-            >
-              {{ $t('tagsLink') }}
-            </a>
-            <rk-icon icon="help" class="mr-5" />
-          </span>
-        </div>
-      </div>
+      <ConditionTags :type="'TRACE'" :clearTags="clearTags" @updateTags="updateTags" />
     </div>
   </div>
 </template>
@@ -111,10 +91,11 @@
   import { Component, Vue, Watch } from 'vue-property-decorator';
   import { Action, Getter, Mutation, State } from 'vuex-class';
   import TraceSelect from '../common/trace-select.vue';
+  import { ConditionTags } from '../common/index';
   import { State as traceState } from '@/store/modules/trace/index';
   import { State as globalState } from '@/store/modules/global/index';
   import dateFormatStep from '@/utils/dateFormat';
-  @Component({ components: { TraceSelect } })
+  @Component({ components: { TraceSelect, ConditionTags } })
   export default class TraceSearch extends Vue {
     @State('rocketbot') private rocketbotGlobal!: globalState;
     @State('rocketTrace') private rocketTrace!: traceState;
@@ -139,12 +120,13 @@
     private endpoint: Option = { label: 'All', key: '' };
     private traceId: string = localStorage.getItem('traceId') || '';
     private traceState: Option = { label: 'All', key: 'ALL' };
-    private tags: string = '';
+    private tagsMap: Array<{ key: string; value: string }> = [];
     private tagsList: string[] = [];
+    private clearTags: boolean = false;
+
     private created() {
       this.traceId = this.$route.query.traceid ? this.$route.query.traceid.toString() : this.traceId;
       this.time = [this.rocketbotGlobal.durationRow.start, this.rocketbotGlobal.durationRow.end];
-      this.tagsList = localStorage.getItem('traceTags') ? JSON.parse(localStorage.getItem('traceTags') || '') : [];
     }
     private mounted() {
       this.getTraceList();
@@ -197,6 +179,10 @@
     private chooseEndpoint(i: Option) {
       this.endpoint = i;
     }
+    private updateTags(data: { tagsMap: Array<{ key: string; value: string }>; tagsList: string[] }) {
+      this.tagsList = data.tagsList;
+      this.tagsMap = data.tagsMap;
+    }
     private getTraceList() {
       this.GET_SERVICES({ duration: this.durationTime });
       const temp: any = {
@@ -235,17 +221,8 @@
         temp.traceId = this.traceId;
       }
       localStorage.setItem('traceId', this.traceId);
-      if (this.tagsList.length) {
-        const tagsMap = this.tagsList.map((item: string) => {
-          const key = item.substring(0, item.indexOf('='));
-          return {
-            key,
-            value: item.substring(item.indexOf('=') + 1, item.length),
-          };
-        });
-        temp.tags = tagsMap;
-        localStorage.setItem('traceTags', JSON.stringify(this.tagsList));
-      }
+      temp.tags = this.tagsMap;
+      localStorage.setItem('traceTags', JSON.stringify(this.tagsList));
       this.SET_TRACE_FORM(temp);
       this.$eventBus.$emit('SET_LOADING_TRUE', () => {
         this.GET_TRACELIST().then(() => {
@@ -263,25 +240,17 @@
       this.service = { label: 'All', key: '' };
       this.instance = { label: 'All', key: '' };
       this.endpoint = { label: 'All', key: '' };
-      this.tagsList = [];
       localStorage.removeItem('traceTags');
+      this.clearTags = true;
+      this.tagsMap = [];
+      this.tagsList = [];
       this.traceId = '';
       localStorage.removeItem('traceId');
       this.traceState = { label: 'All', key: 'ALL' };
       this.SET_TRACE_FORM_ITEM({ type: 'queryOrder', data: '' });
       this.getTraceList();
     }
-    private addLabels(event: KeyboardEvent) {
-      if (event.keyCode !== 13 || !this.tags) {
-        return;
-      }
-      this.tagsList.push(this.tags);
-      this.tags = '';
-    }
-    private removeTags(index: number) {
-      this.tagsList.splice(index, 1);
-      localStorage.setItem('traceTags', JSON.stringify(this.tagsList));
-    }
+
     @Watch('rocketbotGlobal.durationRow')
     private durationRowWatch(value: Duration) {
       this.time = [value.start, value.end];
@@ -290,6 +259,9 @@
 </script>
 
 <style lang="scss">
+  .trace-select {
+    height: 52px;
+  }
   .rk-trace-search {
     flex-shrink: 0;
     background-color: #333840;
@@ -372,7 +344,6 @@
     background-color: #484b55;
     padding: 4px 10px;
     border-radius: 3px;
-    margin-top: 8px;
     position: relative;
     box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.1);
     &:after {