Changeset View
Changeset View
Standalone View
Standalone View
src/resources/js/app.js
/** | /** | ||||
* First we will load all of this project's JavaScript dependencies which | * First we will load all of this project's JavaScript dependencies which | ||||
* includes Vue and other libraries. It is a great starting point when | * includes Vue and other libraries. It is a great starting point when | ||||
* building robust, powerful web applications using Vue and Laravel. | * building robust, powerful web applications using Vue and Laravel. | ||||
*/ | */ | ||||
require('./bootstrap') | require('./bootstrap') | ||||
import AppComponent from '../vue/App' | import AppComponent from '../vue/App' | ||||
import MenuComponent from '../vue/Widgets/Menu' | import MenuComponent from '../vue/Widgets/Menu' | ||||
import SupportForm from '../vue/Widgets/SupportForm' | import SupportForm from '../vue/Widgets/SupportForm' | ||||
import store from './store' | import store from './store' | ||||
const loader = '<div class="app-loader"><div class="spinner-border" role="status"><span class="sr-only">Loading</span></div></div>' | const loader = '<div class="app-loader"><div class="spinner-border" role="status"><span class="sr-only">Loading</span></div></div>' | ||||
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 | |||||
// Note: You cannot use app inside of the function | |||||
window.router.beforeEach((to, from, next) => { | |||||
// check if the route requires authentication and user is not logged in | |||||
if (to.matched.some(route => route.meta.requiresAuth) && !store.state.isLoggedIn) { | |||||
// remember the original request, to use after login | |||||
store.state.afterLogin = to; | |||||
// redirect to login page | |||||
next({ name: 'login' }) | |||||
return | |||||
} | |||||
if (to.meta.loading) { | |||||
startLoading() | |||||
loadingRoute = to.name | |||||
} | |||||
next() | |||||
}) | |||||
window.router.afterEach((to, from) => { | |||||
if (to.name && loadingRoute === to.name) { | |||||
stopLoading() | |||||
loadingRoute = null | |||||
} | |||||
// When changing a page remove old: | |||||
// - error page | |||||
// - modal backdrop | |||||
$('#error-page,.modal-backdrop.show').remove() | |||||
}) | |||||
const app = new Vue({ | const app = new Vue({ | ||||
el: '#app', | el: '#app', | ||||
components: { | components: { | ||||
AppComponent, | AppComponent, | ||||
MenuComponent, | MenuComponent, | ||||
}, | }, | ||||
store, | store, | ||||
router: window.router, | router: window.router, | ||||
data() { | data() { | ||||
return { | return { | ||||
isLoading: true, | |||||
isAdmin: window.isAdmin | isAdmin: window.isAdmin | ||||
} | } | ||||
}, | }, | ||||
methods: { | methods: { | ||||
// Clear (bootstrap) form validation state | // Clear (bootstrap) form validation state | ||||
clearFormValidation(form) { | clearFormValidation(form) { | ||||
$(form).find('.is-invalid').removeClass('is-invalid') | $(form).find('.is-invalid').removeClass('is-invalid') | ||||
$(form).find('.invalid-feedback').remove() | $(form).find('.invalid-feedback').remove() | ||||
▲ Show 20 Lines • Show All 79 Lines • ▼ Show 20 Lines | methods: { | ||||
// Display "loading" overlay inside of the specified element | // Display "loading" overlay inside of the specified element | ||||
addLoader(elem) { | addLoader(elem) { | ||||
$(elem).css({position: 'relative'}).append($(loader).addClass('small')) | $(elem).css({position: 'relative'}).append($(loader).addClass('small')) | ||||
}, | }, | ||||
// Remove loader element added in addLoader() | // Remove loader element added in addLoader() | ||||
removeLoader(elem) { | removeLoader(elem) { | ||||
$(elem).find('.app-loader').remove() | $(elem).find('.app-loader').remove() | ||||
}, | }, | ||||
startLoading() { | startLoading, | ||||
this.isLoading = true | stopLoading, | ||||
// Lock the UI with the 'loading...' element | isLoading() { | ||||
let loading = $('#app > .app-loader').removeClass('fadeOut') | return isLoading > 0 | ||||
if (!loading.length) { | |||||
$('#app').append($(loader)) | |||||
} | |||||
}, | |||||
// Hide "loading" overlay | |||||
stopLoading() { | |||||
$('#app > .app-loader').addClass('fadeOut') | |||||
this.isLoading = false | |||||
}, | }, | ||||
errorPage(code, msg) { | errorPage(code, msg) { | ||||
// Until https://github.com/vuejs/vue-router/issues/977 is implemented | // Until https://github.com/vuejs/vue-router/issues/977 is implemented | ||||
// we can't really use router to display error page as it has two side | // we can't really use router to display error page as it has two side | ||||
// effects: it changes the URL and adds the error page to browser history. | // effects: it changes the URL and adds the error page to browser history. | ||||
// For now we'll be replacing current view with error page "manually". | // For now we'll be replacing current view with error page "manually". | ||||
const map = { | const map = { | ||||
400: "Bad request", | 400: "Bad request", | ||||
▲ Show 20 Lines • Show All 270 Lines • ▼ Show 20 Lines | error => { | ||||
} | } | ||||
app.$toast.error(error_msg || "Server Error") | app.$toast.error(error_msg || "Server Error") | ||||
// Pass the error as-is | // Pass the error as-is | ||||
return Promise.reject(error) | return Promise.reject(error) | ||||
} | } | ||||
) | ) | ||||
// TODO: Investigate if we can use App component's childMounted() method instead | |||||
window.router.afterEach((to, from) => { | |||||
// When changing a page remove old: | |||||
// - error page | |||||
// - modal backdrop | |||||
$('#error-page,.modal-backdrop.show').remove() | |||||
app.updateBodyClass() | |||||
}) |