summaryrefslogblamecommitdiffstats
path: root/webapp/src/components/PermissionModuleEdit.vue
blob: f88eb4cfbe56c2a6dc4842734424f6c976d2aa3e (plain) (tree)
1
2
3
4
5
6
7
8
9
10


         
                             

                                       
                       


                                 
                   
                            
                                                      



                                                          

         
                             

                                        
                        


                            
                    
                             
                                                             



                                                                      







                                                         
                      
              
              

            
                                         




                                                                                                                
                                            







                                            
                                            







                                            
                                            







                                            
                                            

                               








                                            
                                 



                             
                                           




                                                                                                                


                                         


                                      

                                                                         
                                









                                            

                                  
                                                                    
                                                                                                             

                                  
                                                                    




                                                                                                  

                                  
                                          




















                                                                         
                                   

                                   
                                                                              
                                                                        

                                                    
                                       
                                 
                       





                                                                                 
                           

                                   
                                                                         
                                                                        
                                      
                                          
                                       














                                                                                           
                                       
                                 
                       





                                                                                           









                                  




                                                                                                                  

                                                                                                                 





                       
                                              
                               



                               
               
             
    




                       
                          
                              

                    
                          


                                                                  

                     

                                               
                                                            








                                                                           

                                                               
                                                                                      



                                           
                                 
                                      
                             
                                                                                 
                                                          
                                                          


                                                          


          
















                                                                    
















                                                            
                       
      


                                                          
      







                                                                                       
        
                                 


             
                                                          






                                               
                                         
                                     

                           
                     

                                    
                                


                             
                                
         



              





                                                                   

                  
                    



                    





                      



               















                                                 
        
<i18n>
{
  "en": {
    "blacklist": "Blacklist",
    "description": "Description",
    "groupdependent": "Groupdependent",
    "groups": "Groups",
    "id": "ID",
    "name": "Name",
    "permissions": "Permissions",
    "role": "Role",
    "roleName": "Role Name",
    "roleNameEmptyError": "Role Name can't be empty.",
    "roleSavedSuccess": "Role saved successfully.",
    "selectChildGroups": "Click to select all subgroups.",
    "submit": "Submit",
    "summary": "Summary"
  },
  "de": {
    "blacklist": "Blacklist",
    "description": "Beschreibung",
    "groupdependent": "Gruppengebunden",
    "groups": "Gruppen",
    "id": "ID",
    "name": "Name",
    "permissions": "Rechte",
    "role": "Rolle",
    "roleName": "Rollenname",
    "roleNameEmptyError": "Rollenname kann nicht leer sein.",
    "roleSavedSuccess": "Rolle erfolgreich gespeichert.",
    "selectChildGroups": "Klicke, um alle Untergruppen auszuwählen.",
    "submit": "Einreichen",
    "summary": "Zusammenfassung"
  }
}
</i18n>

