summaryrefslogblamecommitdiffstats
path: root/webapp/src/components/GroupModuleDialog.vue
blob: 7776aa017d8f3e95884bdf95e79d95cbfb676661 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15


         











                                                                           



                                  


                                                                     

       













                                                                                   



                                                                        

                 

                                 
                       

                                                                                  

         


                                                                        
                                                                         


                                                                                    
                                                                           


                                                                                                    
                                                                                                     


                                      
                                      


                                                                           

       

                 
                                                                                     


                                                                                   
                                                                                   


                                                                                 
                                                                                           


                                                                                         

                                                                        
                                                                        
      

                 

                                  
                       

                                                                                      





           

                                        
                                       
              

                                                         

            
                                                     
                                               
                             
                                                                                                

                                                     
                     






                                                                                  
                                                                                                               












                                                                                
                                                                            
                            












                                                                           
              
                    
 
                             
 

                             
                                                                                         
                                                                                             





                       
                                              



                                             
               
             
    

            
                   




                                   

                            




                          

                           
       


             
                                                  
                                          
                
                                                                                  
              


                                                           

       


                                                                                                                    


                                                                                                                              
              
                                                                                                                     



                                                                                        
               


                                                                   


                                                                 
     
    


                                                                
      


                                                                  






                                                                                             
                                                                                                               
                                                                                           





                                                                       
                     





                                                







                                                           



                                                                           
       
                                                                                                 




                                                                                                






                                       
       
                                                              
                                                                 
                                                                                           


                                     
                                     
                                                                 

                                                                                                           
                                                                 
                                                      






                                                                   
                  
               
                        
 


               



                   


                      
 


                


                   
        
<i18n>
{
  "en": {
    "title": {
      "delete": {
        "group": "Delete this group? | Delete these {0} groups?",
        "client": "Delete this client? | Delete these {0} clients?"
      },
      "remove": {
        "group": "Remove this subgroup? | Remove these {0} subgroups?",
        "client": "Remove this client? | Remove these {0} clients?"
      },
      "add": {
        "group": "Add groups | Add this group? | Add these {0} groups?",
        "client": "Add clients | Add this client? | Add these {0} clients?"
      },
      "select": {
        "group": "Select groups",
        "client": "Select clients"
      },
      "wake": {
        "client": "Wake this client up? | Wake these {0} clients up?"
      }
    },
    "success": {
      "delete": {
        "client": "Successfully deleted client | Successfully deleted {0} clients",
        "group": "Successfully deleted group | Successfully deleted {0} groups"
      },
      "remove": {
        "client": "Successfully removed client | Successfully removed {0} clients",
        "group": "Successfully removed group | Successfully removed {0} groups"
      },
      "add": {
        "client": "Successfully added client | Successfully added {0} clients",
        "group": "Successfully added group | Successfully added {0} groups"
      }
    },
    "deletePermanently": {
      "group": "Permanently delete group | Permanently delete groups",
      "client": "Permanently delete client | Permanently delete clients"
    },
    "new": "New",
    "id": "ID",
    "name": "Name",
    "description": "Description",
    "ip": "IP Address",
    "wake": "Wake up",
    "deleteInBackends": "Select the backends, where the clients will get deleted:"
  },
  "de": {
    "title": {
      "delete": {
        "group": "Diese Gruppe löschen? | Diese {0} Gruppen löschen?",
        "client": "Diesen Client löschen? | Diese {0} Clients löschen?"
      },
      "remove": {
        "group": "Diese Untergruppe entfernen? | Diese {0} Untergruppen entfernen?",
        "client": "Diesen Client entfernen? | Diese {0} Clients entfernen?"
      },
      "add": {
        "group": "Gruppen hinzufügen | Diese Gruppe hinzufügen? | Diese {0} Gruppen hinzufügen?",
        "client": "Clients hinzufügen | Diesen Client hinzufügen? | Diese {0} Clients hinzufügen?"
      },
      "select": {
        "group": "Gruppen auswählen",
        "client": "Clients auswählen"
      },
      "wake": {
        "client": "Diesen Client aufwecken? | Diese {0} Clients aufwecken?"
      }
    },
    "success": {
      "delete": {
        "client": "Client erfolgreich gelöscht | {0} Clients erfolgreich gelöscht",
        "group": "Gruppe erfolgreich gelöscht | {0} Gruppen erfolgreich gelöscht"
      },
      "remove": {
        "client": "Client erfolgreich entfernt | {0} Clients erfolgreich entfernt",
        "group": "Gruppe erfolgreich entfernt | {0} Gruppen erfolgreich entfernt"
      },
      "add": {
        "client": "Client erfolgreich hinzugefügt | {0} Clients erfolgreich hinzugefügt",
        "group": "Gruppe erfolgreich hinzugefügt | {0} Gruppen erfolgreich hinzugefügt"
      }
    },
    "deletePermanently": {
      "group": "Gruppe dauerhaft löschen | Gruppen dauerhaft löschen",
      "client": "Client dauerhaft löschen | Clients dauerhaft löschen"
    },
    "new": "Neu",
    "id": "ID",
    "name": "Name",
    "description": "Beschreibung",
    "ip": "IP Adresse",
    "wake": "Aufwecken",
    "deleteInBackends": "Wähle die Backends, aus denen die Clients gelöscht werden:"
  }
}
</i18n>

