- {{ $t(reports || loading ? 'diagnosis_explanation' : 'diagnosis_first_run') }}
+ {{ $t(reports ? 'diagnosis_explanation' : 'diagnosis_first_run') }}
{{ $t('unignore') }}
{{ $t('ignore') }}
@@ -114,8 +114,10 @@ export default {
data () {
return {
- queries: ['diagnosis/show?full'],
- loading: true,
+ queries: [
+ ['PUT', 'diagnosis/run?except_if_never_ran_yet', {}, 'diagnosis.run'],
+ ['GET', 'diagnosis?full']
+ ],
reports: undefined
}
},
@@ -149,14 +151,13 @@ export default {
item.icon = icon
},
- formatData (data) {
- if (data === null) {
+ onQueriesResponse (_, reportsData) {
+ if (reportsData === null) {
this.reports = null
- this.loading = false
return
}
- const reports = data.reports
+ const reports = reportsData.reports
for (const report of reports) {
report.warnings = 0
report.errors = 0
@@ -168,25 +169,29 @@ export default {
report.noIssues = report.warnings + report.errors === 0
}
this.reports = reports
- this.loading = false
},
- runDiagnosis (id = null) {
+ runDiagnosis ({ id = null, description } = {}) {
const param = id !== null ? '?force' : ''
const data = id !== null ? { categories: [id] } : {}
- api.post('diagnosis/run' + param, data).then(this.$refs.view.fetchQueries)
+
+ api.put(
+ 'diagnosis/run' + param,
+ data,
+ { key: 'diagnosis.run' + (id !== null ? '_specific' : ''), description }
+ ).then(this.$refs.view.fetchQueries)
},
- toggleIgnoreIssue (ignore, report, item) {
- const key = (ignore ? 'add' : 'remove') + '_filter'
- const filterArgs = Object.entries(item.meta).reduce((filterArgs, entries) => {
- filterArgs.push(entries.join('='))
- return filterArgs
- }, [report.id])
+ toggleIgnoreIssue (action, report, item) {
+ const filterArgs = [report.id].concat(Object.entries(item.meta).map(entries => entries.join('=')))
- api.post('diagnosis/ignore', { [key]: filterArgs }).then(() => {
- item.ignored = ignore
- if (ignore) {
+ api.put(
+ 'diagnosis/' + action,
+ { filter: filterArgs },
+ `diagnosis.${action}.${item.status.toLowerCase()}`
+ ).then(() => {
+ item.ignored = action === 'ignore'
+ if (item.ignored) {
report[item.status.toLowerCase() + 's']--
} else {
report.ignoreds--
@@ -202,10 +207,6 @@ export default {
}
},
- created () {
- api.post('diagnosis/run?except_if_never_ran_yet')
- },
-
filters: { distanceToNow }
}
diff --git a/app/src/views/domain/DomainAdd.vue b/app/src/views/domain/DomainAdd.vue
index c2fc6f02..6b9cfee1 100644
--- a/app/src/views/domain/DomainAdd.vue
+++ b/app/src/views/domain/DomainAdd.vue
@@ -8,30 +8,31 @@
diff --git a/app/src/views/service/ServiceInfo.vue b/app/src/views/service/ServiceInfo.vue
index f222ccbf..299abb3e 100644
--- a/app/src/views/service/ServiceInfo.vue
+++ b/app/src/views/service/ServiceInfo.vue
@@ -1,6 +1,6 @@
@@ -82,8 +82,8 @@ export default {
data () {
return {
queries: [
- 'services/' + this.name,
- `services/${this.name}/log?number=50`
+ ['GET', 'services/' + this.name],
+ ['GET', `services/${this.name}/log?number=50`]
],
// Service data
infos: undefined,
@@ -96,7 +96,7 @@ export default {
},
methods: {
- formatServiceData (
+ onQueriesResponse (
// eslint-disable-next-line
{ status, description, start_on_boot, last_state_change, configuration },
logs
@@ -120,14 +120,11 @@ export default {
)
if (!confirmed) return
- if (!['start', 'restart', 'stop'].includes(action)) return
- const method = action === 'stop' ? 'delete' : 'put'
- const uri = action === 'restart'
- ? `services/${this.name}/restart`
- : 'services/' + this.name
-
- // FIXME API doesn't return anything to the PUT so => json err
- api[method](uri).then(this.$refs.view.fetchQueries)
+ api.put(
+ `services/${this.name}/${action}`,
+ {},
+ { key: 'services.' + action, name: this.name }
+ ).then(this.$refs.view.fetchQueries)
},
shareLogs () {
@@ -141,6 +138,7 @@ export default {
}).then(response => {
if (response.ok) return response.json()
// FIXME flash error
+ /* eslint-disable-next-line */
else console.log('error', response)
}).then(({ key }) => {
window.open('https://paste.yunohost.org/' + key, '_blank')
diff --git a/app/src/views/service/ServiceList.vue b/app/src/views/service/ServiceList.vue
index dae22900..0f6348f5 100644
--- a/app/src/views/service/ServiceList.vue
+++ b/app/src/views/service/ServiceList.vue
@@ -6,7 +6,7 @@
:filtered-items="filteredServices"
items-name="services"
:queries="queries"
- @queries-response="formatServices"
+ @queries-response="onQueriesResponse"
>
{
const service = services[name]
if (service.last_state_change === 'unknown') {
diff --git a/app/src/views/tool/ToolAdminpw.vue b/app/src/views/tool/ToolAdminpw.vue
index 1426421a..8ff3f6cf 100644
--- a/app/src/views/tool/ToolAdminpw.vue
+++ b/app/src/views/tool/ToolAdminpw.vue
@@ -11,7 +11,7 @@
import api from '@/api'
import { validationMixin } from 'vuelidate'
-import { PasswordForm } from '@/components/reusableForms'
+import { PasswordForm } from '@/views/_partials'
import { required, minLength } from '@/helpers/validators'
export default {
@@ -40,20 +40,24 @@ export default {
},
methods: {
- onSubmit ({ password, currentPassword }) {
+ onSubmit ({ currentPassword, password }) {
this.serverError = ''
- // Use `api.fetch` to avoid automatic redirect on 401 (Unauthorized).
- api.fetch('POST', 'login', { password: currentPassword }).then(response => {
- if (response.status === 401) {
- // Dispatch `SERVER_RESPONDED` to hide waiting overlay and display error.
- this.$store.dispatch('SERVER_RESPONDED', true)
+
+ api.fetchAll(
+ [['POST', 'login', { password: currentPassword }, null, { websocket: false }],
+ ['PUT', 'adminpw', { new_password: password }, 'adminpw']],
+ { wait: true }
+ ).then(() => {
+ this.$store.dispatch('DISCONNECT')
+ }).catch(err => {
+ if (err.name === 'APIUnauthorizedError') {
+ // Prevent automatic disconnect if error in current password.
this.serverError = this.$i18n.t('wrong_password')
- } else if (response.ok) {
- api.put('adminpw', { new_password: password }).then(() => {
- this.$store.dispatch('DISCONNECT')
- }).catch(error => {
- this.serverError = error.message
- })
+ } else if (err.name === 'APIBadRequestError') {
+ // Display form error
+ this.serverError = err.message
+ } else {
+ throw err
}
})
}
diff --git a/app/src/views/tool/ToolFirewall.vue b/app/src/views/tool/ToolFirewall.vue
index ac8fc41e..cd0592a2 100644
--- a/app/src/views/tool/ToolFirewall.vue
+++ b/app/src/views/tool/ToolFirewall.vue
@@ -1,6 +1,6 @@
@@ -98,7 +98,9 @@ export default {
data () {
return {
- queries: ['/firewall?raw'],
+ queries: [
+ ['GET', '/firewall?raw']
+ ],
serverError: '',
// Ports tables data
@@ -113,8 +115,8 @@ export default {
// Ports form data
actionChoices: [
- { value: 'open', text: this.$i18n.t('open') },
- { value: 'close', text: this.$i18n.t('close') }
+ { value: 'allow', text: this.$i18n.t('open') },
+ { value: 'disallow', text: this.$i18n.t('close') }
],
connectionChoices: [
{ value: 'ipv4', text: this.$i18n.t('ipv4') },
@@ -126,7 +128,7 @@ export default {
{ value: 'Both', text: this.$i18n.t('both') }
],
form: {
- action: 'open',
+ action: 'allow',
port: undefined,
connection: 'ipv4',
protocol: 'TCP'
@@ -145,7 +147,7 @@ export default {
},
methods: {
- formatFirewallData (data) {
+ onQueriesResponse (data) {
const ports = Object.values(data).reduce((ports, protocols) => {
for (const type of ['TCP', 'UDP']) {
for (const port of protocols[type]) {
@@ -174,23 +176,21 @@ export default {
this.upnpEnabled = data.uPnP.enabled
},
- togglePort ({ action, port, protocol, connection }) {
- return new Promise((resolve, reject) => {
- this.$askConfirmation(
- this.$i18n.t('confirm_firewall_' + action, { port, protocol, connection })
- ).then(confirmed => {
- if (confirmed) {
- const method = action === 'open' ? 'post' : 'delete'
- api[method](`/firewall/port?${connection}_only`, { port, protocol }).then(() => {
- resolve(confirmed)
- }).catch(error => {
- reject(error)
- })
- } else {
- resolve(confirmed)
- }
- })
- })
+ async togglePort ({ action, port, protocol, connection }) {
+ const confirmed = await this.$askConfirmation(
+ this.$i18n.t('confirm_firewall_' + action, { port, protocol, connection })
+ )
+ if (!confirmed) {
+ return Promise.resolve(confirmed)
+ }
+
+ const actionTrad = this.$i18n.t({ allow: 'open', disallow: 'close' }[action])
+ return api.put(
+ `firewall/${protocol}/${action}/${port}?${connection}_only`,
+ {},
+ { key: 'firewall.ports', protocol, action: actionTrad, port, connection },
+ { wait: false }
+ ).then(() => confirmed)
},
async toggleUpnp (value) {
@@ -198,17 +198,22 @@ export default {
const confirmed = await this.$askConfirmation(this.$i18n.t('confirm_upnp_' + action))
if (!confirmed) return
- api.get('firewall/upnp?action=' + action).then(() => {
+ api.put(
+ 'firewall/upnp/' + action,
+ {},
+ { key: 'firewall.upnp', action: this.$i18n.t(action) }
+ ).then(() => {
// FIXME Couldn't test when it works.
this.$refs.view.fetchQueries()
}).catch(err => {
+ if (err.name !== 'APIBadRequestError') throw err
this.upnpError = err.message
})
},
onTablePortToggling (port, protocol, connection, index, value) {
this.$set(this.protocols[protocol][index], connection, value)
- const action = value ? 'open' : 'close'
+ const action = value ? 'allow' : 'disallow'
this.togglePort({ action, port, protocol, connection }).then(toggled => {
// Revert change on cancel
if (!toggled) {
diff --git a/app/src/views/tool/ToolList.vue b/app/src/views/tool/ToolList.vue
index 95b3800d..21716ca0 100644
--- a/app/src/views/tool/ToolList.vue
+++ b/app/src/views/tool/ToolList.vue
@@ -6,8 +6,8 @@
:key="item.routeName"
:to="{name: item.routeName}"
>
-
- {{ $t(item.translation) }}
+
+ {{ $t(item.translation) }}
diff --git a/app/src/views/tool/ToolLog.vue b/app/src/views/tool/ToolLog.vue
index 512fdfe2..7ca3ba4f 100644
--- a/app/src/views/tool/ToolLog.vue
+++ b/app/src/views/tool/ToolLog.vue
@@ -1,6 +1,6 @@
@@ -18,7 +18,7 @@
-
+
{{ operation.description }}
@@ -60,8 +60,8 @@
diff --git a/app/src/views/update/SystemUpdate.vue b/app/src/views/update/SystemUpdate.vue
index 8f244b0d..7deeb8e6 100644
--- a/app/src/views/update/SystemUpdate.vue
+++ b/app/src/views/update/SystemUpdate.vue
@@ -1,5 +1,8 @@
-
+
@@ -69,7 +72,10 @@ export default {
data () {
return {
- loading: true,
+ queries: [
+ ['GET', 'migrations?pending'],
+ ['PUT', 'update/all', {}, 'update']
+ ],
// API data
migrationsNotDone: undefined,
system: undefined,
@@ -78,33 +84,28 @@ export default {
},
methods: {
+ onQueriesResponse ({ migrations }, { apps, system }) {
+ this.migrationsNotDone = migrations.length !== 0
+ this.apps = apps.length ? apps : null
+ this.system = system.length ? system : null
+ },
+
async performUpgrade ({ type, id = null }) {
const confirmMsg = this.$i18n.t('confirm_update_' + type, id ? { app: id } : {})
const confirmed = await this.$askConfirmation(confirmMsg)
if (!confirmed) return
- const uri = type === 'specific_app'
- ? 'upgrade/apps?app=' + id
- : 'upgrade?' + type
-
- api.put(uri).then(() => {
- this.$router.push({ name: 'tool-logs' })
+ const uri = id !== null ? `apps/${id}/upgrade` : 'upgrade/' + type
+ api.put(uri, {}, { key: 'upgrade.' + (id ? 'app' : type), app: id }).then(() => {
+ if (id !== null) {
+ this.apps = this.apps.filter(app => id !== app.id)
+ } else if (type === 'apps') {
+ this.apps = null
+ } else {
+ this.system = null
+ }
})
}
- },
-
- created () {
- // Since we need to query a `PUT` method, we won't use ViewBase's `queries` prop and
- // its automatic loading handling.
- Promise.all([
- api.get('migrations?pending'),
- api.put('update')
- ]).then(([{ migrations }, { apps, system }]) => {
- this.migrationsNotDone = migrations.length !== 0
- this.apps = apps.length ? apps : null
- this.system = system.length ? system : null
- this.loading = false
- })
}
}
diff --git a/app/src/views/user/UserCreate.vue b/app/src/views/user/UserCreate.vue
index c2488d30..fb8d7a89 100644
--- a/app/src/views/user/UserCreate.vue
+++ b/app/src/views/user/UserCreate.vue
@@ -60,6 +60,7 @@