<template>
  <v-dialog
    :value="$store.state.permissions.edit"
    @input="$store.commit('permissions/setEdit', $event)"
    max-width="1000px"
    scrollable
    persistent
  >
    <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('role') }}
            </v-stepper-step>
            <v-divider></v-divider>
            <v-stepper-step
              :complete="stepCompleted >= 2"
              step="2"
              :editable="stepCompleted >= 1"
              edit-icon="check"
            >
              {{ $t('permissions') }}
            </v-stepper-step>
            <v-divider></v-divider>
            <v-stepper-step
              :complete="stepCompleted >= 3"
              step="3"
              :editable="stepCompleted >= 2"
              edit-icon="check"
            >
              {{ $t('groups') }}
            </v-stepper-step>
            <v-divider></v-divider>
            <v-stepper-step
              :complete="stepCompleted >= 4"
              step="4"
              :editable="stepCompleted >= 3"
              edit-icon="check"
            >
              {{ $t('blacklist') }}
            </v-stepper-step>
            <v-divider></v-divider>
            <v-stepper-step
              :complete="stepCompleted >= 5"
              step="5"
              :editable="stepCompleted >= 4"
              edit-icon="check"
            >
              {{ $t('summary') }}
            </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">
                <v-text-field
                  v-model="roleName"
                  :label="$t('roleName')"
                  prepend-icon="label"
                  class="info-input"
                  color="primary"
                  :rules="[() => !!roleName || $t('roleNameEmptyError')]"
                  ref="roleName"
                ></v-text-field>

                <v-textarea
                  v-model="roleDescr"
                  :label="$t('description')"
                  prepend-icon="description"
                  class="info-input"
                  color="primary"
                  rows="1"
                  auto-grow
               ></v-textarea>
              </v-stepper-content>

              <v-stepper-content step="2" class="stepper-padding-0">
                <data-table v-model="permissionsSelected" :headers="permissionHeaders" :items="permissions"/>
              </v-stepper-content>

              <v-stepper-content step="3" class="stepper-padding-0">
                <data-table v-model="whitelist" :headers="groupHeaders" :items="groups" logging/>
              </v-stepper-content>

              <v-stepper-content step="4" class="stepper-padding-0">
                <data-table v-model="blacklist" :headers="groupHeaders" :items="blacklistGroups"/>
              </v-stepper-content>

              <v-stepper-content step="5">
                <v-text-field
                  v-model="roleName"
                  :label="$t('roleName')"
                  prepend-icon="label"
                  class="info-input"
                  color="primary"
                  :rules="[() => !!roleName || $t('roleNameEmptyError')]"
                  ref="roleName"
                  disabled
                ></v-text-field>

                <v-textarea
                  v-model="roleDescr"
                  :label="$t('description')"
                  prepend-icon="description"
                  class="info-input"
                  color="primary"
                  rows="1"
                  auto-grow
                  disabled
               ></v-textarea>
                <v-layout row wrap>
                  <v-flex xs12 sm6>
                    <div>
                      <v-subheader inset>{{ $t('permissions') }}</v-subheader>
                      <v-divider class="list-header-margin"></v-divider>
                      <RecycleScroller
                        :items="permissionsSelected"
                        :item-size="48"
                        page-mode
                      >
                        <div slot-scope="{ item }" class="list-item">
                          <div class="list-item-header">{{ item.name }}</div>
                          <div class="list-item-subheader">{{ item.descr }}</div>
                        </div>
                      </RecycleScroller>
                    </div>
                  </v-flex>
                  <v-flex xs12 sm6>
                    <div>
                      <v-subheader inset>{{ $t('groups') }}</v-subheader>
                      <v-divider class="list-header-margin"></v-divider>
                      <RecycleScroller
                        :items="whitelist"
                        :item-size="48"
                        page-mode
                      >
                        <div slot-scope="{ item }" class="list-item">
                          <div class="list-item-header">{{ item.id }} {{ item.name }}</div>
                          <div class="list-item-subheader">{{ item.description }}</div>
                        </div>
                      </RecycleScroller>
                    </div>
                  </v-flex>
                  <v-flex xs12 sm6>
                    <div>
                      <v-subheader inset>{{ $t('blacklist') }}</v-subheader>
                      <v-divider class="list-header-margin"></v-divider>
                      <RecycleScroller
                        :items="blacklist"
                        :item-size="48"
                        page-mode
                      >
                        <div slot-scope="{ item }" class="list-item">
                          <div class="list-item-header">{{ item.id }} {{ item.name }}</div>
                          <div class="list-item-subheader">{{ item.description }}</div>
                        </div>
                      </RecycleScroller>
                    </div>
                  </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/setEdit', false )">{{ $t('cancel') }}</v-btn>
        <v-btn color="primary" v-show="step == 1" @click.native="completeStepOne()">{{ $t('continue') }}</v-btn>
        <v-btn color="primary" v-show="step == 2" @click.native="completeStepTwo()">{{ $t('continue') }}</v-btn>
        <v-btn color="primary" v-show="step == 3" @click.native="completeStepThree()">{{ $t('continue') }}</v-btn>
        <v-btn color="primary" v-show="step == 4" @click.native="completeStepFour()">{{ $t('continue') }}</v-btn>
        <v-btn class="success" v-show="step == 5" @click="submit" type="submit">{{ $t('submit') }}</v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>

<script>
import DataTable from '@/components/DataTable'
import { mapState } from 'vuex'

