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


         
                                            
                                                          
                                  


                                                             
                                                     

         
                                       
                                                            



                                                                  
                                                            


       
          
           
                                       
                                                      
                     

              

                                             
                                                        






                                                                                                               
                                                                    





                                            
                                                          
                             
                    




                                                                                                                
                                          
                         
                                      

                                         

                                                                               


                                          
                                          

                                       

                                                                           




                                                                          





                              

                                                                                                         
                                                                                                                  
                                                                                                                                                                              


                       
             
           
 
        
                                                                                        

                
                            
                       


                                  




                       
                         
                      
                      
                   
                     




                                       
                                                           


                                       
                             
                                                                                                                          
                                                   
                                                       
                           
                                                                                                     



                         
                                                        




                                           
                                                                              



                                       







                                                                           
 



                                                                                                                  


                        
                                    
                              




                                                            



                                    



                                                            


             

                                      


                                            
     

          


                               
                                                    
                          


                                          
                                









                                

   


                           

                                






























                                                                               



                                                                   
        
<i18n>
{
  "en": {
    "inputCredentials": "Login credentials",
    "backendCreated": "Backend was successfully created.",
    "backendName": "Backend Name",
    "backendEmptyError": "This field can not be empty.",
    "backendType": "Backend type",
    "backendtypeEmptyError": "Please choose a backend type.",
    "backendSaved": "Backend was successfully saved."
  },
  "de": {
    "inputCredentials": "Anmeldedaten",
    "backendCreated": "Backend wurde erfolgreich erstellt.",
    "backendName": "Backend Name",
    "backendEmptyError": "Dieses Feld darf nicht leer sein.",
    "backendType": "Backend Typ",
    "backendtypeEmptyError": "Bitte wähle einen Backendtyp aus.",
    "backendSaved": "Backend wurde erfolgreich gespeichert."
  }
}
</i18n>
<template>
  <v-dialog
    :value="$store.state.backends.edit"
    @input="$store.commit('backends/setEdit', $event)"
    max-width="500px"
    scrollable
  >
    <!-- dialog needs scrollable attribute-->
    <v-card>
      <v-card-title style="padding: 0px" class="body-2">
        <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 >= 1 && !loadData"
              :rules="[() => true]"
            >{{ $t('backendType') }}<small>{{ backendType }}</small>
            </v-stepper-step>
            <v-divider></v-divider>
            <v-stepper-step
              :complete="stepCompleted >= 2"
              step="2"
              :editable="stepCompleted >= 2"
            >{{ $t('inputCredentials') }}</v-stepper-step>
          </v-stepper-header>
        </v-stepper>
      </v-card-title>
      <v-card-text style="height: 500px;">
        <v-form class="edit-backend-form" ref="form" v-model="valid" @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-select
                  menu-props="offsetY"
                  v-model="backendType"
                  :items="backendChoices"
                  :label="$t('backendType')"
                  :rules="[() => !!backendType || $t('backendtypeEmptyError')]"
                  prepend-icon="view_list"
                ></v-select>
              </v-stepper-content>
              <v-stepper-content step="2">
                <v-text-field
                  v-model="backendName"
                  :label="$t('backendName')"
                  :rules="[() => !!backendName || $t('backendEmptyError')]"
                  ref="backendName"
                  prepend-icon="assignment_ind"
                ></v-text-field>
                <backend-module-edit-dynamic-fields :elements="elements"/>
              </v-stepper-content>
            </v-stepper-items>
          </v-stepper>
        </v-form>
      </v-card-text>
      <v-divider></v-divider>
      <v-card-actions>
        <v-flex xl10 offset-xl2 lg12 text-right>
          <v-btn text @click.native="$store.commit('backends/setEdit', 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.native="completeStepTwo()" @click="submit" v-show="step == 2" class="primary" raised>{{ backendId ? $t('save') : $t('create') }}</v-btn>
        </v-flex>
      </v-card-actions>
    </v-card>
  </v-dialog>
