From 6d83a227b052837bee36a08503a042b90e5cf1cb Mon Sep 17 00:00:00 2001
From: Christian Hofmaier
Date: Mon, 20 May 2019 01:56:40 +0000
Subject: [permissionmanager] frontend rework - bulk call for loading childs of
 groups - change submit to save/create - reload site after role changes - skip
 blacklist when no groups selected - performance improvements - new dialog
 system

---
 .../src/components/PermissionModuleGrantRevoke.vue | 166 ++++++---------------
 1 file changed, 44 insertions(+), 122 deletions(-)

(limited to 'webapp/src/components/PermissionModuleGrantRevoke.vue')

diff --git a/webapp/src/components/PermissionModuleGrantRevoke.vue b/webapp/src/components/PermissionModuleGrantRevoke.vue
index a137ea1..10a5ad6 100644
--- a/webapp/src/components/PermissionModuleGrantRevoke.vue
+++ b/webapp/src/components/PermissionModuleGrantRevoke.vue
@@ -10,8 +10,8 @@
     "id": "ID",
     "name": "Name",
     "description": "Description",
-    "roleGrantedSuccess" : "Roles successfully granted.",
-    "roleRevokedSuccess" : "Roles successfully revoked."
+    "roleGrantedSuccess" : "Role successfully granted. | Roles successfully granted.",
+    "roleRevokedSuccess" : "Role successfully revoked. | Roles successfully revoked."
   },
   "de": {
     "select_roles": "Rollen auswählen",
@@ -23,98 +23,30 @@
     "id": "ID",
     "name": "Name",
     "description": "Beschreibung",
-    "roleGrantedSuccess" : "Rollen erfolgreich zugewiesen.",
-    "roleRevokedSuccess" : "Rollen erfolgreich entzogen."
+    "roleGrantedSuccess" : "Rolle erfolgreich zugewiesen. | Rollen erfolgreich zugewiesen.",
+    "roleRevokedSuccess" : "Rolle erfolgreich entzogen. | Rollen erfolgreich entzogen."
   }
 }
 </i18n>
 
 <template>
-  <v-dialog
-    :value="$store.state.permissions.grantRevoke"
-    @input="$store.commit('permissions/setGrantRevoke', $event)"
-    max-width="800px"
-    scrollable
-  >
-    <v-card>
-      <v-card-title class="dialog-title">
-        <v-stepper v-model="step" horizontal  style="width: 100%; background: transparent;" class="elevation-3">
-          <v-stepper-header>
-            <v-stepper-step
-              :complete="stepCompleted >= 1"
-              step="1"
-              :editable="stepCompleted >= 0"
-              edit-icon="check"
-            >
-              {{ $t('select_roles') }}
-            </v-stepper-step>
-            <v-divider></v-divider>
-            <v-stepper-step
-              :complete="stepCompleted >= 2"
-              step="2"
-              :editable="stepCompleted >= 1"
-              edit-icon="check"
-            >
-              {{ $t('check_selection') }}
-            </v-stepper-step>
-          </v-stepper-header>
-        </v-stepper>
-      </v-card-title>
-      <v-card-text class="table-container">
-        <v-form v-model="valid" ref="form" @submit.prevent="submit" lazy-validation>
-          <v-stepper v-model="step" horizontal style="width: 100%; background: transparent" class="elevation-0">
-            <v-stepper-items>
-              <v-stepper-content step="1" class="stepper-padding-0">
-                <data-table v-model="selectedRoles" :headers="roleHeaders" :items="roles"/>
-              </v-stepper-content>
-              <v-stepper-content step="2">
-                <v-layout row wrap>
-                  <v-flex>
-                    <v-list subheader>
-                      <v-subheader inset>{{ $t('roles') }}</v-subheader>
-                      <v-divider class="list-header-margin"></v-divider>
-                      <v-list-tile
-                        v-for="role in selectedRoles"
-                        :key="role.id"
-                      >
-                        <v-list-tile-content>
-                          <v-list-tile-title>{{ role.name }}</v-list-tile-title>
-                          <v-list-tile-sub-title>{{ role.descr }}</v-list-tile-sub-title>
-                        </v-list-tile-content>
-                      </v-list-tile>
-                    </v-list>
-                  </v-flex>
-                  <v-flex>
-                    <v-list subheader>
-                      <v-subheader inset>{{ $t('users') }}</v-subheader>
-                      <v-divider class="list-header-margin"></v-divider>
-                      <v-list-tile
-                        v-for="user in selectedUsers"
-                        :key="user.username"
-                      >
-                        <v-list-tile-content>
-                          <v-list-tile-title>{{ user.username }}</v-list-tile-title>
-                          <v-list-tile-sub-title>{{ user.name }}</v-list-tile-sub-title>
-                        </v-list-tile-content>
-                      </v-list-tile>
-                    </v-list>
-                  </v-flex>
-                </v-layout>
-              </v-stepper-content>
-            </v-stepper-items>
-          </v-stepper>
-        </v-form>
-      </v-card-text>
-      <v-divider></v-divider>
-      <v-card-actions>
-        <v-spacer></v-spacer>
-        <v-btn flat @click.native="$store.commit('permissions/setGrantRevoke', false )">{{ $t('cancel') }}</v-btn>
-        <v-btn color="primary" v-show="step == 1" @click.native="completeStepOne()">{{ $t('continue') }}</v-btn>
-        <v-btn type="submit" @click="submit" v-show="step == 2" v-if="grant" class="success">{{ $t('grant') }}</v-btn>
-        <v-btn type="submit" @click="submit" v-show="step == 2" v-else class="error">{{ $t('revoke') }}</v-btn>
-      </v-card-actions>
-    </v-card>
-  </v-dialog>
+  <v-card>
+    <v-card-title class="dialog-title elevation-3">
+      <div class="headline">{{ $t('select_roles') }}</div>
+    </v-card-title>
+    <v-card-text class="pa-0">
+      <v-form v-model="valid" ref="form" @submit.prevent="submit" lazy-validation>
+        <data-table v-model="selectedRoles" :headers="roleHeaders" :items="roles"/>
+      </v-form>
+    </v-card-text>
+    <v-divider></v-divider>
+    <v-card-actions>
+      <v-spacer></v-spacer>
+      <v-btn flat @click.native="$store.commit('permissions/setDialog', { show : false } )">{{ $t('cancel') }}</v-btn>
+      <v-btn type="submit" @click="submit" v-if="grant" class="success">{{ $t('grant') }}</v-btn>
+      <v-btn type="submit" @click="submit" v-if="revoke" class="error">{{ $t('revoke') }}</v-btn>
+    </v-card-actions>
+  </v-card>
 </template>
 
 <script>
