Просмотр исходного кода

#13946 Improve Access Control And System settings
#13655 Settlement modules

vbea 2 лет назад
Родитель
Сommit
7981be46c7

+ 22 - 0
Strides-Admin/src/router/FinancialRouter.js

@@ -43,6 +43,28 @@ export default {
         activeIcon: 'sidebar-submenu-item-active',
         affix: false
       }
+    },
+    {
+      path: '/financial-management/billing-account-mgmt',
+      component: () => import('@/views/settlement/billingAccount'),
+      name: 'FinancialTopup',
+      meta: {
+        title: 'Billing Account Management',
+        icon: 'sidebar-submenu-item',
+        activeIcon: 'sidebar-submenu-item-active',
+        affix: false
+      }
+    },
+    {
+      path: '/financial-management/account-settlement',
+      component: () => import('@/views/settlement/index'),
+      name: 'FinancialTopup',
+      meta: {
+        title: 'Account Settlement',
+        icon: 'sidebar-submenu-item',
+        activeIcon: 'sidebar-submenu-item-active',
+        affix: false
+      }
     }
   ]
 }

+ 1 - 0
Strides-Admin/src/styles/sidebar.scss

@@ -82,6 +82,7 @@
     .el-menu-item {
       height: 40px;
       display: flex;
+      padding: 0 10px;
       line-height: 48px;
       align-items: center;
       flex-direction: row;

+ 16 - 4
Strides-Admin/src/views/access/DialogDetail.vue

@@ -123,7 +123,7 @@
           class="form-item"
           label="GROUP NAME:"
           prop="groupPk"
-          v-if="form.roleName=='GROUP'">
+          v-else-if="form.roleName=='GROUP'">
           <el-select
             v-model="form.groupPk"
             class="flex-item2">
@@ -138,10 +138,10 @@
           class="form-item"
           label="SITE ALLOCATION:"
           prop="sitePks"
-          v-if="form.roleName=='SITE'">
+          v-else-if="form.roleName=='SITE'">
           <el-select
             v-model="form.sitePks"
-            class="flex-item2"
+            class="flex-item"
             filterable
             multiple
             placeholder="Select with search">
@@ -152,6 +152,7 @@
               :value="item.sitePk"/>
           </el-select>
         </el-form-item>
+        <div class="form-item flex-item" v-else></div>
       </div>
       <div class="flexcc" style="margin-top: 10px;">
         <el-button
@@ -425,9 +426,19 @@ export default {
 </script>
 
 <style scoped>
+.dialog-access {
+  display: flex;
+  align-items: center;
+  flex-direction: column;
+  justify-content: center;
+}
 .dialog-access >>> .el-dialog {
   width: 100%;
   max-width: 600px;
+  margin-top: 0 !important;
+}
+.dialog-access >>> .el-dialog__body {
+  padding: 10px 20px 30px;
 }
 .dialog-access >>> .el-form {
   padding-right: 10px;
@@ -435,7 +446,7 @@ export default {
 .form-row {
   display: flex;
   flex-wrap: wrap;
-  padding: 0 0 10px;
+  padding-bottom: 5px;
 }
 .form-item {
   flex: 1;
@@ -446,6 +457,7 @@ export default {
   padding: 0;
 }
 .flex-item {
+  width: 100%;
   min-width: 200px;
   max-width: 270px;
 }

+ 2 - 9
Strides-Admin/src/views/access/index.vue

@@ -5,6 +5,7 @@
         <el-select
           v-model="params.pageVo.roleName"
           class="filter-view-item"
+          placeholder="Role"
           @change="toSearch"
           clearable>
           <el-option
@@ -23,20 +24,12 @@
             @change="toSearch"
             clearable/>
         </div>
-        <div>
-          <el-button
-            type="primary"
-            icon="el-icon-search"
-            @click="toSearch">
-            Search
-          </el-button>
-        </div>
         <div class="filter-flex-button">
           <el-button
             type="primary"
             icon="el-icon-plus"
             @click="addUser">
-            Add
+            Add User
           </el-button>
         </div>
       </div>

+ 2 - 8
Strides-Admin/src/views/article/typeList.vue

@@ -19,15 +19,9 @@
           v-model="filters.pageVo.criteria"
           placeholder="Search by Type Name"
           prefix-icon="el-icon-search"
+          @keyup.enter.native="onClickSearch"
+          @change="onClickSearch"
           clearable/>
-        <div>
-          <el-button
-            @click="onClickSearch"
-            icon="el-icon-search"
-            type="primary">
-            Search
-          </el-button>
-        </div>
         <div
           class="filter-flex-button"
           v-if="!$route.meta.onlyView">

+ 2 - 2
Strides-Admin/src/views/driver/DriverDetail.vue

@@ -331,12 +331,12 @@ export default {
       const IMAGE_TYPE_ARRAY = ['jpg', 'png', 'jpeg', 'gif']
       const fileExt = file.name.replace(/.+\./, '').toLowerCase()
       if (IMAGE_TYPE_ARRAY.indexOf(fileExt) === -1) {
-        const msg = `请选择类型为${IMAGE_TYPE_ARRAY.join('、')}的文件`
+        const msg = `Please upload file type with ${IMAGE_TYPE_ARRAY.join('、')}`
         this.$message.warning(msg)
         return false
       }
       if (file.size / 1024 / 1024 > 2) {
-        this.$message.warning('上传文件不能超过2m')
+        this.$message.warning('Uploading files cannot exceed 2MB')
         return false
       }
     },

+ 3 - 3
Strides-Admin/src/views/report/ReportV2.vue

@@ -30,7 +30,7 @@
           clearable
           @change="changeDateRange"
           class="filter-input"
-          v-if="filter.pageVo.reportType === 'APENDIXF' || filter.pageVo.reportType === 'APENDIXH'"/>
+          v-if="filter.pageVo.reportType === 'APENDIXF'"/>
         <el-date-picker
           v-model="filter.pageVo.year"
           type="year"
@@ -39,9 +39,9 @@
           :clearable="false"
           class="filter-input half"
           placeholder="Filter Year"
-          v-show="filter.pageVo.reportType != 'APENDIXF' && filter.pageVo.reportType != 'APENDIXH'"/>
+          v-show="filter.pageVo.reportType != 'APENDIXF'"/>
         <el-select
-          v-show="filter.pageVo.reportType != 'APENDIXF' && filter.pageVo.reportType != 'APENDIXH'"
+          v-show="filter.pageVo.reportType != 'APENDIXF'"
           v-model="filter.pageVo.month"
           class="filter-input half"
           placeholder="Filter Month"

+ 156 - 0
Strides-Admin/src/views/settlement/billingAccount.vue

@@ -0,0 +1,156 @@
+<template>
+  <div class="app-container">
+    <div class="filter-container">
+      <div class="filter-view">
+        <el-select
+          class="filter-input"
+          placeholder="Account Type"
+          clearable
+          @change="onClickSearch"
+          v-model="filters.pageVo.accountTypeId">
+          <el-option
+            v-for="(item,index) in options.types"
+            :key="index"
+            :label="item.name"
+            :value="item.value"/>
+        </el-select>
+        <el-input
+          v-model="filters.pageVo.criteria"
+          placeholder="Entity Name, POC Name, POC Email"
+          prefix-icon="el-icon-search"
+          style="max-width: 300px;"
+          @change="onClickSearch"
+          @keyup.enter.native="onClickSearch"
+          clearable/>
+      </div>
+    </div>
+    <el-table
+      v-loading="table.loading"
+      :data="table.list">
+      <el-table-column
+        align="center"
+        label="Entity Name"
+        prop="articleTitle"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="Account Type"
+        prop="articleTitle"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="POC Name"
+        prop="articleTitle"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="POC Email"
+        prop="articleTitle"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="Effective Date"
+        prop="articleTitle"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="Billing Date"
+        prop="articleTitle"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="Update Date Time"
+        prop="articleTitle"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="Status"
+        prop="articleTitle"
+        min-width="120"/>
+      <el-table-column
+        align="center"
+        label="Action"
+        min-width="120"
+        v-if="!$route.meta.onlyView">
+        <template v-slot="{ row }">
+          <TableAction
+            @edit="onClickEdit(row)"
+            @delete="onClickDelete(row)"
+            v-if="row.dataStatus != 'Inactive'"/>
+        </template>
+      </el-table-column>
+    </el-table>
+    <div class="right">
+      <pagination
+        v-show="table.total > 0"
+        :total="table.total"
+        :page.sync="filters.pageNo"
+        :limit.sync="filters.pageSize"
+        @pagination="getTableData" />
+    </div>
+  </div>
+</template>
+
+<script>
+import TableAction from '@/components/TableAction.vue'
+import Pagination from '@/components/Pagination'
+export default {
+  data() {
+    return {
+      filters: {
+        pageNo: 1,
+        pageSize: 10,
+        pageVo: {
+          criteria: "",
+          dataStatus: "",
+          accountTypeId: ""
+        }
+      },
+      table: {
+        list: [],
+        total: 0,
+        loading: false
+      },
+      options: {
+        status: [],
+        types: []
+      }
+    };
+  },
+  components: { Pagination, TableAction },
+  created() {
+    //this.onClickSearch();
+  },
+  methods: {
+    onClickSearch() {
+      this.filters.pageNo = 1
+      this.getTableData()
+    },
+    getTableData() {
+      this.table.loading = true;
+      api.getSettlementPages(this.filters).then(res => {
+        if (res.data && res.total) {
+          this.table.total = res.total;
+          this.table.list = res.data;
+        } else {
+          this.table.total = 0;
+          this.table.list = [];
+        }
+      }).catch(err => {
+        this.$message({
+          type: 'error',
+          message: err
+        })
+        this.table.total = 0;
+        this.table.list = [];
+      }).finally(() => {
+        this.table.loading = false;
+      })
+    },
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 156 - 0
Strides-Admin/src/views/settlement/index.vue

@@ -0,0 +1,156 @@
+<template>
+  <div class="app-container">
+    <div class="filter-container">
+      <div class="filter-view">
+        <el-select
+          class="filter-input"
+          placeholder="Account Type"
+          clearable
+          @change="onClickSearch"
+          v-model="filters.pageVo.accountTypeId">
+          <el-option
+            v-for="(item,index) in options.types"
+            :key="index"
+            :label="item.name"
+            :value="item.value"/>
+        </el-select>
+        <el-input
+          v-model="filters.pageVo.criteria"
+          placeholder="Entity Name, POC Name, POC Email"
+          prefix-icon="el-icon-search"
+          style="max-width: 300px;"
+          @change="onClickSearch"
+          @keyup.enter.native="onClickSearch"
+          clearable/>
+      </div>
+    </div>
+    <el-table
+      v-loading="table.loading"
+      :data="table.list">
+      <el-table-column
+        align="center"
+        label="Entity Name"
+        prop="articleTitle"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="Account Type"
+        prop="articleTitle"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="POC Name"
+        prop="articleTitle"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="POC Email"
+        prop="articleTitle"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="Generated Date"
+        prop="articleTitle"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="Update Date Time"
+        prop="articleTitle"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="Amount"
+        prop="articleTitle"
+        min-width="150"/>
+      <el-table-column
+        align="center"
+        label="Status"
+        prop="articleTitle"
+        min-width="120"/>
+      <el-table-column
+        align="center"
+        label="Action"
+        min-width="120"
+        v-if="!$route.meta.onlyView">
+        <template v-slot="{ row }">
+          <TableAction
+            @edit="onClickEdit(row)"
+            @delete="onClickDelete(row)"
+            v-if="row.dataStatus != 'Inactive'"/>
+        </template>
+      </el-table-column>
+    </el-table>
+    <div class="right">
+      <pagination
+        v-show="table.total > 0"
+        :total="table.total"
+        :page.sync="filters.pageNo"
+        :limit.sync="filters.pageSize"
+        @pagination="getTableData" />
+    </div>
+  </div>
+</template>
+
+<script>
+import TableAction from '@/components/TableAction.vue'
+import Pagination from '@/components/Pagination'
+export default {
+  data() {
+    return {
+      filters: {
+        pageNo: 1,
+        pageSize: 10,
+        pageVo: {
+          criteria: "",
+          dataStatus: "",
+          accountTypeId: ""
+        }
+      },
+      table: {
+        list: [],
+        total: 0,
+        loading: false
+      },
+      options: {
+        status: [],
+        types: []
+      }
+    };
+  },
+  components: { Pagination, TableAction },
+  created() {
+    //this.onClickSearch();
+  },
+  methods: {
+    onClickSearch() {
+      this.filters.pageNo = 1
+      this.getTableData()
+    },
+    getTableData() {
+      this.table.loading = true;
+      api.getSettlementPages(this.filters).then(res => {
+        if (res.data && res.total) {
+          this.table.total = res.total;
+          this.table.list = res.data;
+        } else {
+          this.table.total = 0;
+          this.table.list = [];
+        }
+      }).catch(err => {
+        this.$message({
+          type: 'error',
+          message: err
+        })
+        this.table.total = 0;
+        this.table.list = [];
+      }).finally(() => {
+        this.table.loading = false;
+      })
+    },
+  }
+}
+</script>
+
+<style scoped>
+
+</style>

+ 1 - 0
Strides-Admin/src/views/user/index.vue

@@ -58,6 +58,7 @@
           v-model="filters.pageVo.criteria"
           prefix-icon="el-icon-search"
           placeholder="Email, Name, License Plate"
+          @keyup.enter.native="onClickSearch"
           @change="onClickSearch"
           clearable/>
         <div v-if="false">

+ 134 - 227
Strides-Admin/src/views/zetting/Administrator.vue

@@ -5,182 +5,67 @@
       :rules="rule"
       v-loading="loading"
       ref="settingsForm"
-      label-position="left"
-      label-width="150px"
-      style="width: 100%;">
-      <div class="card-content">
-        <!-- <div class="section-title">OCPP Settings</div>
-        <el-row :gutter="20">
-          <el-col :xs="24" :sm="16" :md="12" :lg="9">
-            <div class="flexc">
-              <el-form-item
-                label="Heartbeat Interval:"
-                prop="heartbeat"
-                class="flex1">
-                <el-input
-                  class="value-text"
-                  v-model="settingsForm.heartbeat"
-                  placeholder="Add text"
-                  maxlength="5"/>
-              </el-form-item>
-              <span class="el-form-item">&nbsp;&nbsp;Minutes</span>
-            </div>
-            <div class="tips">The time interval in <i>minutes</i> for how often a charge point should request the current time from the CSMS.</div>
-          </el-col>
-          <el-col :xs="4" :sm="8" :md="2" :lg="6">
-            <p></p>
-          </el-col>
-          <el-col :xs="24" :sm="16" :md="10" :lg="8">
-            <div class="flexc">
-              <el-form-item
-                label="Expiration:"
-                prop="expiration"
-                label-width="95px"
-                class="flex1">
-                <el-input
-                  class="value-text"
-                  v-model="settingsForm.expiration"
-                  placeholder="Add text"
-                  maxlength="5"/>
-              </el-form-item>
-              <span class="el-form-item">&nbsp;&nbsp;Hours</span>
-            </div>
-            <div class="tips" style="padding-left: 95px;">The amount of time in <i>hours</i> for how long a charge point should cache the authorization info of an idTag in its local white list, if an expiry date is not explicitly set. 
-            The value 0 disables this functionality 
-              (i.e.no expiry date will be set).</div>
-          </el-col>
-        </el-row>
-        <div class="hr"></div> -->
-        <div class="section-title">
-          <span style="padding-right: 30px;">Mail Notification Settings</span>
-          <el-checkbox v-model="settingsForm.enabled">Enable notifications</el-checkbox>
-        </div>
-        <el-row :gutter="20">
-          <el-col :xs="24" :sm="16" :md="10" :lg="9">
-            <el-form-item
-              label="Protocol:"
-              prop="protocol">
-              <el-input
-                class="add-text"
-                v-model="settingsForm.protocol"
-                placeholder="Add text"
-                maxlength="10"/>
-            </el-form-item>
-          </el-col>
-          <el-col :xs="4" :sm="8" :md="4" :lg="6" :xl="6">
-            <p></p>
-          </el-col>
-          <el-col :xs="24" :sm="16" :md="10" :lg="9" :xl="9" v-if="featuresGroup >= 1" style="overflow: hidden;">
-            <el-checkbox-group v-model="settingsForm.enabledFeatures">
-              <template v-for="(item, index) in features">
-                <el-checkbox
-                  :key="index"
-                  v-if="index < 2"
-                  :label="item.value">{{item.name}}</el-checkbox>
-              </template>
-            </el-checkbox-group>
-          </el-col>
-        </el-row>
-        <el-row :gutter="20">
-          <el-col :xs="24" :sm="16" :md="10" :lg="9">
-            <el-form-item
-              label="Host:"
-              prop="host">
-              <el-input
-                class="add-text"
-                v-model="settingsForm.host"
-                placeholder="Add text"
-                maxlength="30"/>
-            </el-form-item>
-          </el-col>
-          <el-col :xs="4" :sm="8" :md="4" :lg="6" :xl="6">
-            <p></p>
-          </el-col>
-          <el-col :xs="24" :sm="16" :md="10" :lg="9" :xl="9" v-if="featuresGroup >= 2" style="overflow: hidden;">
-            <el-checkbox-group v-model="settingsForm.enabledFeatures">
-              <template v-for="(item, index) in features">
-                <el-checkbox
-                  :key="index"
-                  v-if="index >= 2 && index < 4"
-                  :label="item.value">{{item.name}}</el-checkbox>
-              </template>
-            </el-checkbox-group>
-          </el-col>
-        </el-row>
-        <el-row :gutter="20">
-          <el-col :xs="24" :sm="16" :md="10" :lg="9">
-            <el-form-item
-              label="Port:"
-              prop="port">
-              <el-input
-                class="add-text"
-                v-model="settingsForm.port"
-                placeholder="Add text"
-                maxlength="5"/>
-            </el-form-item>
-          </el-col>
-          <el-col :xs="4" :sm="8" :md="4" :lg="6" :xl="6">
-            <p></p>
-          </el-col>
-          <el-col :xs="24" :sm="16" :md="10" :lg="9" :xl="9" v-if="featuresGroup >= 3" style="overflow: hidden;">
-            <el-checkbox-group v-model="settingsForm.enabledFeatures">
-              <template v-for="(item, index) in features">
-                <el-checkbox
-                  :key="index"
-                  v-if="index >= 4 && index < 6"
-                  :label="item.value">{{item.name}}</el-checkbox>
-              </template>
-            </el-checkbox-group>
-          </el-col>
-        </el-row>
-        <el-row :gutter="20">
-          <el-col :xs="24" :sm="16" :md="10" :lg="9">
-            <el-form-item
-              label="From:"
-              prop="from">
-              <el-input
-                class="add-text"
-                v-model="settingsForm.from"
-                placeholder="Add text"
-                maxlength="50"/>
-            </el-form-item>
-          </el-col>
-          <el-col :xs="4" :sm="8" :md="4" :lg="6" :xl="6">
-            <p></p>
-          </el-col>
-          <el-col :xs="24" :sm="16" :md="10" :lg="9" :xl="9" v-if="featuresGroup >= 3" style="overflow: hidden;">
-            <el-checkbox-group v-model="settingsForm.enabledFeatures">
-              <template v-for="(item, index) in features">
-                <el-checkbox
-                  :key="index"
-                  v-if="index >= 6 && index < 8"
-                  :label="item.value">{{item.name}}</el-checkbox>
-              </template>
-            </el-checkbox-group>
-          </el-col>
-        </el-row>
-        <el-row :gutter="20">
-          <el-col :xs="24" :sm="16" :md="10" :lg="9">
-            <el-form-item
-              label="Username:"
-              prop="username">
-              <el-input
-                class="add-text"
-                v-model="settingsForm.username"
-                placeholder="Add text"
-                maxlength="30"/>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-row :gutter="20">
-          <el-col :xs="24" :sm="16" :md="10" :lg="9">
-            <el-form-item
-              label="Password:"
-              prop="password">
-              <div class="flexc">
+      label-position="right"
+      label-width="110px">
+      <div class="flexr">
+        <div class="card-content">
+          <div class="section-title">
+            <span style="padding-right: 30px;">Mail Notification Settings</span>
+            <el-checkbox v-model="settingsForm.enabled">Enable notifications</el-checkbox>
+          </div>
+          <el-form-item
+            label="Protocol:"
+            prop="protocol">
+            <el-input
+              class="add-text"
+              v-model="settingsForm.protocol"
+              placeholder="Add text"
+              maxlength="10"/>
+          </el-form-item>
+          <el-form-item
+            label="Host:"
+            prop="host">
+            <el-input
+              class="add-text"
+              v-model="settingsForm.host"
+              placeholder="Add text"
+              maxlength="30"/>
+          </el-form-item>
+          <el-form-item
+            label="Port:"
+            prop="port">
+            <el-input
+              class="add-text"
+              v-model="settingsForm.port"
+              placeholder="Add text"
+              maxlength="5"/>
+          </el-form-item>
+          <el-form-item
+            label="From:"
+            prop="from">
+            <el-input
+              class="add-text"
+              v-model="settingsForm.from"
+              placeholder="Add text"
+              maxlength="50"/>
+          </el-form-item>
+          <el-form-item
+            label="Username:"
+            prop="username">
+            <el-input
+              class="add-text"
+              v-model="settingsForm.username"
+              placeholder="Add text"
+              maxlength="30"/>
+          </el-form-item>
+          <el-form-item
+            label="Password:"
+            prop="password">
+            <div class="add-text flexcr" style="margin: -5px 0;">
+              <div class="flex1">
                 <el-input
-                  class="add-text pwd"
                   ref="password"
+                  class="add-text"
                   :type="passwordType"
                   v-model="settingsForm.password"
                   placeholder="Email password"
@@ -189,61 +74,73 @@
                   <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" />
                 </span>
               </div>
-            </el-form-item>
-          </el-col>
-          <el-col :span="8">
-            <el-button
-              type="primary"
-              @click="sendTestMail">
-              Send Test Mail
-            </el-button>
-          </el-col>
-        </el-row>
-        <el-form
-          :model="this"
-          :rules="rule"
-          ref="recipForm"
-          label-position="left"
-          label-width="150px">
-          <el-row :gutter="20">
-            <el-col :xs="24" :sm="16" :md="10" :lg="9">
-              <el-form-item
-                label="Recipients:"
-                prop="recipient">
-                <el-input
-                  class="add-text"
-                  v-model="recipient"
-                  placeholder="Add text"
-                  maxlength="50"/>
-              </el-form-item>
-            </el-col>
-            <el-col :span="8">
+              <div class="divide10"></div>
               <el-button
                 type="primary"
-                icon="el-icon-plus"
-                @click="addRecipient">
-                Add
+                @click="sendTestMail"
+                style="margin: 5px 0;">
+                Send Test Mail
               </el-button>
-            </el-col>
-          </el-row>
-        </el-form>
-        <el-row :gutter="20">
-          <el-col :xs="24" :sm="16" :md="10" :lg="9">
+            </div>
+          </el-form-item>
+          <el-form
+            :model="this"
+            :rules="rule"
+            ref="recipForm"
+            label-width="110px"
+            label-position="right">
             <el-form-item
-              label="Added Recipients:"
-              prop="chargeBoxId">
-              <div class="receip-item" v-for="(item, index) in settingsForm.recipients" :key="index">
-                <span>{{item}}</span>
-                <i class="el-icon-close" @click="deleteRecipient(index)"></i>
+              label="Recipients:"
+              prop="recipient">
+              <div class="add-text flexcr" style="margin: -5px 0;">
+                <div class="flex1">
+                  <el-input
+                    class="add-text"
+                    v-model="recipient"
+                    placeholder="Add text"
+                    maxlength="50"/>
+                </div>
+                <div class="divide10"></div>
+                <el-button
+                  type="primary"
+                  icon="el-icon-plus"
+                  @click="addRecipient"
+                  style="margin: 5px 0;">
+                  Add
+                </el-button>
               </div>
-              <div
-                class="link-button"
-                v-if="settingsForm.recipients.length > 0"
-                @click="clearAllRecipient">Clear All</div>
-              <div class="el-form-item__error" v-else-if="manualValid">Please add at least one recipient</div>
             </el-form-item>
-          </el-col>
-        </el-row>
+          </el-form>
+          <el-form-item
+            label=""
+            prop="chargeBoxId"
+            label-width="0">
+            <label class="el-form-item__label">Added Recipients:</label>
+            <div class="receip-item" v-for="(item, index) in settingsForm.recipients" :key="index">
+              <span>{{item}}</span>
+              <i class="el-icon-close" @click="deleteRecipient(index)"></i>
+            </div>
+            <div
+              class="link-button"
+              v-if="settingsForm.recipients.length > 0"
+              @click="clearAllRecipient">Clear All</div>
+            <div class="el-form-item__error" v-else-if="manualValid">Please add at least one recipient</div>
+          </el-form-item>
+        </div>
+        <div class="card-content">
+          <div class="section-title">
+            <span style="padding-right: 10px;"></span>
+          </div>
+          <el-checkbox-group
+            class="features-group"
+            v-model="settingsForm.enabledFeatures">
+            <template v-for="(item, index) in features">
+              <el-checkbox
+                :key="index"
+                :label="item.value">{{item.name}}</el-checkbox>
+            </template>
+          </el-checkbox-group>
+        </div>
       </div>
       <div class="card-content">
         <div class="buttons">
@@ -341,7 +238,6 @@
           "enabledFeatures": []
         },
         features: [],
-        featuresGroup: 0,
         manualValid: false,
         //chargeTypeOptions: [],
         passwordType: "password"
@@ -356,7 +252,6 @@
         const res = await api.getFeatures();
         if (res.data && res.data.length > 0) {
           this.features = res.data;
-          this.featuresGroup = res.data.length / 2
         }
         //this.getChargeTypeOptions()
         this.getSettings();
@@ -495,6 +390,7 @@
 </style>
 <style scoped="scoped">
   .card-content {
+    flex: 1;
     min-width: 500px;
     margin: 0 8px 16px;
     padding: 15px 50px;
@@ -515,7 +411,7 @@
   .add-text {
     width: 100%;
     min-width: 150px;
-    max-width: 300px;
+    max-width: 400px;
   }
   .add-text ::v-deep .el-textarea__inner {
     font-family: sans-serif;
@@ -603,7 +499,12 @@
   .link-button:hover {
     color: #ff5500;
   }
-  
+  .divide10 {
+    width: 10px;
+  }
+  .features-group {
+    min-width: 400px;
+  }
   @media screen and (max-width: 800px) {
     .card-container {
       padding: 10px 20px;
@@ -621,6 +522,12 @@
     .card-content {
       padding: 15px 20px;
     }
+    .divide10 {
+      display: none;
+    }
+    .features-group {
+      min-width: 80vw;
+    }
   }
   .el-checkbox-group .el-checkbox {
     display: flex;