summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJannik Schönartz2019-02-28 01:26:16 +0100
committerJannik Schönartz2019-02-28 01:26:16 +0100
commitc1efc80017ec5f3d6e492749cb19c947c57fd7c0 (patch)
tree8b8d72a843d6c0ae2d87c76464e00d6bad7c9c82
parent[server/ipxe] Fix codemirror only loading on click bug & add the fixes for th... (diff)
downloadbas-c1efc80017ec5f3d6e492749cb19c947c57fd7c0.tar.gz
bas-c1efc80017ec5f3d6e492749cb19c947c57fd7c0.tar.xz
bas-c1efc80017ec5f3d6e492749cb19c947c57fd7c0.zip
[webapp/ipxe] Add scroll to bottom feature, fix multiline bug and fix cancel
-rw-r--r--server/lib/shell.js26
-rw-r--r--webapp/src/components/IpxeBuilderModuleConfig.vue105
2 files changed, 94 insertions, 37 deletions
diff --git a/server/lib/shell.js b/server/lib/shell.js
index 81d3008..fd5151f 100644
--- a/server/lib/shell.js
+++ b/server/lib/shell.js
@@ -31,41 +31,59 @@ module.exports = {
// Cloning git.
sendToLog(ipxeVersion, 'Cloning git ...\n', 'primary')
await cloneIpxe(ipxeVersion)
+ if (!building[ipxeVersion]) return
// Copying configs.
sendToLog(ipxeVersion, 'Copying configs ...\n', 'primary')
copyConfigs(ipxeVersion)
+ if (!building[ipxeVersion]) return
// Make ipxe.
sendToLog(ipxeVersion, 'Make iPXE ...\n', 'primary')
shell.cd(path.join(__appdir, 'ipxe', 'ipxe_' + ipxeVersion, 'src'))
await new Promise((resolve, reject) => {
+ if (!building[ipxeVersion]) return
make[ipxeVersion] = shell.exec(makeCmd, { async: true }, () => {
// make[ipxeVersion] = child.exec(makeCmd, { async: true }, () => {
- updateInProgress(ipxeVersion, false)
resolve()
})
// Send the output to the frontend log.
make[ipxeVersion].stdout.on('data', data => {
- sendToLog(ipxeVersion, data, 'normal')
+ const multiline = data.split('\n')
+ if (multiline.length > 2) {
+ multiline.forEach(line => {
+ if (line) sendToLog(ipxeVersion, line, 'normal')
+ })
+ } else sendToLog(ipxeVersion, data, 'normal')
})
make[ipxeVersion].stderr.on('data', data => {
- sendToLog(ipxeVersion, data, 'error')
+ const multiline = data.split('\n')
+ if (multiline.length > 2) {
+ multiline.forEach(line => {
+ if (line) sendToLog(ipxeVersion, line, 'error')
+ })
+ } else sendToLog(ipxeVersion, data, 'error')
})
})
+ if (!building[ipxeVersion]) return
// Copy and rename the ipxe file.
+ sendToLog(ipxeVersion, 'Copying ipxe file ...\n', 'primary')
shell.cp('bin/undionly.kpxe', path.join(__appdir, 'ipxe'))
shell.mv(path.join(__appdir, 'ipxe', 'undionly.kpxe'), path.join(__appdir, 'ipxe', 'ipxe.' + ipxeVersion))
+ sendToLog(ipxeVersion, 'done\n', 'success')
+ updateInProgress(ipxeVersion, false)
},
cancelBuilding: async function (req, res) {
- const process = make[req.params.version]
+ const ipxeVersion = req.params.version
+ const process = make[ipxeVersion]
if (process) {
const kill = 'pkill -P ' + process.pid
shell.exec(kill)
+ updateInProgress(ipxeVersion, false)
}
res.send({ status: 'SUCCESS', data: process })
},
diff --git a/webapp/src/components/IpxeBuilderModuleConfig.vue b/webapp/src/components/IpxeBuilderModuleConfig.vue
index 709a04b..aaeb197 100644
--- a/webapp/src/components/IpxeBuilderModuleConfig.vue
+++ b/webapp/src/components/IpxeBuilderModuleConfig.vue
@@ -1,42 +1,44 @@
<i18n>
{
"en": {
- "efi": "EFI",
+ "alreadyBuiling": "The iPXE building process not finished",
"bios": "BIOS",
- "general": "general.h",
- "console": "console.h",
- "script": "Embedded script (EMBED=)",
- "trust": "Embedded certificate (TRUST=)",
- "ipxe": "iPXE",
+ "buildingIpxe": "Building iPXE ...",
"buildIpxe": "Build iPXE",
- "scriptSaved": "Embedded script saved successfully",
+ "cancelIpxe": "Cancel iPXE",
"certificateSaved": "Certificate saved successfully",
- "generalSaved": "general.h saved successfully",
- "consoleSaved": "console.h saved successfully",
- "buildingIpxe": "Building iPXE ...",
- "cleanIpxe": "Clean iPXE",
"cleaningIpxe": "Cleaning iPXE ...",
- "alreadyBuiling": "The iPXE building process not finished",
- "cancelIpxe": "Cancel iPXE"
- },
- "de": {
+ "cleanIpxe": "Clean iPXE",
+ "console": "console.h",
+ "consoleSaved": "console.h saved successfully",
"efi": "EFI",
- "bios": "BIOS",
"general": "general.h",
- "console": "console.h",
- "script": "Eingebettetes Skript (EMBED=)",
- "trust": "Eingebettetes Zertifikat (TRUST=)",
+ "generalSaved": "general.h saved successfully",
"ipxe": "iPXE",
+ "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",
- "scriptSaved": "Eingebettetes Skript wurde erfolgreich gespeichert",
+ "cancelIpxe": "iPXE stoppen",
"certificateSaved": "Zertifikat wurde erfolgreich gespeichert",
- "generalSaved": "general.h wurde erfolgreich gespeichert",
+ "console": "console.h",
"consoleSaved": "console.h wurde erfolgreich gespeichert",
- "buildingIpxe": "iPXE wird gebaut ...",
- "cleanIpxe": "iPXE aufräumen",
"cleaningIpxe": "iPXE wird aufgeräumt ..",
- "alreadyBuiling": "Der iPXE build-Prozess ist noch nicht abgeschlossen",
- "cancelIpxe": "iPXE stoppen"
+ "cleanIpxe": "iPXE aufräumen",
+ "efi": "EFI",
+ "general": "general.h",
+ "generalSaved": "general.h wurde erfolgreich gespeichert",
+ "ipxe": "iPXE",
+ "script": "Eingebettetes Skript (EMBED=)",
+ "scriptSaved": "Eingebettetes Skript wurde erfolgreich gespeichert",
+ "scrollDown": "Gehe nach unten",
+ "trust": "Eingebettetes Zertifikat (TRUST=)"
}
}
</i18n>
@@ -45,19 +47,30 @@
<div>
<v-subheader>{{ $t('ipxe') }}</v-subheader>
- <v-card style="height: 588px;" ref="log">
+
+ <v-card style="height: 588px;" ref="log" v-on:wheel="manualScroll">
<RecycleScroller :items="log" :item-size="21" style="height: 100%;">
<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>
+ </v-card>
- <!--
- <v-card style="padding-left: 24px;padding-right: 24px; padding-top: 12px; padding-bottom: 12px; height: 50vh; overflow: auto;" ref="log">
+ <!-- Recycle Scroller or not?! One of them ^v has to go! -->
+ <!--
+ <v-card class="terminal" ref="log" v-on:wheel="manualScroll">
<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>-->
+ <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>
@@ -151,7 +164,8 @@ export default {
generalExpanded: null,
consoleExpanded: null,
log: [],
- disableButtons: false
+ disableButtons: false,
+ autoscroll: true
}
},
computed: {
@@ -205,6 +219,14 @@ export default {
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 === -100) this.autoscroll = false
+ // else if (this.$refs.log.$el.scrollTop + 800 >= this.$refs.log.$el.scrollHeight) this.autoscroll = true
+ else if (this.$refs.log.$el.firstElementChild.scrollTop + 800 >= this.$refs.log.$el.firstElementChild.scrollHeight) this.autoscroll = true
+ },
+ toTheBottom () {
+ this.autoscroll = true
}
},
created () {
@@ -248,12 +270,29 @@ export default {
})
},
updated () {
- this.$refs.log.$el.firstElementChild.scrollTop = this.$refs.log.$el.firstElementChild.scrollHeight
+ if (this.autoscroll) {
+ // this.$refs.log.$el.scrollTop = this.$refs.log.$el.scrollHeight
+ // Use this instead for the virtual scroller
+ this.$refs.log.$el.firstElementChild.scrollTop = this.$refs.log.$el.firstElementChild.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;
+ }
</style>