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


         
                   

                          



                                 
                            
                            


                          

         
                   

                          



                                  
                              
                                   


                              





          

                                                         

                       
                                                   

                             
                                                                                                                                                             
                                               
                                                                                                            



                                                                      

                                        
                                                                                                                    
                                         



                                                                                     


                        
                      
                                                                                                                                                                                                                                                       




                                                                                                             

                       
                                                   
                                                                                                                                                                                            
                                           
                                                                                                                     


















                                                                                                                        
                                     






                                                                              
                                                                                 
                    

                   
                                                                     
                                    







                                                                                    
                          
                                                                                                               
                                                                              
                                                            
                        
                    


                   

                    












                                                                                    
                                                                                                          
                                                    
                                                                                                          
               





                                                                      
                                   


                               
                               





                         


                      

                        
        

                                            

     







                                                                      

                                
                                                   
                                                                 

     
            
                                             



                                                                                                            




                                                    




                                                    
                                              

                                                                                  


                           



                                                                                           
      
                 
                                                                                       

                                                
                        

                                

                                
        
                           
      


                                                                                                       
                    



                                      
     


                                                   





                                                                   


               





                      
               














                            
             
                     
 




                                                 




                      
 


                      
 
            
                   
                    
                             
 
 




                       
        
<i18n>
{
  "en": {
    "info": "Info",
    "showall": "Show All",
    "groups": "Groups",
    "subgroups": "Subgroups",
    "clients": "Clients",
    "name": "Name",
    "description": "Description",
    "ipranges": "IP Ranges",
    "config": "iPXE Config",
    "parents": "Parents",
    "startIp": "Start IP",
    "endIp": "End IP"
  },
  "de": {
    "info": "Info",
    "showall": "Show All",
    "groups": "Groups",
    "subgroups": "Untergruppen",
    "clients": "Clienten",
    "name": "Name",
    "description": "Beschreibung",
    "ipranges": "IP Bereiche",
    "config": "iPXE Konfiguration",
    "parents": "Übergruppen",
    "startIp": "Start IP",
    "endIp": "End IP"
  }
}
</i18n>

<template>
  <div>
    <v-subheader v-if="group.id !== 0">Info</v-subheader>
    <v-card v-if="group.id !== 0">
      <v-card-text>
        <v-layout wrap>
          <v-flex lg4 sm6 xs12 order-lg1 order-xs2>
            <v-layout column>
              <v-flex>
                <v-text-field prepend-icon="label" v-if="editMode" class="info-input" :label="$t('name')" color="primary" v-model="info.name"></v-text-field>
                <div v-else class="info-input">
                  <div class="body-2 info-heading"><v-icon>label</v-icon><span>{{ $t('name') }}</span></div>
                  <div class="info-text">{{ group.name || '-' }}</div>
                </div>
              </v-flex>
              <v-flex>

                <div class="info-input">
                  <div class="body-2 info-heading"><v-icon>device_hub</v-icon><span>{{ $t('parents') }}</span></div>
                  <div class="info-text">
                    <v-chip v-for="parent in group.parents" :key="parent.id" small>
                      {{ parent.name || parent.id }}
                    </v-chip>
                    <span v-if="group.parents && group.parents.length === 0">-</span>
                  </div>
                </div>
              </v-flex>
              <v-flex>
                <v-select v-if="editMode" class="info-input" prepend-icon="list" clearable item-text="name" item-value="id" :menu-props="{ offsetY: '' }" :label="$t('config')" color="primary" v-model="info.configId" :items="configList"></v-select>
                <div v-else class="info-input">
                  <div class="body-2 info-heading"><v-icon>list</v-icon><span>{{ $t('config') }}</span></div>
                  <div class="info-text">{{ configName || '-' }}</div>
                </div>
              </v-flex>
            </v-layout>
          </v-flex>
          <v-flex lg4 sm6 xs12 order-lg2 order-xs3>
            <v-textarea prepend-icon="description" v-if="editMode" rows="1" auto-grow class="info-input" :label="$t('description')" color="primary" v-model="info.description"></v-textarea>
            <div v-else class="info-input">
              <div class="body-2 info-heading"><v-icon>description</v-icon><span>{{ $t('description') }}</span></div>
              <pre class="info-text">{{ group.description || '-' }}</pre>
            </div>

            <div v-if="editMode" class="info-input">
              <div class="body-2 info-heading">
                <v-icon>settings_ethernet</v-icon><span>{{ $t('ipranges') }}</span>
                <v-btn small icon @click="addIprange"><v-icon>add</v-icon></v-btn>
              </div>
              <div>
                <div v-for="(iprange, index) in ipranges" class="iprange" :key="index">
                  <v-btn small icon class="remove-iprange" @click="removeIprange(index)"><v-icon>remove</v-icon></v-btn>
                  <v-text-field :label="$t('startIp')" color="primary" v-model="iprange.startIp"></v-text-field>
                  <span>-</span>
                  <v-text-field :label="$t('endIp')" color="primary" v-model="iprange.endIp"></v-text-field>
                </div>
              </div>
            </div>
            <div v-else class="info-input">
              <div class="body-2 info-heading"><v-icon>settings_ethernet</v-icon><span>{{ $t('ipranges') }}</span></div>
              <div class="info-text">
                <table>
                  <tr v-for="(iprange, index) in group.ipranges" :key="index">
                    <td class="text-xs-right">{{ iprange.startIp }}</td>
                    <td class="ip-seperator">-</td>
                    <td>{{ iprange.endIp }}</td>
                  </tr>
                </table>
                <div v-if="group.ipranges && group.ipranges.length === 0">-</div>
              </div>
            </div>
          </v-flex>
          <v-flex lg4 xs12 order-lg3 order-xs1 class="text-xs-right">
            <div class="info-input">
              <div v-if="!editMode">
                <v-btn color="error" flat @click="deleteGroup" class="info-buttons">
                  <v-icon left>delete</v-icon>{{ $t('delete') }}
                </v-btn>
                <v-btn color="primary" flat @click="editInfo" class="info-buttons">
                  <v-icon left>create</v-icon>{{ $t('edit') }}
                </v-btn>
              </div>
              <div v-else>
                <v-btn color="primary" flat @click="cancelEdit" class="info-buttons">{{ $t('cancel') }}</v-btn>
                <v-btn color="primary" @click="saveData" class="info-buttons">
                  <v-icon left>save</v-icon>{{ $t('save') }}
                </v-btn>
              </div>
            </div>
          </v-flex>
        </v-layout>
      </v-card-text>
    </v-card>
    <template v-if="group.id !== 'create'">
      <v-layout>
        <v-spacer></v-spacer>
        <div><v-switch
          :input-value="group.tabShowAll"
          @change="setShowAll"
          class="show-toggle"
          :label="$t('showall')"
          hide-details
          color="primary"
        ></v-switch></div>
      </v-layout>
      <v-subheader>{{ group.id > 0 ? $t('subgroups') : $t('groups') }}</v-subheader>
      <group-module-group-list :tabIndex="tabIndex" :groupId="group.id" :groups="group.subgroups || []" />
      <v-subheader>{{ $t('clients') }}</v-subheader>
      <group-module-client-list :tabIndex="tabIndex" :groupId="group.id" :clients="group.clients || []" />
    </template>
  </div>
