first commit
This commit is contained in:
28
resources/frontend/core/helpers/common.js
Normal file
28
resources/frontend/core/helpers/common.js
Normal file
@@ -0,0 +1,28 @@
|
||||
export function getParentElement(child, search) {
|
||||
if (child.parentElement.classList.contains(search)) {
|
||||
return child.parentElement;
|
||||
}
|
||||
|
||||
return getParentElement(child.parentElement, search);
|
||||
}
|
||||
|
||||
export function loadSections(context, router, requireSection) {
|
||||
const sections = requireSection
|
||||
.keys()
|
||||
.map(fn => requireSection(fn).default)
|
||||
.map(section => {
|
||||
if (typeof section === 'function') {
|
||||
return section(context, router);
|
||||
}
|
||||
|
||||
return section;
|
||||
});
|
||||
|
||||
sections.forEach(section => {
|
||||
if (Object.prototype.hasOwnProperty.call(section, 'scope') && section.scope === 'company') {
|
||||
context.addCompanySection(section);
|
||||
} else {
|
||||
context.addSettingsSection(section);
|
||||
}
|
||||
});
|
||||
}
|
||||
117
resources/frontend/core/helpers/httpInterceptor.js
Normal file
117
resources/frontend/core/helpers/httpInterceptor.js
Normal file
@@ -0,0 +1,117 @@
|
||||
import Vue from 'vue';
|
||||
import axios from 'axios';
|
||||
import { store } from '@/store';
|
||||
import has from 'lodash/has';
|
||||
import isObject from 'lodash/isObject';
|
||||
|
||||
// Queue for pending queries
|
||||
let pendingRequests = 0;
|
||||
|
||||
// Changes loader bar state
|
||||
const setLoading = value => {
|
||||
if (value) {
|
||||
if (pendingRequests === 0) Vue.prototype.$Loading.start();
|
||||
pendingRequests++;
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
if (pendingRequests > 0) pendingRequests--;
|
||||
if (pendingRequests < 1) Vue.prototype.$Loading.finish();
|
||||
}, 300);
|
||||
}
|
||||
};
|
||||
|
||||
// Returns access token
|
||||
const getAuthToken = () => localStorage.getItem('access_token');
|
||||
|
||||
// Adds response interceptor
|
||||
const responseInterceptor = response => {
|
||||
setLoading(false);
|
||||
return response;
|
||||
};
|
||||
|
||||
// Adds error response interceptor
|
||||
const responseErrorInterceptor = async error => {
|
||||
setLoading(false);
|
||||
|
||||
if (!has(error, 'response.status') || (error.request.responseType === 'blob' && error.request.status === 404)) {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
switch (error.response.status) {
|
||||
case 401:
|
||||
store.getters['user/loggedIn'] && store.dispatch('user/forceUserExit', error.response.data.message);
|
||||
break;
|
||||
|
||||
case 503:
|
||||
store.getters['user/loggedIn'] && store.dispatch('user/forceUserExit', 'Data reset');
|
||||
break;
|
||||
|
||||
default:
|
||||
Vue.prototype.$Notify.error({
|
||||
title: 'Error',
|
||||
message: has(error, 'response.data.error.message')
|
||||
? error.response.data.error.message
|
||||
: 'Internal server error',
|
||||
duration: 5000,
|
||||
});
|
||||
if (isObject(error.response.data.error.fields)) {
|
||||
for (const [fieldName, msgArr] of Object.entries(error.response.data.error.fields)) {
|
||||
for (const msg of msgArr) {
|
||||
await Vue.prototype.$nextTick();
|
||||
Vue.prototype.$Notify.warning({
|
||||
title: 'Warning',
|
||||
message: msg,
|
||||
duration: 5000,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
};
|
||||
|
||||
// Adds request interceptor
|
||||
const requestInterceptor = config => {
|
||||
setLoading(true);
|
||||
return config;
|
||||
};
|
||||
|
||||
// Adds request error interceptor
|
||||
const requestErrorInterceptor = error => {
|
||||
axios.isCancel(error) ? setLoading(false) : Vue.prototype.$Loading.error();
|
||||
return Promise.reject(error);
|
||||
};
|
||||
|
||||
// Sets the access token on the request
|
||||
const authInterceptor = config => {
|
||||
config.headers['Authorization'] = `Bearer ${getAuthToken()}`;
|
||||
return config;
|
||||
};
|
||||
|
||||
// Save pending request cancel tokens to the store
|
||||
const pendingRequestsInterceptor = config => {
|
||||
if (config.ignoreCancel) {
|
||||
return config;
|
||||
}
|
||||
|
||||
// Generate cancel token source
|
||||
let source = axios.CancelToken.source();
|
||||
|
||||
// Set cancel token on this request
|
||||
config.cancelToken = source.token;
|
||||
|
||||
store.commit('httpRequest/addCancelToken', source);
|
||||
|
||||
return config;
|
||||
};
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
axios.interceptors.response.use(responseInterceptor, responseErrorInterceptor);
|
||||
axios.interceptors.request.use(requestInterceptor, requestErrorInterceptor);
|
||||
|
||||
axios.interceptors.request.use(pendingRequestsInterceptor);
|
||||
axios.interceptors.request.use(authInterceptor);
|
||||
},
|
||||
};
|
||||
9
resources/frontend/core/helpers/sloganGenerator.js
Normal file
9
resources/frontend/core/helpers/sloganGenerator.js
Normal file
@@ -0,0 +1,9 @@
|
||||
const slogans = ['Cattr - a free open source time tracker', 'Manage your time with ease'];
|
||||
|
||||
const getRandomInt = max => {
|
||||
return Math.floor(Math.random() * Math.floor(max));
|
||||
};
|
||||
|
||||
export default () => {
|
||||
return slogans[getRandomInt(slogans.length)];
|
||||
};
|
||||
Reference in New Issue
Block a user