@@ -123,16 +55,15 @@ import DataTable from '@/components/DataTable'
 
 export default {
   name: 'PermissionModuleGrantRevoke',
-  props: ['grant'],
   components: {
     DataTable
   },
   data () {
     return {
       valid: true,
-      step: 1,
-      stepCompleted: 0,
       selectedRoles: [],
+      grant: false,
+      revoke: false,
       roleHeaders: [
         { text: this.$t('id'), key: 'id' },
         { text: this.$t('name'), key: 'name' },
@@ -142,36 +73,35 @@ export default {
   },
   methods: {
     async submit (event) {
-      const roleIds = this.selectedRoles.map(x => x.id)
-      for (let i = 0; i < this.selectedUsers.length; i++) {
-        await this.$http.post('/api/users/' + this.selectedUsers[i].id + '/roles' + (this.grant ? '' : '/?delete'), { ids: roleIds })
-      }
+      const roleIds = this.selectedRoles.map(r => r.id)
+      const userIds = this.selectedUsers.map(u => u.id)
+      await this.$http.post('/api/users/roles' + (this.grant ? '' : '?delete'), {
+        roles: roleIds,
+        users: userIds
+      })
       if (this.grant) {
-        this.$snackbar({ color: 'success', text: this.$t('roleGrantedSuccess') })
-      } else {
-        this.$snackbar({ color: 'success', text: this.$t('roleRevokedSuccess') })
+        this.$snackbar({ color: 'success', text: this.$tc('roleGrantedSuccess', [roleIds.length]) })
+      } else if (this.revoke) {
+        this.$snackbar({ color: 'success', text: this.$tc('roleRevokedSuccess', [roleIds.length]) })
       }
-      this.$store.dispatch('permissions/loadUserData')
-      this.$store.commit('permissions/setGrantRevoke', false)
+      this.$store.dispatch('users/loadData')
+      this.$store.commit('permissions/setDialog', { show: false })
       this.$store.commit('permissions/setSelectedUsers', [])
-    },
-    completeStepOne () {
-      this.step = 2
-      this.stepCompleted = Math.max(1, this.stepCompleted)
     }
   },
   computed: {
-    ...mapState('permissions', ['roles', 'selectedUsers']),
-    grantRevoke: function () {
-      return this.$store.state.permissions.grantRevoke
-    }
+    ...mapState('permissions', ['dialog', 'roles', 'selectedUsers'])
   },
   watch: {
-    grantRevoke: function (value) {
-      if (value) {
-        this.selectedRoles = []
-        this.step = 1
-        this.stepCompleted = 0
+    dialog: {
+      immediate: true,
+      deep: true,
+      handler (value) {
+        if (value.show) {
+          this.selectedRoles = []
+          this.grant = value.type === 'grant' || false
+          this.revoke = value.type === 'revoke' || false
+        }
       }
     }
   }
@@ -180,18 +110,10 @@ export default {
 
 <!-- Add "scoped" attribute to limit CSS to this component only -->
 <style scoped>
-.table-container {
-  padding: 0;
-  height: 700px;
-}
 .stepper-padding-0 {
   padding: 0;
 }
-.list-header-margin {
-  margin-bottom: 10px;
-}
 .dialog-title {
-  padding: 0px;
   z-index: 1;
 }
 </style>
-- 
cgit v1.2.3-55-g7522