<template>
  <v-dialog
    :value="dialog.show"
    @input="setDialog({ show: $event })"
    :max-width="actionWidthMap[action]"
    scrollable
    :persistent="action === 'add' || action === 'select'"
    :fullscreen="$vuetify.breakpoint.smAndDown"
  >
    <v-card>
      <v-card-title class="dialog-title elevation-3">
        <div class="headline">{{ title }}</div>
        <v-spacer></v-spacer>
        <v-btn v-if="action === 'add'" class="new-button" text color="success" @click="newItem">
          <v-icon left>create</v-icon>{{ $t('new') }}
        </v-btn>
      </v-card-title>
      <v-card-text ref="cardtext" class="table-container">
        <data-table v-if="action === 'add' || action === 'select'" ref="datatable"
          v-model="selected"
          :headers="headers"
          :items="items"
          :row-count="$vuetify.breakpoint.smAndDown ? -1 : undefined"
        ></data-table>
        <div v-else-if="action === 'remove' || action === 'delete' || action === 'wake'" class="selected-list">
          <v-checkbox
            class="delete-checkbox"
            v-if="dialog.info.action === 'remove'"
            :label="$tc('deletePermanently.' + dialog.info.type, selectedCount)"
            color="error"
            v-model="deleteInsteadOfRemove"
            hide-details
          ></v-checkbox>
          <RecycleScroller
            :items="dialog.info.selected"
            :item-size="24"
            page-mode
          >
            <div slot-scope="{ item }">[{{ item.id }}] {{ item.name }}</div>
          </RecycleScroller>
          <div v-if="action === 'delete' && dialog.info.type === 'client'">
            <div class="select-backends">{{ $t('deleteInBackends') }}</div>
            <template v-for="backend in backends">
              <v-checkbox
                :label="backend.name"
                v-model="backend.selected"
                :key="backend.id"
                :value="backend.selected"
                color="primary"
                hide-details
              ></v-checkbox>
            </template>
          </div>
        </div>
      </v-card-text>

      <v-divider></v-divider>

      <v-card-actions>
        <v-spacer></v-spacer>
        <v-btn text="flat" @click="setDialog({ show: false })">{{ $t('cancel') }}</v-btn>
        <v-btn :color="actionColorMap[action]" @click="submitAction">{{ $t(action) }}</v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>

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

