-
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ text }}
+
+
@@ -25,7 +47,20 @@ export default {
name: 'ApiWaitOverlay',
computed: {
- ...mapGetters(['waiting'])
+ ...mapGetters(['waiting', 'lastAction']),
+
+ progress () {
+ const progress = this.lastAction.progress
+ if (!progress) return null
+ return {
+ values: progress, max: progress.reduce((sum, value) => (sum + value), 0)
+ }
+ },
+
+ messages () {
+ const messages = this.lastAction.messages
+ return messages.length > 0 ? this.lastAction.messages : null
+ }
}
}
@@ -35,6 +70,7 @@ export default {
position: sticky;
top: 5vh;
margin: 0 5%;
+ padding: 3rem 0;
@include media-breakpoint-up(md) {
margin: 0 10%;
@@ -43,4 +79,33 @@ export default {
margin: 0 20%;
}
}
+
+.card-body {
+ padding-bottom: 2rem;
+}
+
+.progress {
+ margin-top: 2rem;
+}
+
+.list-group {
+ max-height: 50vh;
+ overflow-y: auto;
+
+ // Hide all message except the last one if the mouse isn't hovering the list group.
+ &:not(:hover) .list-group-item:not(:last-of-type) {
+ display: none;
+ }
+}
+
+.pacman {
+ animation: back-and-forth 4s linear infinite;
+
+ @keyframes back-and-forth {
+ 0%, 100% { transform: translateX(-50vw) scale(1); }
+ 49% { transform: translateX(50vw) scale(1); }
+ 50% { transform: translateX(50vw) scale(-1); }
+ 99% { transform: translateX(-50vw) scale(-1); }
+ }
+}
diff --git a/app/src/helpers/api.js b/app/src/helpers/api.js
index 4f224b9d..64a33f60 100644
--- a/app/src/helpers/api.js
+++ b/app/src/helpers/api.js
@@ -52,7 +52,7 @@ export function objectToParams (object, { addLocale = false } = {}) {
* @return {DigestedResponse} Parsed response's json, response's text or an error.
*/
export async function handleResponse (response) {
- store.commit('UPDATE_WAITING', false)
+ store.dispatch('SERVER_RESPONDED')
if (!response.ok) return handleErrors(response)
// FIXME the api should always return json objects
const responseText = await response.text()
@@ -174,7 +174,7 @@ export default {
* @return {Promise
} Promise that resolve the api responses as an array.
*/
post (uri, data = {}) {
- store.commit('UPDATE_WAITING', true)
+ store.dispatch('WAITING_FOR_RESPONSE', [uri, 'POST'])
return this.fetch('POST', uri, data).then(handleResponse)
},
@@ -186,7 +186,7 @@ export default {
* @return {Promise} Promise that resolve the api responses as an array.
*/
put (uri, data = {}) {
- store.commit('UPDATE_WAITING', true)
+ store.dispatch('WAITING_FOR_RESPONSE', [uri, 'PUT'])
return this.fetch('PUT', uri, data).then(handleResponse)
},
@@ -198,9 +198,9 @@ export default {
* @return {Promise<('ok'|Error)>} Promise that resolve the api responses as an array.
*/
delete (uri, data = {}) {
- store.commit('UPDATE_WAITING', true)
+ store.dispatch('WAITING_FOR_RESPONSE', [uri, 'DELETE'])
return this.fetch('DELETE', uri, data).then(response => {
- store.commit('UPDATE_WAITING', false)
+ store.dispatch('SERVER_RESPONDED')
return response.ok ? 'ok' : handleErrors(response)
})
}
diff --git a/app/src/store/info.js b/app/src/store/info.js
index c94d0601..346ddd1d 100644
--- a/app/src/store/info.js
+++ b/app/src/store/info.js
@@ -1,12 +1,14 @@
+import Vue from 'vue'
import api, { timeout } from '@/helpers/api'
import router from '@/router'
export default {
state: {
+ host: window.location.host,
connected: localStorage.getItem('connected') === 'true',
yunohost: null, // yunohost app infos: Object {version, repo}
waiting: false,
- host: window.location.host
+ history: []
},
mutations: {
@@ -21,6 +23,18 @@ export default {
'UPDATE_WAITING' (state, boolean) {
state.waiting = boolean
+ },
+
+ 'ADD_HISTORY_ENTRY' (state, [uri, method, date]) {
+ state.history.push({ uri, method, date, messages: [] })
+ },
+
+ 'ADD_MESSAGE' (state, message) {
+ state.history[state.history.length - 1].messages.push(message)
+ },
+
+ 'UPDATE_PROGRESS' (state, progress) {
+ Vue.set(state.history[state.history.length - 1], 'progress', progress)
}
},
@@ -80,15 +94,46 @@ export default {
})
},
- 'DISPATCH_MESSAGE' (store, message) {
- console.log(message)
+ 'WAITING_FOR_RESPONSE' ({ commit }, [uri, method]) {
+ commit('UPDATE_WAITING', true)
+ commit('ADD_HISTORY_ENTRY', [uri, method, Date.now()])
+ },
+
+ 'SERVER_RESPONDED' ({ state, dispatch, commit }) {
+ if (!state.waiting) return
+ commit('UPDATE_WAITING', false)
+ },
+
+ 'DISPATCH_MESSAGE' ({ commit }, messages) {
+ const typeToColor = { error: 'danger' }
+ for (const type in messages) {
+ const message = {
+ text: messages[type],
+ type: type in typeToColor ? typeToColor[type] : type
+ }
+ let progressBar = message.text.match(/^\[#*\+*\.*\] > /)
+ if (progressBar) {
+ progressBar = progressBar[0]
+ message.text = message.text.replace(progressBar, '')
+ const progress = { '#': 0, '+': 0, '.': 0 }
+ for (const char of progressBar) {
+ if (char in progress) progress[char] += 1
+ }
+ commit('UPDATE_PROGRESS', Object.values(progress))
+ }
+ if (message.text) {
+ commit('ADD_MESSAGE', message)
+ }
+ }
}
},
getters: {
+ host: state => state.host,
connected: state => (state.connected),
yunohost: state => (state.yunohost),
waiting: state => state.waiting,
- host: state => state.host
+ history: state => state.history,
+ lastAction: state => state.history[state.history.length - 1]
}
}