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


         
                                                               
                   
                                        
                              
                                
                                                         
                                        


                                                   
                 
                           
                                                   
                   
                         








                                                                            
                              
                                 
                                                                   
                           
                                                              
                                               



                                                              
                         




                                                                        





          
                                               
 








                                                                                                                             
             
       
 
                                                                
                                                                                           
                                              
                                                                                                                                          
                 
             






                                                                                                           
                               
                                                                                                                                     
                                                                                                                                          
                                                                                                                                      
          










                                                                                                                                                                               


                                                                                       




                                                                                                                  
                 

                                                                       


                                                                                                 




                                                                                                                       
                 

                                                                       


                                                                                         




                                                                                                                   
                 

                                                                       


                                                                                         




                                                                                                                   
                 

                   







                                 
                                  









                         
              

                            




                                                               















                                                                                                           

                                                                                                                                



                                                                            

                                                                                                                                
        




                                                                                                                           

                          
                                                   
                                                                                                            


                            
















                                                                                
                                                                                



                                          
                                                                                            




                                                         









                                                                                                    


              
                          
                                                  
                                                                    
     





                                                                   













                                        






                                  
        
<i18n>
{
  "en": {
    "alreadyBuiling": "The iPXE building process not finished",
    "bios": "BIOS",
    "buildingIpxe": "Building iPXE ...",
    "buildIpxe": "Build iPXE",
    "cancelIpxe": "Cancel iPXE",
    "certificateSaved": "Certificate saved successfully",
    "cleaningIpxe": "Cleaning iPXE ...",
    "cleanIpxe": "Clean iPXE",
    "console": "console.h",
    "consoleSaved": "console.h saved successfully",
    "efi": "EFI",
    "general": "general.h",
    "generalSaved": "general.h saved successfully",
    "ipxe": "iPXE",
    "scripts": "Scripts",
    "script": "Embedded script (EMBED=)",
    "scriptSaved": "Embedded script saved successfully",
    "scrollDown": "Go to the bottom",
    "trust": "Embedded certificate (TRUST=)"
  },
  "de": {
    "alreadyBuiling": "Der iPXE build-Prozess ist noch nicht abgeschlossen",
    "bios": "BIOS",
    "buildingIpxe": "iPXE wird gebaut ...",
    "buildIpxe": "iPXE bauen",
    "cancelIpxe": "iPXE stoppen",
    "certificateSaved": "Zertifikat wurde erfolgreich gespeichert",
    "console": "console.h",
    "consoleSaved": "console.h wurde erfolgreich gespeichert",
    "cleaningIpxe": "iPXE wird aufgeräumt ..",
    "cleanIpxe": "iPXE aufräumen",
    "efi": "EFI",
    "general": "general.h",
    "generalSaved": "general.h wurde erfolgreich gespeichert",
    "scripts": "Skripte",
    "ipxe": "iPXE",
    "script": "Eingebettetes Skript (EMBED=)",
    "scriptSaved": "Eingebettetes Skript wurde erfolgreich gespeichert",
    "scrollDown": "Gehe nach unten",
    "trust": "Eingebettetes Zertifikat (TRUST=)"
  }
}
</i18n>

