stash
This commit is contained in:
parent
30cddebdc8
commit
4645a2f48c
5 changed files with 172 additions and 114 deletions
|
@ -36,7 +36,7 @@ export default {
|
|||
}),
|
||||
methods: {
|
||||
...mapMutations(['removeToast', 'createToast', 'closeAddBoxModal', 'openAddBoxModal']),
|
||||
...mapActions(['loadEvents', 'afterLogin']),
|
||||
...mapActions(['loadEvents']),
|
||||
openAddItemModal() {
|
||||
this.addItemModalOpen = true;
|
||||
},
|
||||
|
@ -53,9 +53,9 @@ export default {
|
|||
created: function () {
|
||||
document.title = document.location.hostname;
|
||||
this.loadEvents().then(() => {
|
||||
if (this.isLoggedIn) {
|
||||
/*if (this.isLoggedIn) {
|
||||
this.afterLogin();
|
||||
}
|
||||
}*/
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -165,6 +165,14 @@ export default (config) => {
|
|||
if (config.debug) console.log('worker started');
|
||||
|
||||
const updateWorkerState = (key, new_value, old_value = null) => {
|
||||
if(new_value === old_value) {
|
||||
if (config.debug) console.log('updateWorkerState: no change', key, new_value);
|
||||
return;
|
||||
}
|
||||
if (new_value === undefined) {
|
||||
if (config.debug) console.log('updateWorkerState: undefined', key, new_value);
|
||||
return;
|
||||
}
|
||||
worker.port.postMessage({
|
||||
type: 'state_diff',
|
||||
key: key,
|
||||
|
|
198
web/src/store.js
198
web/src/store.js
|
@ -1,60 +1,12 @@
|
|||
import {createStore} from 'vuex';
|
||||
import AxiosBootstrap from 'axios';
|
||||
import router from './router';
|
||||
|
||||
import * as base64 from 'base-64';
|
||||
import * as utf8 from 'utf8';
|
||||
import {ticketStateColorLookup, ticketStateIconLookup} from "@/utils";
|
||||
import {ticketStateColorLookup, ticketStateIconLookup, http} from "@/utils";
|
||||
import sharedStatePlugin from "@/shared-state-plugin";
|
||||
import persistentStatePlugin from "@/persistent-state-plugin";
|
||||
|
||||
const axios = AxiosBootstrap.create({
|
||||
baseURL: '/api',
|
||||
});
|
||||
axios.interceptors.response.use(response => response, error => {
|
||||
if (error.response.status === 401) {
|
||||
console.log('401 interceptor fired');
|
||||
store.dispatch('reloadToken').then((ok) => {
|
||||
if (ok) {
|
||||
error.config.headers['Authorization'] = `Token ${store.state.token}`;
|
||||
return axios.request(error.config);
|
||||
}
|
||||
});
|
||||
} else if (error.response.status === 403) {
|
||||
const message = `
|
||||
<h3>Access denied.</h3>
|
||||
<p>
|
||||
url: ${error.config.url}
|
||||
<br>
|
||||
method: ${error.config.method}
|
||||
<br>
|
||||
response-body: ${error.response && error.response.body}
|
||||
</p>
|
||||
`;
|
||||
store.commit('createToast', {title: 'Error: Access denied', message, color: 'danger'});
|
||||
return Promise.reject(error)
|
||||
} else {
|
||||
console.error('error interceptor fired', error.message);
|
||||
|
||||
if (error.isAxiosError) {
|
||||
const message = `
|
||||
<h3>A HTTP ${error.config.method} request failed.</h3>
|
||||
<p>
|
||||
url: ${error.config.url}
|
||||
<br>
|
||||
timeout: ${!!error.request.timeout}
|
||||
<br>
|
||||
response-body: ${error.response && error.response.body}
|
||||
</p>
|
||||
`;
|
||||
store.commit('createToast', {title: 'Error: HTTP', message, color: 'danger'});
|
||||
} else {
|
||||
store.commit('createToast', {title: 'Error: Unknown', message: error.toString(), color: 'danger'});
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
});
|
||||
|
||||
const store = createStore({
|
||||
state: {
|
||||
keyIncrement: 0,
|
||||
|
@ -213,8 +165,6 @@ const store = createStore({
|
|||
user.expiry = null;
|
||||
user.permissions = null;
|
||||
state.user = user;
|
||||
if (state.route.name !== 'login')
|
||||
router.push('/login');
|
||||
},
|
||||
setTest(state, test) {
|
||||
state.test = test;
|
||||
|
@ -231,8 +181,7 @@ const store = createStore({
|
|||
credentials: 'omit'
|
||||
}).then(r => r.json())
|
||||
if (data && data.token) {
|
||||
axios.defaults.headers.common['Authorization'] = `Token ${data.token}`;
|
||||
const {data: {permissions}} = await axios.get('/2/self/');
|
||||
const {data: {permissions}} = await http.get('/2/self/', data.token);
|
||||
commit('setUserInfo', {...data, permissions, username, password});
|
||||
return true;
|
||||
} else {
|
||||
|
@ -254,7 +203,6 @@ const store = createStore({
|
|||
}).then(r => r.json()).catch(e => console.error(e))
|
||||
if (data && data.token) {
|
||||
commit('setToken', data);
|
||||
axios.defaults.headers.common['Authorization'] = `Token ${data.token}`;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -265,32 +213,31 @@ const store = createStore({
|
|||
store.commit('logout');
|
||||
},
|
||||
//async verifyToken({commit, state}) {
|
||||
async afterLogin({dispatch, state}) {
|
||||
axios.defaults.headers.common['Authorization'] = `Token ${state.user.token}`;
|
||||
/*const boxes = dispatch('loadBoxes');
|
||||
const states = dispatch('fetchTicketStates');
|
||||
const items = dispatch('loadEventItems');
|
||||
const tickets = dispatch('loadTickets');
|
||||
const user = dispatch('loadUserInfo');
|
||||
await Promise.all([boxes, items, tickets, user, states]);*/
|
||||
/*async afterLogin({dispatch, state}) {
|
||||
//const boxes = dispatch('loadBoxes');
|
||||
//const states = dispatch('fetchTicketStates');
|
||||
//const items = dispatch('loadEventItems');
|
||||
//const tickets = dispatch('loadTickets');
|
||||
//const user = dispatch('loadUserInfo');
|
||||
//await Promise.all([boxes, items, tickets, user, states]);
|
||||
if (!state.user.permissions) {
|
||||
const user = dispatch('loadUserInfo');
|
||||
await Promise.all([user]);
|
||||
}
|
||||
},
|
||||
},*/
|
||||
async fetchImage({state}, url) {
|
||||
return await fetch(url, {headers: {'Authorization': `Token ${state.user.token}`}});
|
||||
},
|
||||
async loadUserInfo({commit}) {
|
||||
const {data} = await axios.get('/2/self/');
|
||||
async loadUserInfo({commit, state}) {
|
||||
const {data} = await http.get('/2/self/', state.user.token);
|
||||
commit('setPermissions', data.permissions);
|
||||
},
|
||||
async loadEvents({commit}) {
|
||||
const {data} = await axios.get('/2/events/');
|
||||
async loadEvents({commit, state}) {
|
||||
const {data} = await http.get('/2/events/', state.user.token);
|
||||
commit('replaceEvents', data);
|
||||
},
|
||||
async fetchTicketStates({commit}) {
|
||||
const {data} = await axios.get('/2/tickets/states/');
|
||||
async fetchTicketStates({commit, state}) {
|
||||
const {data} = await http.get('/2/tickets/states/', state.user.token);
|
||||
commit('replaceTicketStates', data);
|
||||
},
|
||||
changeEvent({dispatch, getters, commit}, eventName) {
|
||||
|
@ -310,94 +257,94 @@ const store = createStore({
|
|||
if (slug in state.itemCache) {
|
||||
commit('replaceLoadedItems', state.itemCache[slug]);
|
||||
}
|
||||
const {data} = await axios.get(`/2/${slug}/items/`);
|
||||
const {data} = await http.get(`/2/${slug}/items/`, state.user.token);
|
||||
commit('replaceLoadedItems', data);
|
||||
commit('setItemCache', {slug, items: data});
|
||||
} catch (e) {
|
||||
console.error("Error loading items");
|
||||
}
|
||||
},
|
||||
async searchEventItems({commit, getters}, query) {
|
||||
async searchEventItems({commit, getters, state}, query) {
|
||||
const foo = utf8.encode(query);
|
||||
const bar = base64.encode(foo);
|
||||
|
||||
const {data} = await axios.get(`/2/${getters.getEventSlug}/items/${bar}/`);
|
||||
const {data} = await http.get(`/2/${getters.getEventSlug}/items/${bar}/`, state.user.token);
|
||||
commit('replaceLoadedItems', data);
|
||||
},
|
||||
async loadBoxes({commit}) {
|
||||
const {data} = await axios.get('/2/boxes/');
|
||||
async loadBoxes({commit, state}) {
|
||||
const {data} = await http.get('/2/boxes/', state.user.token);
|
||||
commit('replaceBoxes', data);
|
||||
},
|
||||
async createBox({commit, dispatch}, box) {
|
||||
const {data} = await axios.post('/2/boxes/', box);
|
||||
async createBox({commit, dispatch, state}, box) {
|
||||
const {data} = await http.post('/2/boxes/', box, state.user.token);
|
||||
commit('replaceBoxes', data);
|
||||
dispatch('loadBoxes').then(() => {
|
||||
commit('closeAddBoxModal');
|
||||
});
|
||||
},
|
||||
async deleteBox({commit, dispatch}, box_id) {
|
||||
await axios.delete(`/2/boxes/${box_id}/`);
|
||||
async deleteBox({commit, dispatch, state}, box_id) {
|
||||
await http.delete(`/2/boxes/${box_id}/`, state.user.token);
|
||||
dispatch('loadBoxes');
|
||||
},
|
||||
async updateItem({commit, getters}, item) {
|
||||
const {data} = await axios.put(`/2/${getters.getEventSlug}/item/${item.uid}/`, item);
|
||||
async updateItem({commit, getters, state}, item) {
|
||||
const {data} = await http.put(`/2/${getters.getEventSlug}/item/${item.uid}/`, item, state.user.token);
|
||||
commit('updateItem', data);
|
||||
},
|
||||
async markItemReturned({commit, getters}, item) {
|
||||
await axios.patch(`/2/${getters.getEventSlug}/item/${item.uid}/`, {returned: true});
|
||||
async markItemReturned({commit, getters, state}, item) {
|
||||
await http.patch(`/2/${getters.getEventSlug}/item/${item.uid}/`, {returned: true}, state.user.token);
|
||||
commit('removeItem', item);
|
||||
},
|
||||
async deleteItem({commit, getters}, item) {
|
||||
await axios.delete(`/2/${getters.getEventSlug}/item/${item.uid}/`, item);
|
||||
async deleteItem({commit, getters, state}, item) {
|
||||
await http.delete(`/2/${getters.getEventSlug}/item/${item.uid}/`, item, state.user.token);
|
||||
commit('removeItem', item);
|
||||
},
|
||||
async postItem({commit, getters}, item) {
|
||||
async postItem({commit, getters, state}, item) {
|
||||
commit('updateLastUsed', {box: item.box, cid: item.cid});
|
||||
const {data} = await axios.post(`/2/${getters.getEventSlug}/item/`, item);
|
||||
const {data} = await http.post(`/2/${getters.getEventSlug}/item/`, item, state.user.token);
|
||||
commit('appendItem', data);
|
||||
},
|
||||
async loadTickets({commit}) {
|
||||
const {data} = await axios.get('/2/tickets/');
|
||||
async loadTickets({commit, state}) {
|
||||
const {data} = await http.get('/2/tickets/', state.user.token);
|
||||
commit('replaceTickets', data);
|
||||
},
|
||||
async sendMail({commit, dispatch}, {id, message}) {
|
||||
const {data} = await axios.post(`/2/tickets/${id}/reply/`, {message});
|
||||
async sendMail({commit, dispatch, state}, {id, message}) {
|
||||
const {data} = await http.post(`/2/tickets/${id}/reply/`, {message}, state.user.token);
|
||||
await dispatch('loadTickets');
|
||||
},
|
||||
async postManualTicket({commit, dispatch}, {sender, message, title,}) {
|
||||
const {data} = await axios.post(`/2/tickets/manual/`, {
|
||||
async postManualTicket({commit, dispatch, state}, {sender, message, title,}) {
|
||||
const {data} = await http.post(`/2/tickets/manual/`, {
|
||||
name: title,
|
||||
sender,
|
||||
body: message,
|
||||
recipient: 'mail@c3lf.de'
|
||||
});
|
||||
}, state.user.token);
|
||||
await dispatch('loadTickets');
|
||||
},
|
||||
async postComment({commit, dispatch}, {id, message}) {
|
||||
const {data} = await axios.post(`/2/tickets/${id}/comment/`, {comment: message});
|
||||
async postComment({commit, dispatch, staee}, {id, message}) {
|
||||
const {data} = await http.post(`/2/tickets/${id}/comment/`, {comment: message}, state.user.token);
|
||||
await dispatch('loadTickets');
|
||||
},
|
||||
async loadUsers({commit}) {
|
||||
const {data} = await axios.get('/2/users/');
|
||||
async loadUsers({commit, state}) {
|
||||
const {data} = await http.get('/2/users/', state.user.token);
|
||||
commit('replaceUsers', data);
|
||||
},
|
||||
async loadGroups({commit}) {
|
||||
const {data} = await axios.get('/2/groups/');
|
||||
async loadGroups({commit, state}) {
|
||||
const {data} = await http.get('/2/groups/', state.user.token);
|
||||
commit('replaceGroups', data);
|
||||
},
|
||||
async updateTicket({commit}, ticket) {
|
||||
const {data} = await axios.put(`/2/tickets/${ticket.id}/`, ticket);
|
||||
async updateTicket({commit, state}, ticket) {
|
||||
const {data} = await http.put(`/2/tickets/${ticket.id}/`, ticket, state.user.token);
|
||||
commit('updateTicket', data);
|
||||
},
|
||||
async updateTicketPartial({commit}, {id, ...ticket}) {
|
||||
const {data} = await axios.patch(`/2/tickets/${id}/`, ticket);
|
||||
async updateTicketPartial({commit, state}, {id, ...ticket}) {
|
||||
const {data} = await http.patch(`/2/tickets/${id}/`, ticket, state.user.token);
|
||||
commit('updateTicket', data);
|
||||
}
|
||||
},
|
||||
plugins: [
|
||||
persistentStatePlugin({ // TODO change remember to some kind of enable field
|
||||
prefix: "lf_",
|
||||
debug: false,
|
||||
debug: true,
|
||||
isLoadedKey: "persistent_loaded",
|
||||
state: [
|
||||
"remember",
|
||||
|
@ -405,24 +352,57 @@ const store = createStore({
|
|||
]
|
||||
}),
|
||||
sharedStatePlugin({
|
||||
debug: false,
|
||||
debug: true,
|
||||
isLoadedKey: "shared_loaded",
|
||||
clearingMutation: "logout",
|
||||
state: [
|
||||
"test",
|
||||
"state_options",
|
||||
"events",
|
||||
"fetchData",
|
||||
"tickets",
|
||||
],
|
||||
watch: [
|
||||
"test",
|
||||
"state_options",
|
||||
"events",
|
||||
"fetchData",
|
||||
],
|
||||
watch: [
|
||||
"test",
|
||||
],
|
||||
mutations: [
|
||||
"replaceTickets",
|
||||
//"replaceTickets",
|
||||
],
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
// watch: {
|
||||
// user: function (user) {
|
||||
// console.log('user changed', user);
|
||||
// if (user.token) {
|
||||
// }
|
||||
// //if(token && this.state.route.name === 'login') {
|
||||
// //if (state.route.name !== 'login')
|
||||
// // router.push('/login');
|
||||
// //if (state.route.name === 'login' && state.route.query.redirect)
|
||||
// // router.push(state.route.query.redirect);
|
||||
// },
|
||||
// },
|
||||
|
||||
store.watch((state) => state.user, (user) => {
|
||||
console.log('user changed', user);
|
||||
if (store.getters.isLoggedIn) {
|
||||
if (store.state.route.name === 'login' && store.state.route.query.redirect)
|
||||
router.push(store.state.route.query.redirect);
|
||||
else if (store.state.route.name === 'login')
|
||||
router.push('/');
|
||||
} else {
|
||||
if (store.state.route.name !== 'login') {
|
||||
router.push({
|
||||
name: 'login',
|
||||
query: {redirect: store.state.route.fullPath},
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default store;
|
||||
|
|
|
@ -24,4 +24,74 @@ function ticketStateIconLookup(ticket) {
|
|||
return 'exclamation';
|
||||
}
|
||||
|
||||
export {ticketStateColorLookup, ticketStateIconLookup};
|
||||
const http = {
|
||||
post: async (url, data, token) => {
|
||||
if (!token) {
|
||||
return null;
|
||||
}
|
||||
const response = await fetch('/api' + url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Token ${data.token}`,
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
return {data: await response.json()};
|
||||
}, get: async (url, token) => {
|
||||
if (!token) {
|
||||
return null;
|
||||
}
|
||||
const response = await fetch('/api' + url, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Token ${token}`,
|
||||
},
|
||||
});
|
||||
return {data: await response.json()};
|
||||
},
|
||||
put: async (url, data, token) => {
|
||||
if (!token) {
|
||||
return null;
|
||||
}
|
||||
const response = await fetch('/api' + url, {
|
||||
method: 'PUT',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Token ${data.token}`,
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
return {data: await response.json()};
|
||||
},
|
||||
patch: async (url, data, token) => {
|
||||
if (!token) {
|
||||
return null;
|
||||
}
|
||||
const response = await fetch('/api' + url, {
|
||||
method: 'PATCH',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Token ${data.token}`,
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
return {data: await response.json()};
|
||||
},
|
||||
delete: async (url, token) => {
|
||||
if (!token) {
|
||||
return null;
|
||||
}
|
||||
const response = await fetch('/api' + url, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Token ${token}`,
|
||||
},
|
||||
});
|
||||
return {data: await response.json()};
|
||||
}
|
||||
}
|
||||
|
||||
export {ticketStateColorLookup, ticketStateIconLookup, http};
|
|
@ -100,7 +100,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<style scoped>
|
||||
input{
|
||||
input {
|
||||
background-color: var(--dark);
|
||||
border: var(--gray) 1px solid;;
|
||||
|
||||
|
|
Loading…
Reference in a new issue