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


         
                                             

                                                          

                                                               




                                   

         
                                        

                                                               

                                                                    




                                   


       
          





                                                                                                        
                                                     
                               
                                                  




                                        





                                                       












                                                                           
                                    







                                                                       
                                         
                          
                                                                    

                                                            















                                                                                                                    



                            
              
                                                 
                                                                                                                   


                                                                                                                

               

                
           




































































                                                                                                                    
 














                                                                                                                     
        
                                                                                        

                
                            
                       


                                  




                       
                         
                      
                      




                                     




                                       
                                               


                                        
                                              


                                                                                           

                                                                   








                                                     
                                                             










                                                                                                    
                                                                                     


                                                    




                                                                                               

                                                                                                                      

                                           



                        
                                    




                                                            








                                                            








                                                                


                                                      














                                                                 


             


                                      




                                      

                            
     

          

   


































                                                                               



                                                                   
                  

                     

        
<i18n>
{
  "en": {
    "input_credentials": "Login credentials",
    "backend_name": "Backend name",
    "backend_empty_error": "This field can not be empty.",
    "backend_type": "Backend type",
    "backendtype_empty_error": "Please choose a backend type.",
    "stepper_optional": "optional",
    "pending": "pending",
    "progress": "in progress ...",
    "success": "success",
    "error": "error"
  },
  "de": {
    "input_credentials": "Anmeldedaten",
    "backend_name": "Backend Name",
    "backend_empty_error": "Dieses Feld darf nicht leer sein.",
    "backend_type": "Backend Typ",
    "backendtype_empty_error": "Bitte wähle einen Backendtyp aus.",
    "stepper_optional": "Optional",
    "pending": "Nicht getestet",
    "progress": "Test läuft ...",
    "success": "Erfolgreich",
    "error": "Fehler"
  }
}
</i18n>
<template>
  <v-form class="edit-backend-form" ref="form" v-model="valid" @submit.prevent="submit" lazy-validation>
    <v-stepper v-model="step" horizontal>
      <v-stepper-header>
        <v-stepper-step
          :complete="stepCompleted >= 1"
          step="1"
          :editable="stepCompleted >= 1 && !loadData"
          :rules="[() => true]"
        >{{ $t('backend_type') }}</v-stepper-step>
        <v-divider></v-divider>
        <v-stepper-step
          :complete="stepCompleted >= 2"
          step="2"
          :editable="stepCompleted >= 2"
        >{{ $t('input_credentials') }}</v-stepper-step>
        <v-divider></v-divider>
        <v-stepper-step
          :complete="stepCompleted >= 3"
          step="3"
          :editable="stepCompleted >= 3"
        >{{ $t('test_connection') }}
        <small>{{ $t('stepper_optional') }}</small>
        </v-stepper-step>
      </v-stepper-header>
      <v-stepper-items>
        <v-stepper-content step="1" class="stepper-content">
          <v-select
            offset-y
            v-model="backendType"
            :items="backendChoices"
            :label="$t('backend_type')"
            :rules="[() => !!backendType || $t('backendtype_empty_error')]"
            @change="loadInputFields"
            prepend-icon="view_list"
          ></v-select>
        </v-stepper-content>
        <v-stepper-content step="2" class="stepper-content">
          <v-text-field
            v-model="backendName"
            :label="$t('backend_name')"
            :rules="[() => !!backendName || $t('backend_empty_error')]"
            ref="backendName"
            prepend-icon="assignment_ind"
          ></v-text-field>
          <backend-module-edit-dynamic-fields :elements="elements"/>
        </v-stepper-content>
        <v-stepper-content step="3" class="stepper-content">
          <v-container>
          <v-layout align-center justify-center column>
          <v-btn
            fab
            dark
            icon
            :loading="loading"
            :disabled="loading"
            @click.stop="checkConnection"
            large
          >
            <v-icon x-large color="primary">cached</v-icon>
          </v-btn>
            <div class="display-1">{{ $t('status') }}: <strong :class="statusColor">{{ statusLabel }}</strong></div>
          </v-layout>
          </v-container>
        </v-stepper-content>
      </v-stepper-items>

<v-divider></v-divider>
    <v-layout>
      <v-flex xl10 offset-xl1 lg12 text-xs-right>
        <v-btn flat @click.native="$store.commit('backends/setDialog', { show: 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 type="submit" v-show="step == 3" class="primary" raised>{{ $t('submit') }}</v-btn>
      </v-flex>
    </v-layout>
    </v-stepper>
  </v-form>
</template>
<!--
<template>
<v-form class="edit-backend-form" ref="form" v-model="valid" @submit.prevent="submit" lazy-validation>
  <v-card>
    <v-stepper v-model="step" horizontal>
        <v-stepper-header>
          <v-stepper-step
            :complete="stepCompleted >= 1"
            step="1"
            :editable="stepCompleted >= 1 && !loadData"
            :rules="[() => true]"
          >{{ $t('backend_type') }}</v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step
            :complete="stepCompleted >= 2"
            step="2"
            :editable="stepCompleted >= 2"
          >{{ $t('input_credentials') }}</v-stepper-step>
          <v-divider></v-divider>
          <v-stepper-step
            :complete="stepCompleted >= 3"
            step="3"
            :editable="stepCompleted >= 3"
          >{{ $t('test_connection') }}
          <small>{{ $t('stepper_optional') }}</small>
          </v-stepper-step>
        </v-stepper-header>
        <v-card-text style="height: 500px;">
