diff --git a/platypush/backend/http/webapp/src/components/elements/CopyButton.vue b/platypush/backend/http/webapp/src/components/elements/CopyButton.vue
index f8f2609241..9878f67964 100644
--- a/platypush/backend/http/webapp/src/components/elements/CopyButton.vue
+++ b/platypush/backend/http/webapp/src/components/elements/CopyButton.vue
@@ -45,5 +45,6 @@ export default {
padding: 0.5em;
font-size: 1.5em;
cursor: pointer;
+ z-index: 1;
}
diff --git a/platypush/backend/http/webapp/src/components/panels/Extensions/Install.vue b/platypush/backend/http/webapp/src/components/panels/Extensions/Install.vue
index 3d92de3ccb..63d8415a8f 100644
--- a/platypush/backend/http/webapp/src/components/panels/Extensions/Install.vue
+++ b/platypush/backend/http/webapp/src/components/panels/Extensions/Install.vue
@@ -1,9 +1,43 @@
@@ -12,14 +46,18 @@ import 'highlight.js/lib/common'
import 'highlight.js/styles/stackoverflow-dark.min.css'
import hljs from "highlight.js"
import CopyButton from "@/components/elements/CopyButton"
+import Loading from "@/components/Loading"
import Utils from "@/Utils"
export default {
name: "Install",
mixins: [Utils],
+ emit: ['install-start', 'install-end'],
components: {
CopyButton,
+ Loading,
},
+
props: {
extension: {
type: Object,
@@ -27,6 +65,14 @@ export default {
},
},
+ data() {
+ return {
+ installRunning: false,
+ installOutput: null,
+ pendingCommands: 0,
+ }
+ },
+
computed: {
installCmd() {
const cmd = this.extension.deps.install_cmd.join('\n').trim()
@@ -47,29 +93,142 @@ export default {
)
},
},
+
+ methods: {
+ wsProcess(path) {
+ try {
+ const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws'
+ const url = `${protocol}://${location.host}${path}`
+ const ws = new WebSocket(url)
+
+ ws.onmessage = this.onMessage
+ ws.onerror = this.onError
+ ws.onclose = this.onClose
+ } catch (err) {
+ console.error('Websocket initialization error') // TODO notify
+ console.error(err)
+ return
+ }
+ },
+
+ onMessage(msg) {
+ if (!this.installOutput)
+ this.installOutput = ''
+
+ this.installOutput += msg.data
+ },
+
+ onClose() {
+ this.installRunning = false
+ this.$emit('install-end', this.extension)
+ },
+
+ onError(error) {
+ console.error('Websocket error') // TODO notify
+ console.error(error)
+ },
+
+ installExtension() {
+ this.installRunning = true
+ this.installOutput = ''
+ this.$emit('install-start', this.extension)
+
+ const cmd = (this.extension.deps.install_cmd || []).join(';\n')
+ this.request('shell.exec', {
+ cmd: cmd,
+ ws: true,
+ }).then((output) => {
+ this.wsProcess(output.ws_path)
+ }).catch((err) => {
+ console.error(err) // TODO notify
+ })
+ },
+ },
+
+ mounted() {
+ this.$watch('installOutput', () => {
+ this.$nextTick(() => {
+ this.$refs.installOutput.focus()
+ this.$refs.installOutput.scrollTop = this.$refs.installOutput.scrollHeight
+ })
+ })
+ },
}
diff --git a/platypush/backend/http/webapp/src/components/panels/Extensions/common.scss b/platypush/backend/http/webapp/src/components/panels/Extensions/common.scss
index 22073c1572..0e19d5934c 100644
--- a/platypush/backend/http/webapp/src/components/panels/Extensions/common.scss
+++ b/platypush/backend/http/webapp/src/components/panels/Extensions/common.scss
@@ -3,6 +3,7 @@ pre {
margin: 0;
background: $code-dark-bg;
color: $code-dark-fg;
+ font-size: 0.9em;
padding: 0.5em;
overflow: auto;
}
diff --git a/platypush/backend/http/webapp/src/style/themes/light.scss b/platypush/backend/http/webapp/src/style/themes/light.scss
index 11ec4f71e8..7e37f6d0f3 100644
--- a/platypush/backend/http/webapp/src/style/themes/light.scss
+++ b/platypush/backend/http/webapp/src/style/themes/light.scss
@@ -166,7 +166,7 @@ $scrollbar-thumb-bg: #a5a2a2 !default;
$row-shadow: 0 0 1px 0.5px #cfcfcf !default;
//// Code blocks
-$code-dark-bg: #090909 !default;
-$code-dark-fg: #f0f0f0 !default;
+$code-dark-bg: rgb(11, 11, 13) !default;
+$code-dark-fg: rgb(243, 243, 250) !default;
$code-light-bg: #f2f0e9 !default;
$code-light-fg: #090909 !default;
diff --git a/platypush/backend/http/webapp/vue.config.js b/platypush/backend/http/webapp/vue.config.js
index cc6aa45cbb..67b0a044a9 100644
--- a/platypush/backend/http/webapp/vue.config.js
+++ b/platypush/backend/http/webapp/vue.config.js
@@ -36,6 +36,7 @@ module.exports = {
proxy: {
'^/ws/events': wsProxy,
'^/ws/requests': wsProxy,
+ '^/ws/shell': wsProxy,
'^/execute': httpProxy,
'^/auth': httpProxy,
'^/camera/': httpProxy,