<template>
  <div>
    <v-subheader>{{ $t('ipxe') }}</v-subheader>

    <!--
    <v-card v-on:wheel="manualScroll">
      <div>
        <RecycleScroller :items="log" ref="log" :item-size="21" style="height: 588px;">
          <div slot-scope="{ item }" style="height: 21px;">
            <pre :class="item.status + '--text'" style="margin-bottom: 0px"><span>{{ item.date }} {{ item.msg }}</span></pre>
          </div>
        </RecycleScroller>
      </div>
    </v-card>
    -->

    <!-- Recycle Scroller or not?! One of them ^v has to go! -->
    <v-card class="terminal" ref="log" v-on:wheel="manualScroll" style="padding-left: 0px">
      <template v-for="(entry, index) in log">
        <pre :class="entry.status + '--text'" style="margin-bottom: 0px;" :key="index"><span>{{ entry.date }} {{ entry.msg }}</span></pre>
      </template>
    </v-card>

    <div class="scroll-overlay non-selectable" v-if="!autoscroll">
      <div @click="toTheBottom" style="cursor: pointer; height: 100%; display: flex; align-items: center;">
        <v-icon style="margin-right: 10px">vertical_align_bottom</v-icon><pre>{{ $t('scrollDown') }}</pre>
      </div>
    </div>

    <div class="text-xs-right">
      <v-btn flat color="error" @click="cleanIpxe" :disabled=disableButtons><v-icon left>delete</v-icon>{{ $t('cleanIpxe') }}</v-btn>
      <v-btn flat color="warning" @click="cancelIpxe" :disabled=!disableButtons><v-icon left>cancel</v-icon>{{ $t('cancelIpxe') }}</v-btn>
      <v-btn flat color="primary" @click="buildIpxe" :disabled=disableButtons><v-icon left>gavel</v-icon>{{ $t('buildIpxe') }}</v-btn>
    </div>
    <v-subheader>{{ $t('scripts') }}</v-subheader>
    <v-card class="tabbar-card subtabs" :color="tabsColor">
      <v-tabs v-model="tabs" grow :dark="tabsDark" :color="tabsColor" :slider-color="tabsSliderColor" hide-slider>
          <v-tab :class="tabs === 0 ? 'primary--text' : ''"><v-icon class="tabbar-tabicon" :color="tabs === 0 ? 'primary' : ''">description</v-icon>{{ $t('script') }}</v-tab>
          <v-tab :class="tabs === 1 ? 'primary--text' : ''"><v-icon class="tabbar-tabicon" :color="tabs === 1 ? 'primary' : ''">description</v-icon>{{ $t('trust') }}</v-tab>
          <v-tab :class="tabs === 2 ? 'primary--text' : ''"><v-icon class="tabbar-tabicon" :color="tabs === 2 ? 'primary' : ''">description</v-icon>{{ $t('general') }}</v-tab>
          <v-tab :class="tabs === 3 ? 'primary--text' : ''"><v-icon class="tabbar-tabicon" :color="tabs === 3 ? 'primary' : ''">description</v-icon>{{ $t('console') }}</v-tab>
      </v-tabs>
    </v-card>
    <v-tabs-items v-model="tabs" style="padding-bottom: 12px"> <!--20px-->
      <v-tab-item lazy :transition="false" :reverse-transition="false">
        <div slot="header">{{ $t('script') }}</div>
        <v-card>
          <codemirror class="script-editor" ref="script" v-model="script"></codemirror>
          <div class="text-xs-right">
            <v-btn flat color="error" @click="undo('script')"><v-icon left>undo</v-icon>{{ $t('undo') }}</v-btn>
            <v-btn flat color="success" @click="redo('script')"><v-icon left>redo</v-icon>{{ $t('redo') }}</v-btn>
            <v-btn color="primary" @click="save('script')"><v-icon left>save</v-icon>{{ $t('save') }}</v-btn>
          </div>
        </v-card>
      </v-tab-item>
      <v-tab-item lazy :transition="false" :reverse-transition="false">
        <div slot="header">{{ $t('trust') }}</div>
        <v-card>
          <codemirror class="script-editor" ref="certificate" v-model="certificate"></codemirror>
          <div class="text-xs-right">
            <v-btn flat color="error" @click="undo('certificate')"><v-icon left>undo</v-icon>{{ $t('undo') }}</v-btn>
            <v-btn flat color="success" @click="redo('certificate')"><v-icon left>redo</v-icon>{{ $t('redo') }}</v-btn>
            <v-btn color="primary" @click="save('certificate')"><v-icon left>save</v-icon>{{ $t('save') }}</v-btn>
          </div>
        </v-card>
      </v-tab-item>
      <v-tab-item lazy :transition="false" :reverse-transition="false">
        <div slot="header">{{ $t('general') }}</div>
        <v-card>
          <codemirror class="script-editor" ref="general" v-model="general"></codemirror>
          <div class="text-xs-right">
            <v-btn flat color="error" @click="undo('general')"><v-icon left>undo</v-icon>{{ $t('undo') }}</v-btn>
            <v-btn flat color="success" @click="redo('general')"><v-icon left>redo</v-icon>{{ $t('redo') }}</v-btn>
            <v-btn color="primary" @click="save('general')"><v-icon left>save</v-icon>{{ $t('save') }}</v-btn>
          </div>
        </v-card>
      </v-tab-item>
      <v-tab-item lazy :transition="false" :reverse-transition="false">
        <div slot="header">{{ $t('console') }}</div>
        <v-card>
          <codemirror class="script-editor" ref="console" v-model="console"></codemirror>
          <div class="text-xs-right">
            <v-btn flat color="error" @click="undo('console')"><v-icon left>undo</v-icon>{{ $t('undo') }}</v-btn>
            <v-btn flat color="success" @click="redo('console')"><v-icon left>redo</v-icon>{{ $t('redo') }}</v-btn>
            <v-btn color="primary" @click="save('console')"><v-icon left>save</v-icon>{{ $t('save') }}</v-btn>
          </div>
        </v-card>
      </v-tab-item>
    </v-tabs-items>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import axios from 'axios'

