Feat: Create a dashboard template using the default template (#326)

diff --git a/src/assets/lang/en.ts b/src/assets/lang/en.ts
index 05ce744..a77d413 100644
--- a/src/assets/lang/en.ts
+++ b/src/assets/lang/en.ts
@@ -28,7 +28,7 @@
   currentEndpoint: 'Current Endpoint',
   currentInstance: 'Current Instance',
   currentDatabase: 'Current Database',
-  templateConfig: 'Template Config',
+  templateConfig: 'Template Configuration',
   copy: 'Copy',
   reset: 'Reset',
   apply: 'Apply',
diff --git a/src/components/rk-header.vue b/src/components/rk-header.vue
index 7127694..3e5d6bd 100644
--- a/src/components/rk-header.vue
+++ b/src/components/rk-header.vue
@@ -39,7 +39,7 @@
       </router-link>
       <router-link class="nav-link mr-20" to="/profile">
         <svg class="icon sm vm">
-          <use xlink:href="#merge"></use>
+          <use xlink:href="#timeline"></use>
         </svg>
         <span class="vm hide-xs ml-5">{{ this.$t('profile') }}</span>
       </router-link>
diff --git a/src/store/modules/dashboard/dashboard-data-layout.ts b/src/store/modules/dashboard/dashboard-data-layout.ts
index 51ac6d6..27d2879 100644
--- a/src/store/modules/dashboard/dashboard-data-layout.ts
+++ b/src/store/modules/dashboard/dashboard-data-layout.ts
@@ -23,6 +23,7 @@
   group: number;
   index: number;
   tree: CompsTree[];
+  templates: CompsTree[];
 }
 
 export const initState: State = {
@@ -42,6 +43,7 @@
       children: [],
     },
   ],
+  templates: [],
 };
 
 // mutations
@@ -70,17 +72,17 @@
     state.group = index;
     state.current = current;
   },
-  [types.ADD_COMPS_GROUP](state: State, params: { type: string; name: string }) {
+  [types.ADD_COMPS_GROUP](state: State, params: { type: string; name: string; templateName: string }) {
     if (!params.name) {
       return;
     }
+    const template = state.templates.filter((item) => item.name === params.templateName && params.type === item.type);
+    let group = { name: params.name, type: params.type, query: {}, children: [{ name: 'demo', children: [] }] };
 
-    const newTree = [];
-    Object.keys(state.tree).forEach((i: any) => {
-      newTree.push(state.tree[i]);
-    });
-    newTree.push({ name: params.name, type: params.type, query: {}, children: [{ name: 'demo', children: [] }] });
-    state.tree = newTree;
+    if (template.length) {
+      group = { ...group, children: template[0].children };
+    }
+    state.tree.push(group);
 
     window.localStorage.setItem('dashboard', JSON.stringify(state.tree));
   },
@@ -131,6 +133,9 @@
     state.tree[state.group].children[state.current].children[params.index] = { ...temp, ...params.values };
     window.localStorage.setItem('dashboard', JSON.stringify(state.tree));
   },