export default {
  name: 'PermissionModuleEdit',
  props: ['roleId'],
  components: {
    DataTable
  },
  data () {
    return {
      valid: true,
      step: 1,
      stepCompleted: 0,
      blacklistGroups: [],
      permissionsSelected: [],
      whitelist: [],
      blacklist: [],
      permissionHeaders: [
        { text: this.$t('name'), key: 'name' },
        { text: this.$t('description'), key: 'descr' },
        { text: this.$t('groupdependent'), key: 'groupdependent' }
      ],
      groupHeaders: [
        { text: this.$t('id'), key: 'id' },
        { text: this.$t('name'), key: 'name' },
        { text: this.$t('description'), key: 'description' }
      ],
      roleName: '',
      roleDescr: ''
    }
  },
  methods: {
    submit (event) {
      if (this.$refs.form.validate()) {
        const filteredPermissions = this.permissionsSelected.map(x => x.id)
        const filteredGroups = this.whitelist.map(x => x.id)
        const filteredBlacklist = this.blacklist.map(x => x.id)
        this.$http.post('/api/roles' + (this.roleId === 0 ? '' : '/' + this.roleId), {
          id: this.roleId,
          name: this.roleName,
          descr: this.roleDescr,
          permissions: filteredPermissions,
          groups: filteredGroups,
          blacklist: filteredBlacklist
        }).then(response => {
          this.$snackbar({ color: 'success', text: this.$t('roleSavedSuccess') })
          this.$store.dispatch('permissions/loadRoleData')
          this.$store.dispatch('permissions/loadUserData')
          this.$store.commit('permissions/setEdit', false)
        }).catch(error => {
          console.log(error)
        })
      }
    },
    async loadRole (roleId) {
      const response = await this.$http('/api/roles/' + this.roleId)
      this.roleName = response.data.name
      this.roleDescr = response.data.descr
      this.permissionsSelected = response.data.permissions

      var blacklistPush = []
      for (let i = 0; i < response.data.groups.length; i++) {
        if (response.data.groups[i].role_x_group.blacklist) {
          blacklistPush.push(response.data.groups[i])
        } else {
          this.whitelist.push(response.data.groups[i])
        }
      }

      this.loadChilds().then(() => {
        this.blacklist = this.blacklist.concat(blacklistPush)
      })
    },
    completeStepOne () {
      if (this.roleName !== '') {
        this.step = 2
        this.stepCompleted = Math.max(1, this.stepCompleted)
      } else {
        this.$refs.form.validate()
      }
    },
    completeStepTwo () {
      this.step = 3
      this.stepCompleted = Math.max(2, this.stepCompleted)
    },
    completeStepThree () {
      this.step = 4
      this.stepCompleted = Math.max(3, this.stepCompleted)
      this.loadChilds()
    },
    completeStepFour () {
      this.step = 5
      this.stepCompleted = Math.max(4, this.stepCompleted)
    },
    async loadChilds () {
      this.blacklistGroups = []
      var promises = []
      this.whitelist.forEach(group => {
        promises.push(
          this.$http('/api/groups/' + group.id + '?all').then(response => {
            this.blacklistGroups = this.blacklistGroups.concat(response.data.subgroups)
          }))
      })
      await Promise.all(promises)
    }
  },
  computed: {
    ...mapState('permissions', ['permissions', 'groups']),
    edit: function () {
      return this.$store.state.permissions.edit
    }
  },
  watch: {
    edit: function (value) {
      if (value) {
        this.$refs.form.resetValidation()
        this.permissionsSelected = []
        this.whitelist = []
        this.blacklist = []
        this.step = 1
        if (this.roleId !== 0) {
          this.loadRole(this.roleId)
          this.stepCompleted = 5
        } else {
          this.roleName = ''
          this.roleDescr = ''
          this.stepCompleted = 0
        }
      }
    }
  },
  created () {
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.table-container {
  padding: 0;
  max-height: 700px;
}
.stepper-padding-0 {
  padding: 0;
}
.info-input {
  margin: 20px;
}
.list-header-margin {
  margin-bottom: 10px;
}
.dialog-title {
  padding: 0px;
  z-index: 1;
}
.list-item {
  height: 48px;
  max-width: 500px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.list-item-header {
  font-size: 16px;
}
.theme--light .list-item > .list-item-subheader {
    color: rgba(0,0,0,.54);
}
.theme--dark .list-item > .list-item-subheader {
    color: hsla(0,0%,100%,.7);
}
</style>