diff --git a/src/resources/js/app.js b/src/resources/js/app.js
--- a/src/resources/js/app.js
+++ b/src/resources/js/app.js
@@ -11,33 +11,13 @@
import SupportForm from '../vue/Widgets/SupportForm'
import { Tab } from 'bootstrap'
import { loadLangAsync, i18n } from './locale'
-
-const loader = '
'
+import { clearFormValidation, pick, startLoading, stopLoading } from './utils'
const routerState = {
afterLogin: null,
isLoggedIn: !!localStorage.getItem('token')
}
-let isLoading = 0
-
-// Lock the UI with the 'loading...' element
-const startLoading = () => {
- isLoading++
- let loading = $('#app > .app-loader').removeClass('fadeOut')
- if (!loading.length) {
- $('#app').append($(loader))
- }
-}
-
-// Hide "loading" overlay
-const stopLoading = () => {
- if (isLoading > 0) {
- $('#app > .app-loader').addClass('fadeOut')
- isLoading--;
- }
-}
-
let loadingRoute
// Note: This has to be before the app is created
@@ -97,11 +77,7 @@
}
},
methods: {
- // Clear (bootstrap) form validation state
- clearFormValidation(form) {
- $(form).find('.is-invalid').removeClass('is-invalid')
- $(form).find('.invalid-feedback').remove()
- },
+ clearFormValidation,
hasPermission(type) {
const key = 'enable' + type.charAt(0).toUpperCase() + type.slice(1)
return !!(this.authInfo && this.authInfo.statusInfo[key])
@@ -129,6 +105,9 @@
return false
},
+ isDegraded() {
+ return this.authInfo && this.authInfo.isAccountDegraded
+ },
// Set user state to "logged in"
loginUser(response, dashboard, update) {
if (!update) {
@@ -187,37 +166,9 @@
return ``
},
- // Display "loading" overlay inside of the specified element
- addLoader(elem, small = true, style = null) {
- if (style) {
- $(elem).css(style)
- } else {
- $(elem).css('position', 'relative')
- }
-
- $(elem).append(small ? $(loader).addClass('small') : $(loader))
- },
- // Create an object copy with specified properties only
- pick(obj, properties) {
- let result = {}
-
- properties.forEach(prop => {
- if (prop in obj) {
- result[prop] = obj[prop]
- }
- })
-
- return result
- },
- // Remove loader element added in addLoader()
- removeLoader(elem) {
- $(elem).find('.app-loader').remove()
- },
+ pick,
startLoading,
stopLoading,
- isLoading() {
- return isLoading > 0
- },
tab(e) {
e.preventDefault()
new Tab(e.target).show()
@@ -241,7 +192,7 @@
app.updateBodyClass('error')
},
errorHandler(error) {
- this.stopLoading()
+ stopLoading()
const status = error.response ? error.response.status : 500
const message = error.response ? error.response.statusText : ''
@@ -258,32 +209,6 @@
this.errorPage(status, message)
}
},
- downloadFile(url, filename) {
- // TODO: This might not be a best way for big files as the content
- // will be stored (temporarily) in browser memory
- // TODO: This method does not show the download progress in the browser
- // but it could be implemented in the UI, axios has 'progress' property
- axios.get(url, { responseType: 'blob' })
- .then(response => {
- const link = document.createElement('a')
-
- if (!filename) {
- const contentDisposition = response.headers['content-disposition']
- filename = 'unknown'
-
- if (contentDisposition) {
- const match = contentDisposition.match(/filename="?(.+)"?/);
- if (match && match.length === 2) {
- filename = match[1];
- }
- }
- }
-
- link.href = window.URL.createObjectURL(response.data)
- link.download = filename
- link.click()
- })
- },
price(price, currency) {
// TODO: Set locale argument according to the currently used locale
return ((price || 0) / 100).toLocaleString('de-DE', { style: 'currency', currency: currency || 'CHF' })
@@ -303,9 +228,6 @@
$(event.target).closest('tr').find('a').trigger('click')
}
},
- isDegraded() {
- return this.authInfo && this.authInfo.isAccountDegraded
- },
pageName(path) {
let page = this.$route.path
@@ -405,6 +327,11 @@
// on a running application. We need this for browser testing.
config.headers['X-Test-Payment-Provider'] = window.config.paymentProvider
+ let loader = config.loader
+ if (loader) {
+ startLoading(loader)
+ }
+
return config
},
error => {
@@ -420,9 +347,19 @@
response.config.onFinish()
}
+ let loader = response.config.loader
+ if (loader) {
+ stopLoading(loader)
+ }
+
return response
},
error => {
+ let loader = error.config.loader
+ if (loader) {
+ stopLoading(loader)
+ }
+
// Do not display the error in a toast message, pass the error as-is
if (axios.isCancel(error) || error.config.ignoreErrors) {
return Promise.reject(error)
diff --git a/src/resources/js/utils.js b/src/resources/js/utils.js
new file mode 100644
--- /dev/null
+++ b/src/resources/js/utils.js
@@ -0,0 +1,134 @@
+
+/**
+ * Clear (bootstrap) form validation state
+ */
+const clearFormValidation = (form) => {
+ $(form).find('.is-invalid').removeClass('is-invalid')
+ $(form).find('.invalid-feedback').remove()
+}
+
+/**
+ * File downloader
+ */
+const downloadFile = (url, filename) => {
+ // TODO: This might not be a best way for big files as the content
+ // will be stored (temporarily) in browser memory
+ // TODO: This method does not show the download progress in the browser
+ // but it could be implemented in the UI, axios has 'progress' property
+ axios.get(url, { responseType: 'blob' })
+ .then(response => {
+ const link = document.createElement('a')
+
+ if (!filename) {
+ const contentDisposition = response.headers['content-disposition']
+ filename = 'unknown'
+
+ if (contentDisposition) {
+ const match = contentDisposition.match(/filename="?(.+)"?/);
+ if (match && match.length === 2) {
+ filename = match[1];
+ }
+ }
+ }
+
+ link.href = window.URL.createObjectURL(response.data)
+ link.download = filename
+ link.click()
+ })
+}
+
+/**
+ * Create an object copy with specified properties only
+ */
+const pick = (obj, properties) => {
+ let result = {}
+
+ properties.forEach(prop => {
+ if (prop in obj) {
+ result[prop] = obj[prop]
+ }
+ })
+
+ return result
+}
+
+const loader = ''
+
+let isLoading = 0
+
+/**
+ * Display the 'loading...' element, lock the UI
+ *
+ * @param array|string|DOMElement|null|bool|jQuery $element Supported input:
+ * - DOMElement or jQuery collection or selector string: for element-level loader inside
+ * - array: for element-level loader inside the element specified in the first array element
+ * - undefined, null or true: for page-level loader
+ * @param object $style Additional element style
+ */
+const startLoading = (element, style = null) => {
+ let small = false
+
+ if (Array.isArray(element)) {
+ style = element[1]
+ element = element[0]
+ }
+
+ if (element && element !== true) {
+ // The loader inside some page element
+ small = true
+
+ if (style) {
+ small = style.small
+ delete style.small
+ $(element).css(style)
+ } else {
+ $(element).css('position', 'relative')
+ }
+ } else {
+ // The full page loader
+ isLoading++
+ let loading = $('#app > .app-loader').removeClass('fadeOut')
+ if (loading.length) {
+ return
+ }
+
+ element = $('#app')
+ }
+
+ const loaderElement = $(loader)
+
+ if (small) {
+ loaderElement.addClass('small')
+ }
+
+ $(element).append(loaderElement)
+
+ return loaderElement
+}
+
+/**
+ * Hide the "loading" element
+ *
+ * @param array|string|DOMElement|null|bool|jQuery $element
+ * @see startLoading()
+ */
+const stopLoading = (element) => {
+ if (element && element !== true) {
+ if (Array.isArray(element)) {
+ element = element[0]
+ }
+
+ $(element).find('.app-loader').remove()
+ } else if (isLoading > 0) {
+ $('#app > .app-loader').addClass('fadeOut')
+ isLoading--;
+ }
+}
+
+export {
+ clearFormValidation,
+ downloadFile,
+ pick,
+ startLoading,
+ stopLoading
+}
diff --git a/src/resources/vue/Admin/Distlist.vue b/src/resources/vue/Admin/Distlist.vue
--- a/src/resources/vue/Admin/Distlist.vue
+++ b/src/resources/vue/Admin/Distlist.vue
@@ -83,11 +83,8 @@
}
},
created() {
- this.$root.startLoading()
-
- axios.get('/api/v4/groups/' + this.$route.params.list)
+ axios.get('/api/v4/groups/' + this.$route.params.list, { loader: true })
.then(response => {
- this.$root.stopLoading()
this.list = response.data
})
.catch(this.$root.errorHandler)
diff --git a/src/resources/vue/Admin/Resource.vue b/src/resources/vue/Admin/Resource.vue
--- a/src/resources/vue/Admin/Resource.vue
+++ b/src/resources/vue/Admin/Resource.vue
@@ -67,11 +67,8 @@
}
},
created() {
- this.$root.startLoading()
-
- axios.get('/api/v4/resources/' + this.$route.params.resource)
+ axios.get('/api/v4/resources/' + this.$route.params.resource, { loader: true })
.then(response => {
- this.$root.stopLoading()
this.resource = response.data
})
.catch(this.$root.errorHandler)
diff --git a/src/resources/vue/Admin/SharedFolder.vue b/src/resources/vue/Admin/SharedFolder.vue
--- a/src/resources/vue/Admin/SharedFolder.vue
+++ b/src/resources/vue/Admin/SharedFolder.vue
@@ -106,11 +106,8 @@
}
},
created() {
- this.$root.startLoading()
-
- axios.get('/api/v4/shared-folders/' + this.$route.params.folder)
+ axios.get('/api/v4/shared-folders/' + this.$route.params.folder, { loader: true })
.then(response => {
- this.$root.stopLoading()
this.folder = response.data
})
.catch(this.$root.errorHandler)
diff --git a/src/resources/vue/Admin/Stats.vue b/src/resources/vue/Admin/Stats.vue
--- a/src/resources/vue/Admin/Stats.vue
+++ b/src/resources/vue/Admin/Stats.vue
@@ -28,16 +28,12 @@
loadChart(name) {
const chart = $('').attr({ id: 'chart-' + name }).appendTo(this.$el)
- this.$root.addLoader(chart)
-
- axios.get('/api/v4/stats/chart/' + name)
+ axios.get('/api/v4/stats/chart/' + name, { loader: chart })
.then(response => {
- this.$root.removeLoader(chart)
this.drawChart(name, response.data)
})
.catch(error => {
console.error(error)
- this.$root.removeLoader(chart)
chart.append($('
').text(this.$t('msg.loading-failed')))
})
}
diff --git a/src/resources/vue/Admin/User.vue b/src/resources/vue/Admin/User.vue
--- a/src/resources/vue/Admin/User.vue
+++ b/src/resources/vue/Admin/User.vue
@@ -548,15 +548,11 @@
created() {
const user_id = this.$route.params.user
- this.$root.startLoading()
-
- axios.get('/api/v4/users/' + user_id)
+ axios.get('/api/v4/users/' + user_id, { loader: true })
.then(response => {
- this.$root.stopLoading()
-
this.user = response.data
- const financesTab = '#user-finances'
+ const loader = '#user-finances'
const keys = ['first_name', 'last_name', 'external_email', 'billing_address', 'phone', 'organization']
let country = this.user.settings.country
@@ -573,16 +569,11 @@
// TODO: currencies, multi-wallets, accounts
// Get more info about the wallet (e.g. payment provider related)
- this.$root.addLoader(financesTab)
- axios.get('/api/v4/wallets/' + this.user.wallets[0].id)
+ axios.get('/api/v4/wallets/' + this.user.wallets[0].id, { loader })
.then(response => {
- this.$root.removeLoader(financesTab)
this.wallet = response.data
this.setMandateState()
})
- .catch(error => {
- this.$root.removeLoader(financesTab)
- })
// Create subscriptions list
axios.get('/api/v4/users/' + user_id + '/skus')
diff --git a/src/resources/vue/App.vue b/src/resources/vue/App.vue
--- a/src/resources/vue/App.vue
+++ b/src/resources/vue/App.vue
@@ -29,23 +29,22 @@
const token = localStorage.getItem('token')
if (token) {
- this.$root.startLoading()
axios.defaults.headers.common.Authorization = 'Bearer ' + token
const post = { refresh_token: localStorage.getItem("refreshToken") }
- axios.post('/api/auth/info?refresh=1', post, { ignoreErrors: true })
+ axios.post('/api/auth/info?refresh=1', post, { ignoreErrors: true, loader: true })
.then(response => {
this.$root.loginUser(response.data, false)
- this.$root.stopLoading()
- this.isLoading = false
})
.catch(error => {
- // Release lock on the router-view, otherwise links (e.g. Logout) will not work
- this.isLoading = false
// Handle the error, on 401 display the logon page
this.$root.errorHandler(error)
})
+ .finally(() => {
+ // Release lock on the router-view, otherwise links (e.g. Logout) will not work
+ this.isLoading = false
+ })
} else {
this.isLoading = false
}
diff --git a/src/resources/vue/CompanionApp.vue b/src/resources/vue/CompanionApp.vue
--- a/src/resources/vue/CompanionApp.vue
+++ b/src/resources/vue/CompanionApp.vue
@@ -63,16 +63,11 @@
}
},
mounted() {
- this.$root.startLoading()
-
- axios.get('/api/v4/companion/pairing')
+ axios.get('/api/v4/companion/pairing', { loading: true })
.then(response => {
- this.$root.stopLoading()
this.qrcode = response.data.qrcode
})
.catch(this.$root.errorHandler)
- },
- methods: {
- },
+ }
}
diff --git a/src/resources/vue/Distlist/Info.vue b/src/resources/vue/Distlist/Info.vue
--- a/src/resources/vue/Distlist/Info.vue
+++ b/src/resources/vue/Distlist/Info.vue
@@ -93,11 +93,8 @@
this.list_id = this.$route.params.list
if (this.list_id != 'new') {
- this.$root.startLoading()
-
- axios.get('/api/v4/groups/' + this.list_id)
+ axios.get('/api/v4/groups/' + this.list_id, { loader: true })
.then(response => {
- this.$root.stopLoading()
this.list = response.data
this.status = response.data.statusInfo
})
diff --git a/src/resources/vue/Distlist/List.vue b/src/resources/vue/Distlist/List.vue
--- a/src/resources/vue/Distlist/List.vue
+++ b/src/resources/vue/Distlist/List.vue
@@ -54,11 +54,8 @@
}
},
created() {
- this.$root.startLoading()
-
- axios.get('/api/v4/groups')
+ axios.get('/api/v4/groups', { loader: true })
.then(response => {
- this.$root.stopLoading()
this.lists = response.data
})
.catch(this.$root.errorHandler)
diff --git a/src/resources/vue/Domain/Info.vue b/src/resources/vue/Domain/Info.vue
--- a/src/resources/vue/Domain/Info.vue
+++ b/src/resources/vue/Domain/Info.vue
@@ -145,11 +145,8 @@
this.domain_id = this.$route.params.domain
if (this.domain_id !== 'new') {
- this.$root.startLoading()
-
- axios.get('/api/v4/domains/' + this.domain_id)
+ axios.get('/api/v4/domains/' + this.domain_id, { loader: true })
.then(response => {
- this.$root.stopLoading()
this.domain = response.data
this.spf_whitelist = this.domain.config.spf_whitelist || []
diff --git a/src/resources/vue/Domain/List.vue b/src/resources/vue/Domain/List.vue
--- a/src/resources/vue/Domain/List.vue
+++ b/src/resources/vue/Domain/List.vue
@@ -49,11 +49,8 @@
}
},
created() {
- this.$root.startLoading()
-
- axios.get('/api/v4/domains')
+ axios.get('/api/v4/domains', { loader: true })
.then(response => {
- this.$root.stopLoading()
this.domains = response.data
})
.catch(this.$root.errorHandler)
diff --git a/src/resources/vue/File/Info.vue b/src/resources/vue/File/Info.vue
--- a/src/resources/vue/File/Info.vue
+++ b/src/resources/vue/File/Info.vue
@@ -102,11 +102,8 @@
this.fileId = this.$route.params.file
- this.$root.startLoading()
-
- axios.get('/api/v4/files/' + this.fileId)
+ axios.get('/api/v4/files/' + this.fileId, { loader: true })
.then(response => {
- this.$root.stopLoading()
this.file = response.data
if (this.file.isOwner) {
diff --git a/src/resources/vue/File/List.vue b/src/resources/vue/File/List.vue
--- a/src/resources/vue/File/List.vue
+++ b/src/resources/vue/File/List.vue
@@ -93,7 +93,7 @@
fileDownload(file) {
// This is not an appropriate method for big files, we can consider
// using it still for very small files.
- // this.$root.downloadFile('api/v4/files/' + file.id + '?download=1', file.name)
+ // downloadFile('api/v4/files/' + file.id + '?download=1', file.name)
// This method first makes a request to the API to get the download URL (which does not
// require authentication) and then use it to download the file.
diff --git a/src/resources/vue/Page.vue b/src/resources/vue/Page.vue
--- a/src/resources/vue/Page.vue
+++ b/src/resources/vue/Page.vue
@@ -18,11 +18,8 @@
return
}
- this.$root.startLoading()
-
- axios.get('/content/page/' + page, { ignoreErrors: true })
+ axios.get('/content/page/' + page, { ignoreErrors: true, loader: true })
.then(response => {
- this.$root.stopLoading()
this.content = response.data
})
.catch(this.$root.errorHandler)
diff --git a/src/resources/vue/PasswordReset.vue b/src/resources/vue/PasswordReset.vue
--- a/src/resources/vue/PasswordReset.vue
+++ b/src/resources/vue/PasswordReset.vue
@@ -122,19 +122,17 @@
let params = {}
if (bylink === true) {
- this.$root.startLoading()
params.ignoreErrors = true
+ params.loader = true
}
this.$root.clearFormValidation($('#step2 form'))
axios.post('/api/auth/password-reset/verify', post, params).then(response => {
- this.$root.stopLoading()
this.userId = response.data.userId
this.displayForm(3, true)
}).catch(error => {
if (bylink === true) {
- this.$root.stopLoading()
this.$root.errorPage(404, '', this.$t('password.link-invalid'))
}
})
diff --git a/src/resources/vue/Resource/Info.vue b/src/resources/vue/Resource/Info.vue
--- a/src/resources/vue/Resource/Info.vue
+++ b/src/resources/vue/Resource/Info.vue
@@ -101,11 +101,8 @@
this.resource_id = this.$route.params.resource
if (this.resource_id != 'new') {
- this.$root.startLoading()
-
- axios.get('/api/v4/resources/' + this.resource_id)
+ axios.get('/api/v4/resources/' + this.resource_id, { loader: true })
.then(response => {
- this.$root.stopLoading()
this.resource = response.data
this.status = response.data.statusInfo
@@ -117,11 +114,8 @@
})
.catch(this.$root.errorHandler)
} else {
- this.$root.startLoading()
-
- axios.get('/api/v4/domains')
+ axios.get('/api/v4/domains', { loader: true })
.then(response => {
- this.$root.stopLoading()
this.domains = response.data
this.resource.domain = this.domains[0].namespace
})
diff --git a/src/resources/vue/Resource/List.vue b/src/resources/vue/Resource/List.vue
--- a/src/resources/vue/Resource/List.vue
+++ b/src/resources/vue/Resource/List.vue
@@ -54,11 +54,8 @@
}
},
created() {
- this.$root.startLoading()
-
- axios.get('/api/v4/resources')
+ axios.get('/api/v4/resources', { loader: true })
.then(response => {
- this.$root.stopLoading()
this.resources = response.data
})
.catch(this.$root.errorHandler)
diff --git a/src/resources/vue/Rooms.vue b/src/resources/vue/Rooms.vue
--- a/src/resources/vue/Rooms.vue
+++ b/src/resources/vue/Rooms.vue
@@ -46,12 +46,8 @@
return
}
- this.$root.startLoading()
-
- axios.get('/api/v4/meet/rooms')
+ axios.get('/api/v4/meet/rooms', { loader: true })
.then(response => {
- this.$root.stopLoading()
-
this.rooms = response.data.list
if (response.data.count) {
this.roomRoute = '/meet/' + encodeURI(this.rooms[0].name)
diff --git a/src/resources/vue/Settings.vue b/src/resources/vue/Settings.vue
--- a/src/resources/vue/Settings.vue
+++ b/src/resources/vue/Settings.vue
@@ -61,12 +61,8 @@
this.wallet = this.$root.authInfo.wallet
},
mounted() {
- this.$root.startLoading()
-
- axios.get('/api/v4/password-policy')
+ axios.get('/api/v4/password-policy', { loader: true })
.then(response => {
- this.$root.stopLoading()
-
if (response.data.list) {
this.passwordPolicy = response.data.list
this.config = response.data.config
diff --git a/src/resources/vue/SharedFolder/Info.vue b/src/resources/vue/SharedFolder/Info.vue
--- a/src/resources/vue/SharedFolder/Info.vue
+++ b/src/resources/vue/SharedFolder/Info.vue
@@ -107,21 +107,15 @@
this.folder_id = this.$route.params.folder
if (this.folder_id != 'new') {
- this.$root.startLoading()
-
- axios.get('/api/v4/shared-folders/' + this.folder_id)
+ axios.get('/api/v4/shared-folders/' + this.folder_id, { loader: true })
.then(response => {
- this.$root.stopLoading()
this.folder = response.data
this.status = response.data.statusInfo
})
.catch(this.$root.errorHandler)
} else {
- this.$root.startLoading()
-
- axios.get('/api/v4/domains')
+ axios.get('/api/v4/domains', { loader: true })
.then(response => {
- this.$root.stopLoading()
this.domains = response.data
this.folder.domain = this.domains[0].namespace
})
diff --git a/src/resources/vue/SharedFolder/List.vue b/src/resources/vue/SharedFolder/List.vue
--- a/src/resources/vue/SharedFolder/List.vue
+++ b/src/resources/vue/SharedFolder/List.vue
@@ -53,11 +53,8 @@
}
},
created() {
- this.$root.startLoading()
-
- axios.get('/api/v4/shared-folders')
+ axios.get('/api/v4/shared-folders', { loader: true })
.then(response => {
- this.$root.stopLoading()
this.folders = response.data
})
.catch(this.$root.errorHandler)
diff --git a/src/resources/vue/Signup.vue b/src/resources/vue/Signup.vue
--- a/src/resources/vue/Signup.vue
+++ b/src/resources/vue/Signup.vue
@@ -138,8 +138,7 @@
let param = this.$route.params.param;
if (this.$route.name == 'signup-invite') {
- this.$root.startLoading()
- axios.get('/api/auth/signup/invitations/' + param)
+ axios.get('/api/auth/signup/invitations/' + param, { loader: true })
.then(response => {
this.invitation = response.data
this.login = response.data.login
@@ -149,7 +148,6 @@
this.plan = response.data.plan
this.is_domain = response.data.is_domain
this.setDomain(response.data)
- this.$root.stopLoading()
this.displayForm(3, true)
})
.catch(error => {
@@ -185,9 +183,7 @@
// Composes plan selection page
step0() {
if (!this.plans.length) {
- this.$root.startLoading()
- axios.get('/api/auth/signup/plans').then(response => {
- this.$root.stopLoading()
+ axios.get('/api/auth/signup/plans', { loader: true }).then(response => {
this.plans = response.data.plans
})
.catch(error => {
diff --git a/src/resources/vue/User/Info.vue b/src/resources/vue/User/Info.vue
--- a/src/resources/vue/User/Info.vue
+++ b/src/resources/vue/User/Info.vue
@@ -174,12 +174,8 @@
this.user_id = this.$route.params.user
if (this.user_id !== 'new') {
- this.$root.startLoading()
-
- axios.get('/api/v4/users/' + this.user_id)
+ axios.get('/api/v4/users/' + this.user_id, { loader: true })
.then(response => {
- this.$root.stopLoading()
-
this.user = response.data
this.user.first_name = response.data.settings.first_name
this.user.last_name = response.data.settings.last_name
@@ -241,16 +237,10 @@
// Note: we use $nextTick() because we have to wait for the HTML elements to exist
this.$nextTick().then(() => {
if (mode == 'link' && !this.passwordLinkCode) {
- const element = $('#password-link')
- this.$root.addLoader(element)
- axios.post('/api/v4/password-reset/code')
+ axios.post('/api/v4/password-reset/code', {}, { loader: '#password-link' })
.then(response => {
- this.$root.removeLoader(element)
this.passwordLinkCode = response.data.short_code + '-' + response.data.code
})
- .catch(error => {
- this.$root.removeLoader(element)
- })
} else if (mode == 'input') {
$('#password').focus();
}
diff --git a/src/resources/vue/Wallet.vue b/src/resources/vue/Wallet.vue
--- a/src/resources/vue/Wallet.vue
+++ b/src/resources/vue/Wallet.vue
@@ -188,6 +188,7 @@
import { Modal } from 'bootstrap'
import TransactionLog from './Widgets/TransactionLog'
import PaymentLog from './Widgets/PaymentLog'
+ import { downloadFile } from '../js/utils'
import { library } from '@fortawesome/fontawesome-svg-core'
@@ -225,23 +226,14 @@
this.walletId = this.$root.authInfo.wallets[0].id
- this.$root.startLoading()
- axios.get('/api/v4/wallets/' + this.walletId)
+ axios.get('/api/v4/wallets/' + this.walletId, { loader: true })
.then(response => {
- this.$root.stopLoading()
this.wallet = response.data
- const receiptsTab = $('#wallet-receipts')
-
- this.$root.addLoader(receiptsTab)
- axios.get('/api/v4/wallets/' + this.walletId + '/receipts')
+ axios.get('/api/v4/wallets/' + this.walletId + '/receipts', { loader: '#wallet-receipts' })
.then(response => {
- this.$root.removeLoader(receiptsTab)
this.receipts = response.data.list
})
- .catch(error => {
- this.$root.removeLoader(receiptsTab)
- })
if (this.wallet.provider == 'stripe') {
this.stripeInit()
@@ -269,20 +261,15 @@
},
methods: {
loadMandate() {
- const mandate_form = $('#mandate-form')
+ const loader = '#mandate-form'
- this.$root.removeLoader(mandate_form)
+ this.$root.stopLoading(loader)
if (!this.mandate.id || this.mandate.isPending) {
- this.$root.addLoader(mandate_form)
- axios.get('/api/v4/payments/mandate')
+ axios.get('/api/v4/payments/mandate', { loader })
.then(response => {
- this.$root.removeLoader(mandate_form)
this.mandate = response.data
})
- .catch(error => {
- this.$root.removeLoader(mandate_form)
- })
}
},
selectPaymentMethod(method) {
@@ -384,14 +371,11 @@
this.dialog.show()
this.$nextTick().then(() => {
- const form = $('#payment-method')
const type = nextForm == 'manual' ? 'oneoff' : 'recurring'
+ const loader = ['#payment-method', { 'min-height': '10em', small: false }]
- this.$root.addLoader(form, false, { 'min-height': '10em' })
-
- axios.get('/api/v4/payments/methods', { params: { type } })
+ axios.get('/api/v4/payments/methods', { params: { type }, loader })
.then(response => {
- this.$root.removeLoader(form)
this.paymentMethods = response.data
})
})
@@ -406,7 +390,7 @@
},
receiptDownload() {
const receipt = $('#receipt-id').val()
- this.$root.downloadFile('/api/v4/wallets/' + this.walletId + '/receipts/' + receipt)
+ downloadFile('/api/v4/wallets/' + this.walletId + '/receipts/' + receipt)
},
stripeInit() {
let script = $('#stripe-script')
diff --git a/src/resources/vue/Widgets/ListTools.vue b/src/resources/vue/Widgets/ListTools.vue
--- a/src/resources/vue/Widgets/ListTools.vue
+++ b/src/resources/vue/Widgets/ListTools.vue
@@ -76,26 +76,14 @@
if (!loader.length || get.page == 1) {
loader = $(this.$el).find('tfoot td')
}
+ } else {
+ loader = true
}
} else {
this.currentSearch = null
}
- if (params && params.init) {
- this.$root.startLoading()
- } else {
- this.$root.addLoader(loader)
- }
-
- const finish = () => {
- if (params && params.init) {
- this.$root.stopLoading()
- } else {
- this.$root.removeLoader(loader)
- }
- }
-
- axios.get(url, { params: get })
+ axios.get(url, { params: get, loader })
.then(response => {
// Note: In Vue we can't just use .concat()
for (let i in response.data.list) {
@@ -104,11 +92,6 @@
this.hasMore = response.data.hasMore
this.page = response.data.page || 1
-
- finish()
- })
- .catch(error => {
- finish()
})
}
}
diff --git a/src/resources/vue/Widgets/PackageSelect.vue b/src/resources/vue/Widgets/PackageSelect.vue
--- a/src/resources/vue/Widgets/PackageSelect.vue
+++ b/src/resources/vue/Widgets/PackageSelect.vue
@@ -58,12 +58,8 @@
// assign currency, discount, discount_description of the current user
this.$root.userWalletProps(this)
- this.$root.startLoading()
-
- axios.get('/api/v4/packages')
+ axios.get('/api/v4/packages', { loader: true })
.then(response => {
- this.$root.stopLoading()
-
this.packages = response.data.filter(pkg => {
if (this.type == 'domain') {
return pkg.isDomain
diff --git a/src/resources/vue/Widgets/SubscriptionSelect.vue b/src/resources/vue/Widgets/SubscriptionSelect.vue
--- a/src/resources/vue/Widgets/SubscriptionSelect.vue
+++ b/src/resources/vue/Widgets/SubscriptionSelect.vue
@@ -72,12 +72,8 @@
this.discount_description = this.object.wallet.discount_description
}
- this.$root.startLoading()
-
- axios.get('/api/v4/' + this.type + 's/' + this.object.id + '/skus')
+ axios.get('/api/v4/' + this.type + 's/' + this.object.id + '/skus', { loader: true })
.then(response => {
- this.$root.stopLoading()
-
if (this.readonly) {
response.data = response.data.filter(sku => { return sku.id in this.object.skus })
}
diff --git a/src/resources/vue/Widgets/TransactionLog.vue b/src/resources/vue/Widgets/TransactionLog.vue
--- a/src/resources/vue/Widgets/TransactionLog.vue
+++ b/src/resources/vue/Widgets/TransactionLog.vue
@@ -58,19 +58,14 @@
let cell = record.find('td.description')
let details = $('').appendTo(cell)
- this.$root.addLoader(cell)
- axios.get('/api/v4/wallets/' + this.walletId + '/transactions' + '?transaction=' + id)
+ axios.get('/api/v4/wallets/' + this.walletId + '/transactions' + '?transaction=' + id, { loader: cell })
.then(response => {
- this.$root.removeLoader(cell)
record.find('button').remove()
let list = details.find('ul')
response.data.list.forEach(elem => {
list.append($('
').text(this.description(elem)))
})
})
- .catch(error => {
- this.$root.removeLoader(cell)
- })
},
amount(transaction) {
return this.$root.price(transaction.amount, transaction.currency)