diff --git a/src/resources/js/app.js b/src/resources/js/app.js index e1c2fc2a..b3257455 100644 --- a/src/resources/js/app.js +++ b/src/resources/js/app.js @@ -1,199 +1,199 @@ /** * First we will load all of this project's JavaScript dependencies which * includes Vue and other libraries. It is a great starting point when * building robust, powerful web applications using Vue and Laravel. */ require('./bootstrap') window.Vue = require('vue') -import AppComponent from '../vue/components/App' -import MenuComponent from '../vue/components/Menu' -import router from '../vue/js/routes.js' -import store from '../vue/js/store' -import FontAwesomeIcon from './fontawesome.js' +import AppComponent from '../vue/App' +import MenuComponent from '../vue/Menu' +import router from './routes' +import store from './store' +import FontAwesomeIcon from './fontawesome' import VueToastr from '@deveodk/vue-toastr' Vue.component('svg-icon', FontAwesomeIcon) Vue.use(VueToastr, { defaultPosition: 'toast-bottom-right', defaultTimeout: 5000 }) // Add a response interceptor for general/validation error handler // This have to be before Vue and Router setup. Otherwise we would // not be able to handle axios responses initiated from inside // components created/mounted handlers (e.g. signup code verification link) window.axios.interceptors.response.use( response => { // Do nothing return response }, error => { var error_msg if (error.response && error.response.status == 422) { error_msg = "Form validation error" $.each(error.response.data.errors || {}, (idx, msg) => { $('form').each((i, form) => { const input_name = ($(form).data('validation-prefix') || '') + idx const input = $('#' + input_name) if (input.length) { // Create an error message\ // API responses can use a string, array or object let msg_text = '' if ($.type(msg) !== 'string') { $.each(msg, (index, str) => { msg_text += str + ' ' }) } else { msg_text = msg } let feedback = $('
').text(msg_text) if (input.is('.listinput')) { // List input widget let list = input.next('.listinput-widget') list.children(':not(:first-child)').each((index, element) => { if (msg[index]) { $(element).find('input').addClass('is-invalid') } }) list.addClass('is-invalid').next('.invalid-feedback').remove() list.after(feedback) } else { // Standard form element input.addClass('is-invalid') input.parent().find('.invalid-feedback').remove() input.parent().append(feedback) } return false } }); }) $('form .is-invalid:not(.listinput-widget)').first().focus() } else if (error.response && error.response.data) { error_msg = error.response.data.message } else { error_msg = error.request ? error.request.statusText : error.message } app.$toastr('error', error_msg || "Server Error", 'Error') // Pass the error as-is return Promise.reject(error) } ) const app = new Vue({ el: '#app', components: { 'app-component': AppComponent, 'menu-component': MenuComponent }, store, router, data() { return { isLoading: true } }, methods: { // Clear (bootstrap) form validation state clearFormValidation(form) { $(form).find('.is-invalid').removeClass('is-invalid') $(form).find('.invalid-feedback').remove() }, isController(wallet_id) { if (wallet_id && store.state.authInfo) { let i for (i = 0; i < store.state.authInfo.wallets.length; i++) { if (wallet_id == store.state.authInfo.wallets[i].id) { return true } } for (i = 0; i < store.state.authInfo.accounts.length; i++) { if (wallet_id == store.state.authInfo.accounts[i].id) { return true } } } return false }, // Set user state to "logged in" loginUser(token, dashboard) { store.commit('logoutUser') // destroy old state data store.commit('loginUser') localStorage.setItem('token', token) axios.defaults.headers.common.Authorization = 'Bearer ' + token if (dashboard !== false) { router.push(store.state.afterLogin || { name: 'dashboard' }) } store.state.afterLogin = null }, // Set user state to "not logged in" logoutUser() { store.commit('logoutUser') localStorage.setItem('token', '') delete axios.defaults.headers.common.Authorization router.push({ name: 'login' }) }, // Display "loading" overlay (to be used by route components) startLoading() { this.isLoading = true // Lock the UI with the 'loading...' element $('#app').append($('
Loading
')) }, // Hide "loading" overlay stopLoading() { $('#app > .app-loader').fadeOut() this.isLoading = false }, errorPage(code, msg) { // 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 // 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". const map = { 400: "Bad request", 401: "Unauthorized", 403: "Access denied", 404: "Not found", 405: "Method not allowed", 500: "Internal server error" } if (!msg) msg = map[code] || "Unknown Error" const error_page = `
${code}
${msg}
` $('#app').children(':not(nav)').remove() $('#app').append(error_page) }, errorHandler(error) { this.stopLoading() if (error.response.status === 401) { this.logoutUser() } else { this.errorPage(error.response.status, error.response.statusText) } } } }) diff --git a/src/resources/vue/js/routes.js b/src/resources/js/routes.js similarity index 76% rename from src/resources/vue/js/routes.js rename to src/resources/js/routes.js index 7a4ebd54..9809be8d 100644 --- a/src/resources/vue/js/routes.js +++ b/src/resources/js/routes.js @@ -1,115 +1,115 @@ import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) -import DashboardComponent from '../components/Dashboard' -import DomainInfoComponent from '../components/Domain/Info' -import DomainListComponent from '../components/Domain/List' -import Error404Component from '../components/404' -import LoginComponent from '../components/Login' -import LogoutComponent from '../components/Logout' -import PasswordResetComponent from '../components/PasswordReset' -import SignupComponent from '../components/Signup' -import UserInfoComponent from '../components/User/Info' -import UserListComponent from '../components/User/List' -import UserProfileComponent from '../components/User/Profile' -import UserProfileDeleteComponent from '../components/User/ProfileDelete' +import DashboardComponent from '../vue/Dashboard' +import DomainInfoComponent from '../vue/Domain/Info' +import DomainListComponent from '../vue/Domain/List' +import Error404Component from '../vue/404' +import LoginComponent from '../vue/Login' +import LogoutComponent from '../vue/Logout' +import PasswordResetComponent from '../vue/PasswordReset' +import SignupComponent from '../vue/Signup' +import UserInfoComponent from '../vue/User/Info' +import UserListComponent from '../vue/User/List' +import UserProfileComponent from '../vue/User/Profile' +import UserProfileDeleteComponent from '../vue/User/ProfileDelete' import store from './store' const routes = [ { path: '/', redirect: { name: 'dashboard' } }, { path: '/dashboard', name: 'dashboard', component: DashboardComponent, meta: { requiresAuth: true } }, { path: '/domain/:domain', name: 'domain', component: DomainInfoComponent, meta: { requiresAuth: true } }, { path: '/domains', name: 'domains', component: DomainListComponent, meta: { requiresAuth: true } }, { path: '/login', name: 'login', component: LoginComponent }, { path: '/logout', name: 'logout', component: LogoutComponent }, { path: '/password-reset/:code?', name: 'password-reset', component: PasswordResetComponent }, { path: '/profile', name: 'profile', component: UserProfileComponent, meta: { requiresAuth: true } }, { path: '/profile/delete', name: 'profile-delete', component: UserProfileDeleteComponent, meta: { requiresAuth: true } }, { path: '/signup/:param?', name: 'signup', component: SignupComponent }, { path: '/user/:user', name: 'user', component: UserInfoComponent, meta: { requiresAuth: true } }, { path: '/users', name: 'users', component: UserListComponent, meta: { requiresAuth: true } }, { name: '404', path: '*', component: Error404Component } ] const router = new VueRouter({ mode: 'history', routes }) 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 } next() }) export default router diff --git a/src/resources/vue/js/store.js b/src/resources/js/store.js similarity index 100% rename from src/resources/vue/js/store.js rename to src/resources/js/store.js diff --git a/src/resources/vue/components/404.vue b/src/resources/vue/404.vue similarity index 100% rename from src/resources/vue/components/404.vue rename to src/resources/vue/404.vue diff --git a/src/resources/vue/components/App.vue b/src/resources/vue/App.vue similarity index 100% rename from src/resources/vue/components/App.vue rename to src/resources/vue/App.vue diff --git a/src/resources/vue/components/Dashboard.vue b/src/resources/vue/Dashboard.vue similarity index 100% rename from src/resources/vue/components/Dashboard.vue rename to src/resources/vue/Dashboard.vue diff --git a/src/resources/vue/components/Domain/Info.vue b/src/resources/vue/Domain/Info.vue similarity index 100% rename from src/resources/vue/components/Domain/Info.vue rename to src/resources/vue/Domain/Info.vue diff --git a/src/resources/vue/components/Domain/List.vue b/src/resources/vue/Domain/List.vue similarity index 100% rename from src/resources/vue/components/Domain/List.vue rename to src/resources/vue/Domain/List.vue diff --git a/src/resources/vue/components/Login.vue b/src/resources/vue/Login.vue similarity index 100% rename from src/resources/vue/components/Login.vue rename to src/resources/vue/Login.vue diff --git a/src/resources/vue/components/Logout.vue b/src/resources/vue/Logout.vue similarity index 100% rename from src/resources/vue/components/Logout.vue rename to src/resources/vue/Logout.vue diff --git a/src/resources/vue/components/Menu.vue b/src/resources/vue/Menu.vue similarity index 100% rename from src/resources/vue/components/Menu.vue rename to src/resources/vue/Menu.vue diff --git a/src/resources/vue/components/PasswordReset.vue b/src/resources/vue/PasswordReset.vue similarity index 100% rename from src/resources/vue/components/PasswordReset.vue rename to src/resources/vue/PasswordReset.vue diff --git a/src/resources/vue/components/Signup.vue b/src/resources/vue/Signup.vue similarity index 100% rename from src/resources/vue/components/Signup.vue rename to src/resources/vue/Signup.vue diff --git a/src/resources/vue/components/User/Info.vue b/src/resources/vue/User/Info.vue similarity index 100% rename from src/resources/vue/components/User/Info.vue rename to src/resources/vue/User/Info.vue diff --git a/src/resources/vue/components/User/List.vue b/src/resources/vue/User/List.vue similarity index 100% rename from src/resources/vue/components/User/List.vue rename to src/resources/vue/User/List.vue diff --git a/src/resources/vue/components/User/Profile.vue b/src/resources/vue/User/Profile.vue similarity index 100% rename from src/resources/vue/components/User/Profile.vue rename to src/resources/vue/User/Profile.vue diff --git a/src/resources/vue/components/User/ProfileDelete.vue b/src/resources/vue/User/ProfileDelete.vue similarity index 100% rename from src/resources/vue/components/User/ProfileDelete.vue rename to src/resources/vue/User/ProfileDelete.vue