export default {
  name: 'IpxeBuilderModuleConfig',
  props: ['ipxeVersion'],
  components: {
  },
  data () {
    return {
      tabs: 0,
      script: '',
      certificate: '',
      general: '',
      console: '',
      log: [],
      disableButtons: false,
      autoscroll: true
    }
  },
  computed: {
    ...mapGetters(['tabsDark', 'tabsColor', 'tabsSliderColor'])
  },
  methods: {
    save (apiPath) {
      axios.put('/api/ipxe/' + this.ipxeVersion + '/' + apiPath, { data: this[apiPath] }).then(result => {
        const saveMsg = apiPath + 'Saved'
        if (result.data.status === 'SUCCESS') this.$snackbar({ color: 'success', text: this.$tc(saveMsg) })
        else this.$snackbar({ color: 'error', text: result.data.error })
      })
    },
    undo (element) {
      this.$refs[element].codemirror.undo()
    },
    redo (element) {
      this.$refs[element].codemirror.redo()
    },
    buildIpxe () {
      axios.get('/api/ipxe/' + this.ipxeVersion + '/build').then(result => {
        if (result.data.status === 'SUCCESS') this.$snackbar({ color: 'primary', text: this.$tc('buildingIpxe') })
        else if (result.data.status === 'ALREADY_BUILDING') this.$snackbar({ color: 'error', text: this.$tc('alreadyBuiling') })
      })
    },
    cleanIpxe () {
      axios.get('/api/ipxe/' + this.ipxeVersion + '/clean').then(result => {
        if (result.data.status === 'SUCCESS') this.$snackbar({ color: 'primary', text: this.$tc('cleaningIpxe') })
        else if (result.data.status === 'ALREADY_BUILDING') this.$snackbar({ color: 'error', text: this.$tc('alreadyBuiling') })
      })
    },
    cancelIpxe () {
      axios.get('/api/ipxe/' + this.ipxeVersion + '/cancel').then(result => {
        if (result.data.status === 'SUCCESS') this.$snackbar({ color: 'primary', text: this.$tc('cleaningIpxe') }) // TODO:
      })
    },
    manualScroll (event) {
      if (event.deltaY < 0) this.autoscroll = false
      else if (this.$refs.log.$el.scrollTop + 800 >= this.$refs.log.$el.scrollHeight) this.autoscroll = true
    },
    toTheBottom () {
      this.autoscroll = true
    }
  },
  created () {
    // Load the data.
    axios.get('/api/ipxe/' + this.ipxeVersion + '/script').then(result => {
      this.script = result.data
    })
    axios.get('/api/ipxe/' + this.ipxeVersion + '/certificate').then(result => {
      this.certificate = result.data
    })
    axios.get('/api/ipxe/' + this.ipxeVersion + '/general').then(result => {
      this.general = result.data
    })
    axios.get('/api/ipxe/' + this.ipxeVersion + '/console').then(result => {
      this.console = result.data
    })

    axios.get('/api/ipxe/' + this.ipxeVersion + '/log?max=500').then(result => {
      var lines = result.data.split('\n')
      for (var line in lines) {
        if (lines[line] === '') continue
        var attr = lines[line].split('\t')
        this.log.push({ id: this.log.length, date: attr[0], status: attr[1], msg: attr[2] })
      }
    })

    // Socket io event listeners
    this.$socket.on(this.ipxeVersion + ' log', entry => {
      this.log.push({ id: this.log.length, msg: entry.msg, status: entry.status, date: entry.date })
    })

    // Disable the buttons if a building process is running.
    axios.get('/api/ipxe/' + this.ipxeVersion + '/status').then(result => {
      this.disableButtons = result.data.data
    })

    this.$socket.on(this.ipxeVersion + ' inProgress', inProgress => {
      this.disableButtons = inProgress
    })
  },
  updated () {
    if (this.autoscroll) {
      // Use this instead for the virtual scroller
      this.$refs.log.$el.scrollTop = this.$refs.log.$el.scrollHeight
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  .scroll-overlay {
    position: absolute;
    margin-top: -35px;
    width: 100%;
    display: flex;
    justify-content: center;
    background-color: rgba(0, 0, 0, .5);
    height: 35px;
  }
  .terminal {
    padding: 12px 24px 12px 24px;
    height: 588px;
    overflow: auto;
  }

  .script-editor >>> .CodeMirror {
    height: calc(90vh - 160px);
  }
  .subtabs {
    z-index: 1;
  }
</style>