From a6202e7460b5a5b1e65f194bcb6ed38c8048b0aa Mon Sep 17 00:00:00 2001
From: Angelina Filippova <linakirsanova@gmail.com>
Date: Fri, 30 Oct 2020 21:23:23 +0300
Subject: [PATCH] Add dropdown for changing report's state and moderating user

---
 src/store/modules/reports.js                  | 64 ++++++++++++++++---
 .../components/ModerateUserDropdown.vue       | 31 +++++++--
 src/views/reports/components/Report.vue       | 12 ++--
 src/views/reports/show.vue                    | 48 +++++++++++++-
 4 files changed, 134 insertions(+), 21 deletions(-)

diff --git a/src/store/modules/reports.js b/src/store/modules/reports.js
index 51f08219..c42fa894 100644
--- a/src/store/modules/reports.js
+++ b/src/store/modules/reports.js
@@ -59,6 +59,17 @@ const reports = {
       }
       dispatch('SuccessMessage')
     },
+    async ActivateUserFromReportShow({ commit, dispatch, getters, state }, user) {
+      try {
+        await activateUsers([user.nickname], getters.authHost, getters.token)
+      } catch (_e) {
+        return
+      } finally {
+        const updatedReport = { ...state.singleReport, account: { ...user, deactivated: false }}
+        commit('SET_SINGLE_REPORT', updatedReport)
+      }
+      dispatch('SuccessMessage')
+    },
     async AddTagFromReports({ commit, dispatch, getters, state }, { user, tag, reportId }) {
       try {
         await tagUser([user.nickname], [tag], getters.authHost, getters.token)
@@ -73,16 +84,31 @@ const reports = {
       }
       dispatch('SuccessMessage')
     },
+    async AddTagFromReportsFromReportShow({ commit, dispatch, getters, state }, { user, tag }) {
+      try {
+        await tagUser([user.nickname], [tag], getters.authHost, getters.token)
+      } catch (_e) {
+        return
+      } finally {
+        const updatedReport = { ...state.singleReport, account: { ...user, tags: [...user.tags, tag] }}
+        commit('SET_SINGLE_REPORT', updatedReport)
+      }
+      dispatch('SuccessMessage')
+    },
     async ChangeReportState({ commit, dispatch, getters, state }, reportsData) {
-      changeState(reportsData, getters.authHost, getters.token)
-
-      const updatedReports = state.fetchedReports.map(report => {
-        const updatedReportsIds = reportsData.map(({ id }) => id)
-        return updatedReportsIds.includes(report.id) ? { ...report, state: reportsData[0].state } : report
-      })
+      try {
+        await changeState(reportsData, getters.authHost, getters.token)
+      } catch (_e) {
+        return
+      } finally {
+        const updatedReports = state.fetchedReports.map(report => {
+          const updatedReportsIds = reportsData.map(({ id }) => id)
+          return updatedReportsIds.includes(report.id) ? { ...report, state: reportsData[0].state } : report
+        })
 
-      commit('SET_REPORTS', updatedReports)
-      dispatch('FetchOpenReportsCount')
+        commit('SET_REPORTS', updatedReports)
+        dispatch('FetchOpenReportsCount')
+      }
     },
     ClearFetchedReports({ commit }) {
       commit('SET_REPORTS', [])
@@ -101,6 +127,17 @@ const reports = {
       }
       dispatch('SuccessMessage')
     },
+    async DeactivateUserFromReportShow({ commit, dispatch, getters, state }, user) {
+      try {
+        await deactivateUsers([user.nickname], getters.authHost, getters.token)
+      } catch (_e) {
+        return
+      } finally {
+        const updatedReport = { ...state.singleReport, account: { ...user, deactivated: true }}
+        commit('SET_SINGLE_REPORT', updatedReport)
+      }
+      dispatch('SuccessMessage')
+    },
     async DeleteUserFromReports({ commit, dispatch, getters, state }, { user, reportId }) {
       try {
         await deleteUsers([user.nickname], getters.authHost, getters.token)
@@ -152,6 +189,17 @@ const reports = {
       }
       dispatch('SuccessMessage')
     },
+    async RemoveTagFromReportsFromReportShow({ commit, dispatch, getters, state }, { user, tag }) {
+      try {
+        await untagUser([user.nickname], [tag], getters.authHost, getters.token)
+      } catch (_e) {
+        return
+      } finally {
+        const updatedReport = { ...state.singleReport, account: { ...user, tags: user.tags.filter(userTag => userTag !== tag) }}
+        commit('SET_SINGLE_REPORT', updatedReport)
+      }
+      dispatch('SuccessMessage')
+    },
     SetReportsFilter({ commit }, filter) {
       commit('SET_REPORTS_FILTER', filter)
     },
diff --git a/src/views/reports/components/ModerateUserDropdown.vue b/src/views/reports/components/ModerateUserDropdown.vue
index 9e7fb0ec..2608b540 100644
--- a/src/views/reports/components/ModerateUserDropdown.vue
+++ b/src/views/reports/components/ModerateUserDropdown.vue
@@ -1,6 +1,7 @@
 <template>
   <el-dropdown :hide-on-click="false" trigger="click">
-    <el-button :disabled="!account.id" plain size="small" icon="el-icon-files">{{ $t('reports.moderateUser') }}
+    <el-button :disabled="!account.id" :size="renderedFrom === 'showPage' ? 'medium' : 'small'" plain icon="el-icon-files">
+      {{ $t('reports.moderateUser') }}
       <i class="el-icon-arrow-down el-icon--right"/>
     </el-button>
     <el-dropdown-menu slot="dropdown">
@@ -47,6 +48,10 @@ export default {
     reportId: {
       type: String,
       required: true
+    },
+    renderedFrom: {
+      type: String,
+      required: true
     }
   },
   computed: {
@@ -96,9 +101,15 @@ export default {
       })
     },
     handleDeactivation(user) {
-      user.deactivated
-        ? this.$store.dispatch('ActivateUserFromReports', { user, reportId: this.reportId })
-        : this.$store.dispatch('DeactivateUserFromReports', { user, reportId: this.reportId })
+      if (this.renderedFrom === 'showPage') {
+        user.deactivated
+          ? this.$store.dispatch('ActivateUserFromReportShow', user)
+          : this.$store.dispatch('DeactivateUserFromReportShow', user)
+      } else if (this.renderedFrom === 'reportsPage') {
+        user.deactivated
+          ? this.$store.dispatch('ActivateUserFromReports', { user, reportId: this.reportId })
+          : this.$store.dispatch('DeactivateUserFromReports', { user, reportId: this.reportId })
+      }
     },
     handleDeletion(user) {
       this.$confirm(
@@ -120,9 +131,15 @@ export default {
       return this.$store.state.user.id !== id
     },
     toggleTag(user, tag) {
-      user.tags.includes(tag)
-        ? this.$store.dispatch('RemoveTagFromReports', { user, tag, reportId: this.reportId })
-        : this.$store.dispatch('AddTagFromReports', { user, tag, reportId: this.reportId })
+      if (this.renderedFrom === 'showPage') {
+        user.tags.includes(tag)
+          ? this.$store.dispatch('RemoveTagFromReportsFromReportShow', { user, tag })
+          : this.$store.dispatch('AddTagFromReportsFromReportShow', { user, tag })
+      } else if (this.renderedFrom === 'reportsPage') {
+        user.tags.includes(tag)
+          ? this.$store.dispatch('RemoveTagFromReports', { user, tag, reportId: this.reportId })
+          : this.$store.dispatch('AddTagFromReports', { user, tag, reportId: this.reportId })
+      }
     }
   }
 }
diff --git a/src/views/reports/components/Report.vue b/src/views/reports/components/Report.vue
index 81847635..423aa439 100644
--- a/src/views/reports/components/Report.vue
+++ b/src/views/reports/components/Report.vue
@@ -24,7 +24,11 @@
                   <el-dropdown-item v-if="report.state !== 'closed'" @click.native="changeReportState('closed', report.id)">{{ $t('reports.close') }}</el-dropdown-item>
                 </el-dropdown-menu>
               </el-dropdown>
-              <moderate-user-dropdown v-if="propertyExists(report.account, 'nickname')" :account="report.account" :report-id="report.id" />
+              <moderate-user-dropdown
+                v-if="propertyExists(report.account, 'nickname')"
+                :account="report.account"
+                :report-id="report.id"
+                :rendered-from="'reportsPage'"/>
             </div>
           </div>
           <el-divider class="divider"/>
@@ -74,12 +78,12 @@ export default {
     }
   },
   methods: {
-    changeReportState(state, id) {
-      this.$store.dispatch('ChangeReportState', [{ state, id }])
-    },
     capitalizeFirstLetter(str) {
       return str.charAt(0).toUpperCase() + str.slice(1)
     },
+    changeReportState(state, id) {
+      this.$store.dispatch('ChangeReportState', [{ state, id }])
+    },
     getStateType(state) {
       switch (state) {
         case 'closed':
diff --git a/src/views/reports/show.vue b/src/views/reports/show.vue
index 35468fbb..5f30f376 100644
--- a/src/views/reports/show.vue
+++ b/src/views/reports/show.vue
@@ -12,7 +12,23 @@
         </div>
         <h1 v-else>{{ $t('reports.report') }}</h1>
       </div>
-      <reboot-button/>
+      <div>
+        <el-tag :type="getStateType(report.state)" class="report-tag">{{ capitalizeFirstLetter(report.state) }}</el-tag>
+        <el-dropdown trigger="click">
+          <el-button plain icon="el-icon-edit" class="report-actions-button">{{ $t('reports.changeState') }}<i class="el-icon-arrow-down el-icon--right"/></el-button>
+          <el-dropdown-menu slot="dropdown">
+            <el-dropdown-item v-if="report.state !== 'resolved'" @click.native="changeReportState('resolved', report.id)">{{ $t('reports.resolve') }}</el-dropdown-item>
+            <el-dropdown-item v-if="report.state !== 'open'" @click.native="changeReportState('open', report.id)">{{ $t('reports.reopen') }}</el-dropdown-item>
+            <el-dropdown-item v-if="report.state !== 'closed'" @click.native="changeReportState('closed', report.id)">{{ $t('reports.close') }}</el-dropdown-item>
+          </el-dropdown-menu>
+        </el-dropdown>
+        <moderate-user-dropdown
+          v-if="propertyExists(report.account, 'nickname')"
+          :account="report.account"
+          :report-id="report.id"
+          :rendered-from="'showPage'"/>
+        <reboot-button/>
+      </div>
     </header>
     <h4 v-if="propertyExists(report.account, 'id')" class="id">{{ $t('reports.id') }}: {{ report.id }}</h4>
     <el-card class="report">
@@ -22,12 +38,13 @@
 </template>
 
 <script>
+import ModerateUserDropdown from './components/ModerateUserDropdown'
 import RebootButton from '@/components/RebootButton'
 import ReportContent from './components/ReportContent'
 
 export default {
   name: 'ReportsShow',
-  components: { RebootButton, ReportContent },
+  components: { ModerateUserDropdown, RebootButton, ReportContent },
   computed: {
     loading() {
       return this.$store.state.reports.loading
@@ -40,8 +57,26 @@ export default {
     this.$store.dispatch('NeedReboot')
     this.$store.dispatch('GetNodeInfo')
     this.$store.dispatch('FetchSingleReport', this.$route.params.id)
+    this.$store.dispatch('FetchTagPolicySetting')
   },
   methods: {
+    capitalizeFirstLetter(str) {
+      return str.charAt(0).toUpperCase() + str.slice(1)
+    },
+    async changeReportState(state, id) {
+      await this.$store.dispatch('ChangeReportState', [{ state, id }])
+      this.$store.dispatch('FetchSingleReport', id)
+    },
+    getStateType(state) {
+      switch (state) {
+        case 'closed':
+          return 'info'
+        case 'resolved':
+          return 'success'
+        default:
+          return 'primary'
+      }
+    },
     propertyExists(account, property, _secondProperty) {
       if (_secondProperty) {
         return account[property] && account[_secondProperty]
@@ -62,6 +97,9 @@ export default {
     width: 1000px;
     margin: auto;
   }
+  .report-actions-button {
+    margin: 3px 0 6px;
+  }
   .report-page-header {
     display: flex;
     flex-direction: column;
@@ -94,5 +132,11 @@ export default {
     margin: 0 15px;
     padding: 0;
   }
+  .report-tag {
+    height: 36px;
+    line-height: 36px;
+    padding: 0 20px;
+    font-size: 14px;
+  }
 }
 </style>
-- 
GitLab