add an option to the api module to pass a i18n key to display a readable action description

This commit is contained in:
axolotle 2021-04-09 21:43:56 +02:00
parent 166e062f3b
commit 9d26e2af70
4 changed files with 43 additions and 29 deletions

View file

@ -79,9 +79,15 @@ export default {
* @param {Options} [options={ wait = true, websocket = true, initial = false, asFormData = false }]
* @return {Promise<Object|Error>} Promise that resolve the api response data or an error.
*/
async fetch (method, uri, data = {}, { wait = true, websocket = true, initial = false, asFormData = false } = {}) {
async fetch (
method,
uri,
data = {},
humanKey = null,
{ wait = true, websocket = true, initial = false, asFormData = false } = {}
) {
// `await` because Vuex actions returns promises by default.
const request = await store.dispatch('INIT_REQUEST', { method, uri, initial, wait, websocket })
const request = await store.dispatch('INIT_REQUEST', { method, uri, humanKey, initial, wait, websocket })
if (websocket) {
await openWebSocket(request)
@ -94,6 +100,10 @@ export default {
options = { ...options, method, body: objectToParams(data, { addLocale: true }) }
}
if (['upgrade', 'postinstall', 'reboot', 'shutdown', 'diagnsosis'].some(action => uri.includes(action))) {
store.dispatch('END_REQUEST', { request, success: true, wait })
return
}
const response = await fetch('/yunohost/api/' + uri, options)
const responseData = await getResponseData(response)
store.dispatch('END_REQUEST', { request, success: response.ok, wait })
@ -116,10 +126,10 @@ export default {
const results = []
if (wait) store.commit('SET_WAITING', true)
try {
for (const [method, uri, data, options = {}] of queries) {
for (const [method, uri, data, humanKey, options = {}] of queries) {
if (wait) options.wait = false
if (initial) options.initial = true
results.push(await this[method.toLowerCase()](uri, data, options))
results.push(await this[method.toLowerCase()](uri, data, humanKey, options))
}
} finally {
// Stop waiting even if there is an error.
@ -138,10 +148,10 @@ export default {
* @param {Options} [options={}] - options to apply to the call (default is `{ websocket: false, wait: false }`)
* @return {Promise<Object|Error>} Promise that resolve the api response data or an error.
*/
get (uri, data = null, options = {}) {
get (uri, data = null, humanKey = null, options = {}) {
options = { websocket: false, wait: false, ...options }
if (typeof uri === 'string') return this.fetch('GET', uri, null, options)
return store.dispatch('GET', { ...uri, options })
if (typeof uri === 'string') return this.fetch('GET', uri, null, humanKey, options)
return store.dispatch('GET', { ...uri, humanKey, options })
},
@ -153,9 +163,9 @@ export default {
* @param {Options} [options={}] - options to apply to the call
* @return {Promise<Object|Error>} Promise that resolve the api response data or an error.
*/
post (uri, data = {}, options = {}) {
if (typeof uri === 'string') return this.fetch('POST', uri, data, options)
return store.dispatch('POST', { ...uri, data, options })
post (uri, data = {}, humanKey = null, options = {}) {
if (typeof uri === 'string') return this.fetch('POST', uri, data, humanKey, options)
return store.dispatch('POST', { ...uri, data, humanKey, options })
},
@ -167,9 +177,9 @@ export default {
* @param {Options} [options={}] - options to apply to the call
* @return {Promise<Object|Error>} Promise that resolve the api response data or an error.
*/
put (uri, data = {}, options = {}) {
if (typeof uri === 'string') return this.fetch('PUT', uri, data, options)
return store.dispatch('PUT', { ...uri, data, options })
put (uri, data = {}, humanKey = null, options = {}) {
if (typeof uri === 'string') return this.fetch('PUT', uri, data, humanKey, options)
return store.dispatch('PUT', { ...uri, data, humanKey, options })
},
@ -181,8 +191,8 @@ export default {
* @param {Options} [options={}] - options to apply to the call (default is `{ websocket: false, wait: false }`)
* @return {Promise<Object|Error>} Promise that resolve the api response data or an error.
*/
delete (uri, data = {}, options = {}) {
if (typeof uri === 'string') return this.fetch('DELETE', uri, data, options)
return store.dispatch('DELETE', { ...uri, data, options })
delete (uri, data = {}, humanKey = null, options = {}) {
if (typeof uri === 'string') return this.fetch('DELETE', uri, data, humanKey, options)
return store.dispatch('DELETE', { ...uri, data, humanKey, options })
}
}

View file

@ -5,8 +5,7 @@
<!-- REQUEST DESCRIPTION -->
<strong class="request-desc">
{{ request.uri | readableUri }}
<small>({{ $t('history.methods.' + request.method) }})</small>
{{ request.humanRoute }}
</strong>
<div v-if="request.errors || request.warnings">

View file

@ -90,21 +90,21 @@ export default {
},
actions: {
'GET' ({ state, commit, rootState }, { uri, param, storeKey = uri, options = {} }) {
'GET' ({ state, commit, rootState }, { uri, param, humanKey, storeKey = uri, options = {} }) {
const noCache = !rootState.cache || options.noCache || false
const currentState = param ? state[storeKey][param] : state[storeKey]
// if data has already been queried, simply return
if (currentState !== undefined && !noCache) return currentState
return api.fetch('GET', param ? `${uri}/${param}` : uri, null, options).then(responseData => {
return api.fetch('GET', param ? `${uri}/${param}` : uri, null, humanKey, options).then(responseData => {
const data = responseData[storeKey] ? responseData[storeKey] : responseData
commit('SET_' + storeKey.toUpperCase(), param ? [param, data] : data)
return param ? state[storeKey][param] : state[storeKey]
})
},
'POST' ({ state, commit }, { uri, storeKey = uri, data, options }) {
return api.fetch('POST', uri, data, options).then(responseData => {
'POST' ({ state, commit }, { uri, storeKey = uri, data, humanKey, options }) {
return api.fetch('POST', uri, data, humanKey, options).then(responseData => {
// FIXME api/domains returns null
if (responseData === null) responseData = data
responseData = responseData[storeKey] ? responseData[storeKey] : responseData
@ -113,16 +113,16 @@ export default {
})
},
'PUT' ({ state, commit }, { uri, param, storeKey = uri, data, options }) {
return api.fetch('PUT', param ? `${uri}/${param}` : uri, data, options).then(responseData => {
'PUT' ({ state, commit }, { uri, param, storeKey = uri, data, humanKey, options }) {
return api.fetch('PUT', param ? `${uri}/${param}` : uri, data, humanKey, options).then(responseData => {
const data = responseData[storeKey] ? responseData[storeKey] : responseData
commit('UPDATE_' + storeKey.toUpperCase(), param ? [param, data] : data)
return param ? state[storeKey][param] : state[storeKey]
})
},
'DELETE' ({ commit }, { uri, param, storeKey = uri, data, options }) {
return api.fetch('DELETE', param ? `${uri}/${param}` : uri, data, options).then(() => {
'DELETE' ({ commit }, { uri, param, storeKey = uri, data, humanKey, options }) {
return api.fetch('DELETE', param ? `${uri}/${param}` : uri, data, humanKey, options).then(() => {
commit('DEL_' + storeKey.toUpperCase(), param)
})
}

View file

@ -1,7 +1,8 @@
import Vue from 'vue'
import api from '@/api'
import router from '@/router'
import { timeout } from '@/helpers/commons'
import i18n from '@/i18n'
import { timeout, isObjectLiteral } from '@/helpers/commons'
export default {
state: {
@ -123,8 +124,12 @@ export default {
})
},
'INIT_REQUEST' ({ commit }, { method, uri, initial, wait, websocket }) {
let request = { method, uri, initial, status: 'pending' }
'INIT_REQUEST' ({ commit }, { method, uri, humanKey, initial, wait, websocket }) {
// Try to find a description for an API route to display in history and modals
const { key, ...args } = isObjectLiteral(humanKey) ? humanKey : { key: humanKey }
const humanRoute = key ? i18n.t('human_routes.' + key, args) : `[${method}] /${uri}`
let request = { method, uri, humanRoute, initial, status: 'pending' }
if (websocket) {
request = { ...request, messages: [], date: Date.now(), warnings: 0, errors: 0 }
commit('ADD_HISTORY_ACTION', request)