export default {
  name: 'GroupModuleDialog',
  components: {
    DataTable
  },
  data () {
    return {
      selected: [],
      deleteInsteadOfRemove: false,
      actionColorMap: {
        'add': 'success',
        'remove': 'error',
        'delete': 'error',
        'select': 'primary',
        'wake': 'primary'
      },
      actionWidthMap: {
        'add': '1000px',
        'remove': '500px',
        'delete': '500px',
        'select': '1000px',
        'wake': '500px'
      }
    }
  },
  computed: {
    ...mapState('groups', ['dialog', 'tabChain']),
    ...mapState('backends', ['backends']),
    headers () {
      const lastColumn = this.dialog.info.type === 'client' ? 'ip' : 'description'
      return [
        { key: 'id', text: this.$t('id'), width: '100px' },
        { key: 'name', text: this.$t('name') },
        { key: lastColumn, text: this.$t(lastColumn) }
      ]
    },
    action () {
      return this.dialog.info.action === 'remove' && this.deleteInsteadOfRemove ? 'delete' : this.dialog.info.action
    },
    selectedCount () {
      return this.action === 'add' ? this.selected.length : (this.dialog.info.selected ? this.dialog.info.selected.length : 0)
    },
    title () {
      return this.$tc('title.' + this.action + '.' + this.dialog.info.type, this.selectedCount, [this.selectedCount])
    },
    items () {
      if (this.dialog.info.type === 'group') return this.$store.state.groups.groupList
      if (this.dialog.info.type === 'client') return this.$store.state.groups.clientList
      return []
    },
    dialogAction () {
      return this.dialog.info ? this.dialog.info.action : undefined
    },
    dialogType () {
      return this.dialog.info ? this.dialog.info.type : undefined
    }
  },
  watch: {
    dialogAction () {
      if (this.$refs.datatable) this.$refs.datatable.resetData()
    },
    dialogType () {
      if (this.$refs.datatable) this.$refs.datatable.resetSearch()
    },
    dialog: {
      deep: true,
      handler () {
        if (this.dialog.show) {
          this.deleteInsteadOfRemove = false
          if (this.dialog.info.action === 'select') this.selected = this.dialog.info.selected
          else this.selected = []
          if (this.$refs.cardtext) this.$nextTick(() => this.$refs.cardtext.dispatchEvent(new Event('scroll')))
          if (this.dialog.info.type === 'client') this.$store.dispatch('backends/loadData')
        }
      }
    }
  },
  methods: {
    ...mapMutations('groups', ['setActiveTab', 'setTab', 'setDialog']),
    submitAction () {
      if (this.action === 'select') {
        this.dialog.info.callback(this.selected)
        this.setDialog({ show: false })
        return
      }

      if (this.action === 'wake') {
        this.$http.post('/api/wakerequests', {
          clients: this.dialog.info.selected.map(x => x.id)
        })
        this.setDialog({ show: false })
        return
      }

      const actionMap = {
        'delete': { 'group': 'deleteGroups', 'client': 'deleteClients' },
        'remove': { 'group': 'removeSubroups', 'client': 'removeClients' },
        'add': { 'group': 'addSubgroups', 'client': 'addClients' }
      }
      var count = this.action === 'add' ? this.selected.length : this.dialog.info.selected.length
      var data = {
        ...this.dialog.info,
        callback: () => this.$snackbar({
          color: 'success',
          text: this.$tc('success.' + this.action + '.' + this.dialog.info.type, count, [count])
        }),
        snackbar: (color, message) => {
          this.$snackbar({
            color: color,
            text: message
          })
        }
      }
      if (this.action === 'add') data.selected = this.selected
      if (this.action === 'delete') data.backends = this.backends
      this.$store.dispatch('groups/' + actionMap[this.action][this.dialog.info.type], data)
      this.setDialog({ show: false })
    },
    newItem () {
      this.setDialog({ show: false })
      var item = { id: 'create', tabType: this.dialog.info.type }
      if (this.dialog.info.type === 'group') item.parents = [this.tabChain[this.dialog.info.tabIndex]]
      else if (this.dialog.info.type === 'client') item.groups = [this.tabChain[this.dialog.info.tabIndex]]
      this.setTab({ index: this.dialog.info.tabIndex + 1, item })
      this.setActiveTab(this.dialog.info.tabIndex + 1)
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
.table-container {
  height: 100%;
  padding: 0 !important;
}
.dialog-title {
  z-index: 1;
}
.new-button {
  margin-top: 0;
  margin-bottom: 0;
}
.delete-checkbox {
  margin-top: 0;
  margin-bottom: 20px;
}
.selected-list {
  padding: 30px;
}
.select-backends {
  margin-top: 20px;
}
</style>