</template>

<script>
import GroupModuleGroupList from '@/components/GroupModuleGroupList'
import GroupModuleClientList from '@/components/GroupModuleClientList'
import { mapMutations } from 'vuex'

export default {
  name: 'GroupModuleGroupView',
  props: ['tabIndex', 'group'],
  components: {
    GroupModuleGroupList,
    GroupModuleClientList
  },
  data () {
    return {
      editMode: false,
      info: {
        name: '',
        description: '',
        configId: null
      },
      parents: [],
      ipranges: [{ startIp: '', endIp: '' }]
    }
  },
  computed: {
    configList () {
      return this.$store.state.groups.configList
    },
    configName () {
      return this.$store.state.groups.configNames[this.group.configId]
    }
  },
  watch: {
    group (newValue, oldValue) {
      if (newValue.id === 'create') this.editInfo()
      else if (newValue.id !== oldValue.id) this.editMode = false
    }
  },
  methods: {
    ...mapMutations('groups', ['setDialog']),
    setShowAll (value) {
      this.$store.commit('groups/setShowAll', { index: this.tabIndex, value })
      this.$store.dispatch('groups/loadGroup', { id: this.group.id, tabIndex: this.tabIndex, reload: true })
    },
    removeIprange (index) {
      this.ipranges.splice(index, 1)
    },
    addIprange () {
      this.ipranges.push({ startIp: '', endIp: '' })
    },
    editInfo () {
      this.editMode = true
      this.info.name = this.group.name
      this.info.description = this.group.description
      this.info.configId = this.group.configId
      this.parents = this.group.parents.slice(0) || []
      this.ipranges = this.group.ipranges.slice(0) || [{ startIp: '', endIp: '' }]
    },
    cancelEdit () {
      this.editMode = false
      if (this.group.id === 'create') {
        this.$store.commit('groups/deleteFromTabChain', { index: this.tabIndex, count: 1 })
        this.$store.commit('groups/setActiveTab', this.tabIndex - 1)
      }
    },
    saveData () {
      this.info.configId = this.info.configId === undefined ? null : this.info.configId
      this.$store.dispatch('groups/saveGroup', {
        id: this.group.id,
        data: this.info,
        parents: this.parents,
        ipranges: this.ipranges,
        tabIndex: this.tabIndex,
        callback: this.updateUrl
      })
      this.editMode = false
    },
    deleteGroup () {
      this.setDialog({ show: true, info: { action: 'delete', type: 'group', selected: [this.group] } })
    },
    updateUrl (id) {
      this.$router.replace({
        name: 'GroupModule.group',
        params: { id, noReload: true }
      })
    }
  },
  created () {
    if (this.group.id === 'create') this.editInfo()
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.info-buttons {
  margin: 0;
}

.iprange {
  display: flex;
  align-items: center;
}

.ip-seperator {
  padding: 0 10px;
}

.iprange > .remove-iprange {
  margin: 0 8px 0 -2px;
}

.iprange >>> input {
  font-size: 14px;
}

.iprange > span {
  margin: 0 10px;
}

.info-input {
  padding: 10px 20px;
}

.info-input >>> input, .info-input >>> textarea {
  font-family: 'Roboto Mono';
}

.info-heading {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
}

.info-heading > span {
  margin-left: 10px;
}

.info-text {
  overflow-x: auto;
  margin-left: 34px;
  font-family: 'Roboto Mono';
}

.show-toggle {
  margin-top: 20px;
  margin-right: 20px;
  margin-bottom: -20px;
}
</style>