migrate to vue 3
This commit is contained in:
parent
bb07a6b641
commit
bb71c44aa7
16 changed files with 318 additions and 432 deletions
394
web/src/store.js
Normal file
394
web/src/store.js
Normal file
|
@ -0,0 +1,394 @@
|
|||
import {createStore} from 'vuex';
|
||||
import router from './router';
|
||||
|
||||
import * as base64 from 'base-64';
|
||||
import * as utf8 from 'utf8';
|
||||
import {ticketStateColorLookup, ticketStateIconLookup, http} from "@/utils";
|
||||
|
||||
const store = createStore({
|
||||
state: {
|
||||
keyIncrement: 0,
|
||||
events: [],
|
||||
loadedItems: [],
|
||||
itemCache: {},
|
||||
loadedBoxes: [],
|
||||
toasts: [],
|
||||
tickets: [],
|
||||
users: [],
|
||||
groups: [],
|
||||
state_options: [],
|
||||
lastEvent: localStorage.getItem('lf_lastEvent') || '37C3',
|
||||
lastUsed: JSON.parse(localStorage.getItem('lf_lastUsed') || '{}'),
|
||||
remember: false,
|
||||
|
||||
user: {
|
||||
username: null,
|
||||
password: null,
|
||||
permissions: [],
|
||||
token: null,
|
||||
expiry: null,
|
||||
},
|
||||
|
||||
local_loaded: false,
|
||||
showAddBoxModal: false,
|
||||
},
|
||||
getters: {
|
||||
route: state => router.currentRoute.value,
|
||||
getEventSlug: state => router.currentRoute.value.params.event ? router.currentRoute.value.params.event : state.lastEvent,
|
||||
getActiveView: state => router.currentRoute.value.name || 'items',
|
||||
getFilters: state => router.currentRoute.value.query,
|
||||
getBoxes: state => state.loadedBoxes,
|
||||
checkPermission: state => (event, perm) => state.user.permissions.includes(`${event}:${perm}`) || state.user.permissions.includes(`*:${perm}`),
|
||||
hasPermissions: state => state.user.permissions.length > 0,
|
||||
stateInfo: state => (slug) => {
|
||||
const obj = state.state_options.filter((s) => s.value === slug)[0];
|
||||
if (obj) {
|
||||
return {
|
||||
color: ticketStateColorLookup(obj.value),
|
||||
icon: ticketStateIconLookup(obj.value),
|
||||
slug: obj.value,
|
||||
text: obj.text,
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
color: 'danger',
|
||||
icon: 'exclamation',
|
||||
slug: slug,
|
||||
text: 'Unknown'
|
||||
}
|
||||
}
|
||||
},
|
||||
layout: (state, getters) => {
|
||||
if (router.currentRoute.value.query.layout)
|
||||
return router.currentRoute.value.query.layout;
|
||||
if (getters.getActiveView === 'items')
|
||||
return 'cards';
|
||||
if (getters.getActiveView === 'tickets')
|
||||
return 'tasks';
|
||||
},
|
||||
isLoggedIn(state) {
|
||||
if (!state.local_loaded) {
|
||||
state.remember = localStorage.getItem('remember') === 'true';
|
||||
state.user.username = localStorage.getItem('user');
|
||||
//state.password = localStorage.getItem('password');
|
||||
state.user.permissions = JSON.parse(localStorage.getItem('permissions') || '[]');
|
||||
state.user.token = localStorage.getItem('token');
|
||||
state.user.expiry = localStorage.getItem('token_expiry');
|
||||
state.local_loaded = true;
|
||||
}
|
||||
|
||||
return state.user && state.user.username !== null && state.user.token !== null;
|
||||
},
|
||||
},
|
||||
mutations: {
|
||||
updateLastUsed(state, diff) {
|
||||
state.lastUsed = {...state.lastUsed, ...diff};
|
||||
localStorage.setItem('lf_lastUsed', JSON.stringify(state.lastUsed));
|
||||
},
|
||||
updateLastEvent(state, slug) {
|
||||
state.lastEvent = slug;
|
||||
localStorage.setItem('lf_lastEvent', slug);
|
||||
},
|
||||
replaceEvents(state, events) {
|
||||
state.events = events;
|
||||
},
|
||||
replaceTicketStates(state, states) {
|
||||
state.state_options = states;
|
||||
},
|
||||
changeView(state, {view, slug}) {
|
||||
router.push({path: `/${slug}/${view}`});
|
||||
},
|
||||
replaceLoadedItems(state, newItems) {
|
||||
state.loadedItems = newItems;
|
||||
},
|
||||
setItemCache(state, {slug, items}) {
|
||||
state.itemCache[slug] = items;
|
||||
},
|
||||
replaceBoxes(state, loadedBoxes) {
|
||||
state.loadedBoxes = loadedBoxes;
|
||||
},
|
||||
updateItem(state, updatedItem) {
|
||||
const item = state.loadedItems.filter(({uid}) => uid === updatedItem.uid)[0];
|
||||
Object.assign(item, updatedItem);
|
||||
},
|
||||
removeItem(state, item) {
|
||||
state.loadedItems = state.loadedItems.filter(it => it !== item);
|
||||
},
|
||||
appendItem(state, item) {
|
||||
state.loadedItems.push(item);
|
||||
},
|
||||
replaceTickets(state, tickets) {
|
||||
state.tickets = tickets;
|
||||
},
|
||||
replaceUsers(state, users) {
|
||||
state.users = users;
|
||||
},
|
||||
replaceGroups(state, groups) {
|
||||
state.groups = groups;
|
||||
},
|
||||
updateTicket(state, updatedTicket) {
|
||||
const ticket = state.tickets.filter(({id}) => id === updatedTicket.id)[0];
|
||||
Object.assign(ticket, updatedTicket);
|
||||
},
|
||||
openAddBoxModal(state) {
|
||||
state.showAddBoxModal = true;
|
||||
},
|
||||
closeAddBoxModal(state) {
|
||||
state.showAddBoxModal = false;
|
||||
},
|
||||
createToast(state, {title, message, color}) {
|
||||
var toast = {title, message, color, key: state.keyIncrement}
|
||||
state.toasts.push(toast);
|
||||
state.keyIncrement += 1;
|
||||
return toast;
|
||||
},
|
||||
removeToast(state, key) {
|
||||
state.toasts = state.toasts.filter(toast => toast.key !== key);
|
||||
},
|
||||
setRemember(state, remember) {
|
||||
state.remember = remember;
|
||||
localStorage.setItem('remember', remember);
|
||||
},
|
||||
setUser(state, user) {
|
||||
state.user.username = user;
|
||||
if (user)
|
||||
localStorage.setItem('user', user);
|
||||
},
|
||||
setPassword(state, password) {
|
||||
state.user.password = password;
|
||||
},
|
||||
setPermissions(state, permissions) {
|
||||
state.user.permissions = permissions;
|
||||
if (permissions)
|
||||
localStorage.setItem('permissions', JSON.stringify(permissions));
|
||||
},
|
||||
setToken(state, {token, expiry}) {
|
||||
const user = {...state.user};
|
||||
user.token = token;
|
||||
user.expiry = expiry;
|
||||
state.user = user;
|
||||
if (token)
|
||||
localStorage.setItem('token', token);
|
||||
localStorage.setItem('token_expiry', expiry);
|
||||
},
|
||||
setUserInfo(state, user) {
|
||||
state.user = user;
|
||||
},
|
||||
logout(state) {
|
||||
const user = {...state.user};
|
||||
user.user = null;
|
||||
user.password = null;
|
||||
user.token = null;
|
||||
user.expiry = null;
|
||||
user.permissions = null;
|
||||
state.user = user;
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
async login({commit, dispatch, state}, {username, password, remember}) {
|
||||
commit('setRemember', remember);
|
||||
try {
|
||||
const data = await fetch('/api/2/login/', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({username: username, password: password}),
|
||||
credentials: 'omit'
|
||||
}).then(r => r.json())
|
||||
if (data && data.token) {
|
||||
commit('setToken', data);
|
||||
commit('setUser', username);
|
||||
commit('setPassword', password);
|
||||
dispatch('afterLogin');
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
return false;
|
||||
}
|
||||
},
|
||||
async reloadToken({commit, state, getters}) {
|
||||
try {
|
||||
if (state.user.username && state.user.password) {
|
||||
const data = await fetch('/api/2/login/', {
|
||||
method: 'POST',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify({username: state.user.username, password: state.user.password}),
|
||||
credentials: 'omit'
|
||||
}).then(r => r.json()).catch(e => console.error(e))
|
||||
if (data && data.token) {
|
||||
commit('setToken', data);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
//credentials failed, logout
|
||||
store.commit('logout');
|
||||
},
|
||||
//async verifyToken({commit, state}) {
|
||||
async afterLogin({dispatch, state}) {
|
||||
let promises = [];
|
||||
promises.push(dispatch('loadBoxes'));
|
||||
promises.push(dispatch('fetchTicketStates'));
|
||||
promises.push(dispatch('loadEventItems'));
|
||||
promises.push(dispatch('loadTickets'));
|
||||
if (!state.user.permissions) {
|
||||
promises.push(dispatch('loadUserInfo'));
|
||||
}
|
||||
await Promise.all(promises);
|
||||
},
|
||||
async fetchImage({state}, url) {
|
||||
return await fetch(url, {headers: {'Authorization': `Token ${state.user.token}`}});
|
||||
},
|
||||
async loadUserInfo({commit, state}) {
|
||||
const {data, success} = await http.get('/2/self/', state.user.token);
|
||||
commit('setPermissions', data.permissions);
|
||||
},
|
||||
async loadEvents({commit, state}) {
|
||||
const {data, success} = await http.get('/2/events/', state.user.token);
|
||||
if (data && success)
|
||||
commit('replaceEvents', data);
|
||||
},
|
||||
async fetchTicketStates({commit, state}) {
|
||||
const {data, success} = await http.get('/2/tickets/states/', state.user.token);
|
||||
if (data && success)
|
||||
commit('replaceTicketStates', data);
|
||||
},
|
||||
changeEvent({dispatch, getters, commit}, eventName) {
|
||||
router.push({path: `/${eventName.slug}/${getters.getActiveView}/`});
|
||||
dispatch('loadEventItems');
|
||||
},
|
||||
changeView({getters}, link) {
|
||||
router.push({path: `/${getters.getEventSlug}/${link.path}/`});
|
||||
},
|
||||
showBoxContent({getters}, box) {
|
||||
router.push({path: `/${getters.getEventSlug}/items/`, query: {box}});
|
||||
},
|
||||
async loadEventItems({commit, getters, state}) {
|
||||
try {
|
||||
commit('replaceLoadedItems', []);
|
||||
const slug = getters.getEventSlug;
|
||||
if (slug in state.itemCache) {
|
||||
commit('replaceLoadedItems', state.itemCache[slug]);
|
||||
}
|
||||
const {data, success} = await http.get(`/2/${slug}/items/`, state.user.token);
|
||||
if (data && success) {
|
||||
commit('replaceLoadedItems', data);
|
||||
commit('setItemCache', {slug, items: data});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Error loading items");
|
||||
}
|
||||
},
|
||||
async searchEventItems({commit, getters, state}, query) {
|
||||
const foo = utf8.encode(query);
|
||||
const bar = base64.encode(foo);
|
||||
|
||||
const {data, success} = await http.get(`/2/${getters.getEventSlug}/items/${bar}/`, state.user.token);
|
||||
if (data && success)
|
||||
commit('replaceLoadedItems', data);
|
||||
},
|
||||
async loadBoxes({commit, state}) {
|
||||
const {data, success} = await http.get('/2/boxes/', state.user.token);
|
||||
if (data && success)
|
||||
commit('replaceBoxes', data);
|
||||
},
|
||||
async createBox({commit, dispatch, state}, box) {
|
||||
const {data, success} = await http.post('/2/boxes/', box, state.user.token);
|
||||
commit('replaceBoxes', data);
|
||||
dispatch('loadBoxes').then(() => {
|
||||
commit('closeAddBoxModal');
|
||||
});
|
||||
},
|
||||
async deleteBox({commit, dispatch, state}, box_id) {
|
||||
await http.delete(`/2/boxes/${box_id}/`, state.user.token);
|
||||
dispatch('loadBoxes');
|
||||
},
|
||||
async updateItem({commit, getters, state}, item) {
|
||||
const {
|
||||
data,
|
||||
success
|
||||
} = await http.put(`/2/${getters.getEventSlug}/item/${item.uid}/`, item, state.user.token);
|
||||
commit('updateItem', data);
|
||||
},
|
||||
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, state}, item) {
|
||||
await http.delete(`/2/${getters.getEventSlug}/item/${item.uid}/`, item, state.user.token);
|
||||
commit('removeItem', item);
|
||||
},
|
||||
async postItem({commit, getters, state}, item) {
|
||||
commit('updateLastUsed', {box: item.box, cid: item.cid});
|
||||
const {data, success} = await http.post(`/2/${getters.getEventSlug}/item/`, item, state.user.token);
|
||||
commit('appendItem', data);
|
||||
},
|
||||
async loadTickets({commit, state}) {
|
||||
const {data, success} = await http.get('/2/tickets/', state.user.token);
|
||||
if (data && success)
|
||||
commit('replaceTickets', data);
|
||||
},
|
||||
async sendMail({commit, dispatch, state}, {id, message}) {
|
||||
const {data, success} = await http.post(`/2/tickets/${id}/reply/`, {message}, state.user.token);
|
||||
if (data && success) {
|
||||
await dispatch('loadTickets');
|
||||
}
|
||||
},
|
||||
async postManualTicket({commit, dispatch, state}, {sender, message, title,}) {
|
||||
const {data, success} = 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, state}, {id, message}) {
|
||||
const {data, success} = await http.post(`/2/tickets/${id}/comment/`, {comment: message}, state.user.token);
|
||||
if (data && success) {
|
||||
await dispatch('loadTickets');
|
||||
}
|
||||
},
|
||||
async loadUsers({commit, state}) {
|
||||
const {data, success} = await http.get('/2/users/', state.user.token);
|
||||
if (data && success)
|
||||
commit('replaceUsers', data);
|
||||
},
|
||||
async loadGroups({commit, state}) {
|
||||
const {data, success} = await http.get('/2/groups/', state.user.token);
|
||||
if (data && success)
|
||||
commit('replaceGroups', data);
|
||||
},
|
||||
async updateTicket({commit, state}, ticket) {
|
||||
const {data, success} = await http.put(`/2/tickets/${ticket.id}/`, ticket, state.user.token);
|
||||
commit('updateTicket', data);
|
||||
},
|
||||
async updateTicketPartial({commit, state}, {id, ...ticket}) {
|
||||
const {data, success} = await http.patch(`/2/tickets/${id}/`, ticket, state.user.token);
|
||||
commit('updateTicket', data);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
store.watch((state) => state.user, (user) => {
|
||||
console.log('user changed', user);
|
||||
if (store.getters.isLoggedIn) {
|
||||
if (router.currentRoute.value.name === 'login' && router.currentRoute.value.query.redirect)
|
||||
router.push(router.currentRoute.value.query.redirect);
|
||||
else if (router.currentRoute.value.name === 'login')
|
||||
router.push('/');
|
||||
} else {
|
||||
if (router.currentRoute.value.name !== 'login') {
|
||||
router.push({
|
||||
name: 'login',
|
||||
query: {redirect: router.currentRoute.value.fullPath},
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
export default store;
|
Loading…
Add table
Add a link
Reference in a new issue