+  [types.SET_TEMPLATES](state: State, templates) {
+    state.templates = templates;
+  },
 };
 
 export default {
diff --git a/src/store/modules/dashboard/mutation-types.ts b/src/store/modules/dashboard/mutation-types.ts
index 8da2958..d43fb6f 100644
--- a/src/store/modules/dashboard/mutation-types.ts
+++ b/src/store/modules/dashboard/mutation-types.ts
@@ -34,6 +34,7 @@
 export const SET_CURRENT_INSTANCE = 'SET_CURRENT_INSTANCE';
 export const SET_INSTANCE_INFO = 'SET_INSTANCE_INFO';
 export const SET_KEYWORDSERVICE = 'SET_KEYWORDSERVICE';
+export const SET_TEMPLATES = 'SET_TEMPLATES';
 
 // comp
 export const SET_CURRENT_GROUP = 'SET_CURRENT_GROUP';
diff --git a/src/views/components/dashboard/tool-group.vue b/src/views/components/dashboard/tool-group.vue
index 2225978..00e9d94 100644
--- a/src/views/components/dashboard/tool-group.vue
+++ b/src/views/components/dashboard/tool-group.vue
@@ -44,6 +44,11 @@
           <option :value="DASHBOARDTYPE.METRIC">{{ $t('metricsView') }}</option>
           <option :value="DASHBOARDTYPE.DATABASE">{{ $t('databaseView') }}</option>
         </select>
+        <div class="sm grey  mb-5 mr-10" v-show="type !== DASHBOARDTYPE.METRIC">{{ $t('templateConfig') }}</div>
+        <select v-model="templateName" class="rk-dashboard-group-sel" v-show="type !== DASHBOARDTYPE.METRIC">
+          <option :value="''">None</option>
+          <option v-for="template in templates" :key="template.name" :value="template.name">{{ template.name }}</option>
+        </select>
         <div class="sm grey  mb-5 mr-10">{{ $t('templateName') }}</div>
         <input class="mb-5 rk-dashboard-group-input" type="text" v-model="name" />
         <a class="rk-btn r vm long tc confirm" @click="handleCreate">{{ $t('confirm') }}</a>
@@ -74,6 +79,7 @@
     private type: string = DASHBOARDTYPE.SERVICE;
     private show: boolean = false;
     private DASHBOARDTYPE = DASHBOARDTYPE;
+    private templateName: string = '';
 
     private get compType() {
       return (
@@ -81,7 +87,31 @@
         'service'
       );
     }
-    private handleOption(index: any) {
+    private get servicesTemplates() {
+      const templates = this.rocketComps.templates.filter(
+        (item: { type: string; name: string; children: any[] }) => item.type === DASHBOARDTYPE.SERVICE,
+      );
+
+      return templates;
+    }
+    private get databaseTemplates() {
+      const templates = this.rocketComps.templates.filter(
+        (item: { type: string; name: string; children: any[] }) => item.type === DASHBOARDTYPE.DATABASE,
+      );
+
+      return templates;
+    }
+    private get templates() {
+      let templates = [];
+      if (this.type === DASHBOARDTYPE.SERVICE) {
+        templates = this.servicesTemplates;
+      } else if (this.type === DASHBOARDTYPE.DATABASE) {
+        templates = this.databaseTemplates;
+      }
+
+      return templates;
+    }
+    private handleOption(index: number) {
       this.MIXHANDLE_CHANGE_GROUP(index);
       return this.MIXHANDLE_GET_OPTION({
         compType: this.compType,
@@ -92,9 +122,10 @@
       this.name = '';
       this.type = DASHBOARDTYPE.SERVICE;
       this.show = false;
+      this.templateName = '';
     }
     private handleCreate() {
-      this.ADD_COMPS_GROUP({ name: this.name, type: this.type });
+      this.ADD_COMPS_GROUP({ name: this.name, type: this.type, templateName: this.templateName });
       this.handleHide();
     }
   }
diff --git a/src/views/components/topology/topo-group/index.vue b/src/views/components/topology/topo-group/index.vue
index 6ace529..6508a67 100644
--- a/src/views/components/topology/topo-group/index.vue
+++ b/src/views/components/topology/topo-group/index.vue
@@ -1,10 +1,17 @@
-/** * 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. */
+<!-- 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="topo-group">
diff --git a/src/views/containers/dashboard.vue b/src/views/containers/dashboard.vue
index f996dd4..b48b530 100644
--- a/src/views/containers/dashboard.vue
+++ b/src/views/containers/dashboard.vue
@@ -78,6 +78,7 @@
     @Mutation('SET_COMPS_TREE') private SET_COMPS_TREE: any;
     @Mutation('ADD_COMP') private ADD_COMP: any;
     @Mutation('SET_EDIT') private SET_EDIT: any;
+    @Mutation('SET_TEMPLATES') private SET_TEMPLATES: any;
 
     private ObjectsType = ObjectsType;
 
@@ -110,17 +111,24 @@
       // }).then((data: any) => {
       //   console.log(data);
       // });
-      if (window.localStorage.getItem('version') !== '8.0') {
-        this.GET_ALL_TEMPLATES().then((allTemplate: ITemplate[]) => {
+      this.GET_ALL_TEMPLATES().then((allTemplate: ITemplate[]) => {
+        const dashboardTemplate = allTemplate.filter((item: ITemplate) => item.type === 'DASHBOARD');
+        const templatesConfig = dashboardTemplate.map((item: ITemplate) => JSON.parse(item.configuration)).flat(1);
+        this.SET_TEMPLATES(templatesConfig);
+        if (window.localStorage.getItem('version') !== '8.0') {
           window.localStorage.removeItem('dashboard');
-          this.setDashboardTemplates(allTemplate);
+          const template = allTemplate.filter((item: ITemplate) => item.type === 'DASHBOARD' && item.activated);
+          const templatesConfiguration = template.map((item: ITemplate) => JSON.parse(item.configuration)).flat(1);
+          this.SET_COMPS_TREE(templatesConfiguration || []);
+          window.localStorage.setItem('version', '8.0');
+          window.localStorage.setItem('dashboard', JSON.stringify(templatesConfiguration));
           this.handleOption();
-        });
-      } else {
-        const data: string = `${window.localStorage.getItem('dashboard')}`;
-        this.SET_COMPS_TREE(JSON.parse(data));
-      }
-      this.handleOption();
+        } else {
+          const data: string = `${window.localStorage.getItem('dashboard')}`;
+          this.SET_COMPS_TREE(JSON.parse(data));
+          this.handleOption();
+        }
+      });
     }
     private setDashboardTemplates(allTemplate: ITemplate[]) {
       const template = allTemplate.filter((item: ITemplate) => item.type === 'DASHBOARD' && item.activated);