<v-stepper-items>
        <v-stepper-content step="1" class="stepper-content">
          <v-select
            offset-y
            v-model="backendType"
            :items="backendChoices"
            :label="$t('backend_type')"
            :rules="[() => !!backendType || $t('backendtype_empty_error')]"
            @change="loadInputFields"
            prepend-icon="view_list"
          ></v-select>
        </v-stepper-content>
        <v-stepper-content step="2" class="stepper-content">
          <v-text-field
            v-model="backendName"
            :label="$t('backend_name')"
            :rules="[() => !!backendName || $t('backend_empty_error')]"
            ref="backendName"
            prepend-icon="assignment_ind"
          ></v-text-field>
          <backend-module-edit-dynamic-fields :elements="elements"/>
        </v-stepper-content>
        <v-stepper-content step="3" class="stepper-content">
          <v-container>
          <v-layout align-center justify-center column>
          <v-btn
            fab
            dark
            icon
            :loading="loading"
            :disabled="loading"
            @click.stop="checkConnection"
            large
          >
            <v-icon x-large color="primary">cached</v-icon>
          </v-btn>
            <div class="display-1">{{ $t('status') }}: <strong :class="statusColor">{{ statusLabel }}</strong></div>
          </v-layout>
          </v-container>
        </v-stepper-content>
      </v-stepper-items>

        </v-card-text>
      <v-divider></v-divider>
      <v-card-actions>
        <v-flex xl10 offset-xl1 lg12 text-xs-right>
          <v-btn flat @click.native="$store.commit('backends/setDialog', { show: 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 type="submit" v-show="step == 3" class="primary" raised>{{ $t('submit') }}</v-btn>
        </v-flex>
      </v-card-actions>
    </v-stepper>
  </v-card>
</v-form>
</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,
      loading: false,
      statusColor: 'primary--text',
      statusLabel: this.$t('pending')
    }
  },
  methods: {
    submit (event) {
      if (this.$refs.form.validate()) {
        this.$http.post('/api/backends/save', {
          backendId: this.backendId,
          backendName: this.backendName,
          backendType: this.backendType,
          backendCredentials: this.credentials
        }).then(response => {
          // TODO: Add backend saved successfull msg.
          console.log('TODO: Implement snackbar and print backend added successfully msg.')
          this.$store.dispatch('backends/loadData')
          this.$store.commit('backends/setDialog', { show: false })
        }).catch(error => {
          console.log(error)
          // if (error.response.data.status === '') {
          // }
          // this.$refs.form.validate()
        })
      }
    },
    loadBackendTypes () {
      this.$http('/api/backends/getTypes').then(response => {
        this.backendChoices = response.data
      })
    },
    loadInputFields () {
      if (!this.loadData) {
        this.$http('/api/backends/getCredentialsByType?type=' + this.backendType).then(response => {
          this.elements = response.data
        })
      }
    },
    loadBackend (backendId) {
      this.$http('/api/backends/getInfoById?id=' + this.backendId).then(response => {
        this.backendName = response.data.backendName
        this.loadData = true
        this.backendType = response.data.backendType
        const credentialValues = JSON.parse(response.data.backendCredentials)
        this.$http('/api/backends/getCredentialsByType?type=' + this.backendType).then(res => {
          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.step = 2
        this.stepCompleted = Math.max(1, this.stepCompleted)
      } else {
        this.$refs.form.validate()
      }
    },
    completeStepTwo () {
      // Error handling
      if (this.backendName !== '') {
        this.step = 3
        this.stepCompleted = Math.max(2, this.stepCompleted)
      } else {
        this.$refs.form.validate()
      }
    },
    checkConnection () {
      // Start the loading animation and reset the label colors.
      this.loading = true
      this.statusColor = 'primary--text'
      this.statusLabel = this.$t('progress')

      // Test the credential connection.
      this.$http.post('/api/backends/checkConnection', {
        name: this.backendName,
        type: this.backendType,
        credentials: JSON.stringify(this.credentials),
        headers: {
          'Cache-Control': 'no-cache'
        }
      }).then(response => {
        if (response.data.success) {
          this.statusColor = 'success--text'
          this.statusLabel = this.$t('success')
        } else {
          this.statusColor = 'error--text'
          this.statusLabel = this.$t('error')
          this.$store.commit('newSnackbar', response.data.msg)
        }
        // Set item.loading = false to end the loading animation.
        this.loading = false
      })
    }
  },
  computed: {
    credentials: function () {
      return filterData(this.elements)
    }
  },
  beforeMount () {
    this.loadBackendTypes()
    if (this.backendId !== 0) {
      this.loadBackend(this.backendId)
      this.step = 2
      this.stepCompleted = 3
    }
  },
  watch: {
  }
}

function filterData (obj) {
  var result = []
  obj.forEach(function (element) {
    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>
.stepper-content {
  /*height: 600px;*/
  /*overflow: auto;*/
}
</style>