</template>

<script>
import BackendModuleEditDynamicFields from '@/components/BackendModuleEditDynamicFields'

export default {
  name: 'BackendModuleEdit',
  props: ['backendId'],
  components: {
    BackendModuleEditDynamicFields
  },
  data () {
    return {
      valid: true,
      step: 1,
      stepCompleted: 0,
      backendChoices: [],
      backendType: '',
      backendName: '',
      elements: [],
      loadData: false
    }
  },
  methods: {
    submit (event) {
      if (this.$refs.form.validate()) {
        this.$http.put('/api/backends/' + this.backendId, {
          name: this.backendName,
          type: this.backendType,
          credentials: this.credentials
        }).then(response => {
          this.$snackbar({ color: 'success', text: this.backendId ? this.$t('backendSaved') : this.$t('backendUpdated') })
          this.$store.dispatch('backends/loadData')
          this.$store.commit('backends/setEdit', false)
        }).catch(error => {
          if (error.response.status !== 403) this.$snackbar({ color: 'error', text: error.response })
        })
      }
    },
    loadBackendTypes () {
      this.$http('/api/backendtypes').then(response => {
        this.backendChoices = response.data
      })
    },
    loadInputFields () {
      if (!this.loadData) {
        this.$http('/api/backendtypes/' + this.backendType).then(response => {
          this.elements = response.data
        })
      }
    },
    async loadBackend (backendId) {
      const response = await this.$http('/api/backends/' + this.backendId)
      this.backendName = response.data.name
      this.loadData = true
      this.backendType = response.data.type
      const credentialValues = response.data.credentials
      const res = await this.$http('/api/backendtypes/' + this.backendType)
      var credentials = res.data

      // Make an array merge to combine the credentials with the values.
      // var mergedCredentials = credentials.map(x => Object.assign(x, credentialValues.find(y => y.id === x.id)))
      var mergedCredentials = mergeObjects(credentials, credentialValues)
      this.elements = mergedCredentials
    },
    completeStepOne () {
      // Error handling
      if (this.backendType !== '') {
        this.loadInputFields()
        this.step = 2
        this.stepCompleted = Math.max(1, this.stepCompleted)
      } else {
        this.$refs.form.validate()
      }
    },
    completeStepTwo () {
      // Error handling
      if (this.backendName !== '') {
        this.stepCompleted = Math.max(2, this.stepCompleted)
      } else {
        this.$refs.form.validate()
      }
    }
  },
  computed: {
    credentials: function () {
      return filterData(this.elements)
    },
    edit: function () {
      return this.$store.state.backends.edit
    }
  },
  watch: {
    edit: function (value) {
      if (value) {
        this.loadBackendTypes()
        if (this.$refs.form) this.$refs.form.reset()
        this.elements = []
        if (this.backendId !== 0) {
          this.loadBackend(this.backendId)
          this.step = 2
          this.stepCompleted = 2
        } else {
          this.backendName = ''
          this.backendType = ''
          this.step = 1
          this.stepCompleted = 0
          this.elements = []
          this.loadData = false
        }
      }
    }
  }
}

function filterData (obj) {
  var result = []
  obj.forEach(element => {
    if (element.disabled) return
    const e = { id: element.id, value: element.value }
    if (element.elements) {
      e.elements = filterData(element.elements)
    }
    result.push(e)
  })
  return result
}

function mergeObjects (obj1, obj2) {
  var tmp = []
  var merged = obj1.map(x => Object.assign(x, obj2.find(y => {
    if (y.id === x.id) {
      if (x.elements && y.elements) {
        var tmp2 = { id: x.id, elements: mergeObjects(x.elements, y.elements) }
        tmp.push(tmp2)
      }
    }
    return y.id === x.id
  })))

  // Is there a cleaner way?
  tmp.forEach(function (e) {
    merged.forEach(function (r) {
      if (e.id === r.id) {
        r.elements = e.elements
      }
    })
  })
  return merged
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>