Better handle focus perks
This commit is contained in:
parent
87b4a25aa6
commit
747478f0d7
|
@ -50,11 +50,11 @@
|
||||||
},
|
},
|
||||||
"markdown": {
|
"markdown": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
"sha256:c00429bd503a47ec88d5e30a751e147dcb4c6889663cd3e2ba0afe858e009baa",
|
"sha256:fc4a6f69a656b8d858d7503bda633f4dd63c2d70cf80abdc6eafa64c4ae8c250",
|
||||||
"sha256:d02e0f9b04c500cde6637c11ad7c72671f359b87b9fe924b2383649d8841db7c"
|
"sha256:fe463ff51e679377e3624984c829022e2cfb3be5518726b06f608a07a3aad680"
|
||||||
],
|
],
|
||||||
"index": "pypi",
|
"index": "pypi",
|
||||||
"version": "==3.0.1"
|
"version": "==3.1"
|
||||||
},
|
},
|
||||||
"psycopg2-binary": {
|
"psycopg2-binary": {
|
||||||
"hashes": [
|
"hashes": [
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from .models import Tree, Perk
|
from .models import Tree, Perk, User
|
||||||
|
|
||||||
admin.site.register(Tree)
|
admin.site.register(Tree)
|
||||||
admin.site.register(Perk)
|
admin.site.register(Perk)
|
||||||
|
admin.site.register(User)
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,9 @@ class Tree(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f'<Tree: {str(self)}>'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('name',)
|
ordering = ('name',)
|
||||||
|
|
||||||
|
@ -29,7 +32,10 @@ class Perk(models.Model):
|
||||||
trees = models.ManyToManyField('Tree', related_name='perks', symmetrical=False)
|
trees = models.ManyToManyField('Tree', related_name='perks', symmetrical=False)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f'{self.name}'
|
return f'{self.name} [{self.level}]'
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f'<Perk: {str(self)}>'
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ('name',)
|
ordering = ('name',)
|
||||||
|
@ -39,3 +45,9 @@ class User(models.Model):
|
||||||
base_user = models.OneToOneField(AuthUser, on_delete=models.CASCADE)
|
base_user = models.OneToOneField(AuthUser, on_delete=models.CASCADE)
|
||||||
perks = models.ManyToManyField(Perk, related_name='users', symmetrical=False)
|
perks = models.ManyToManyField(Perk, related_name='users', symmetrical=False)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'{self.base_user.username} ({self.id})'
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f'<User: {str(self)}>'
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
import csv
|
import csv
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from .models import Tree, Perk
|
from .models import Tree, Perk
|
||||||
|
|
||||||
requirement_pattern = re.compile(r'([\w\s]+) \(([\w\s]+)\)')
|
requirement_pattern = re.compile(r'([\w\s]+) \(([\w\s]+)\)')
|
||||||
|
@ -94,11 +95,19 @@ class PerkParser():
|
||||||
elif 'Skill Focus' in req_name or 'Ability Focus' in req_name:
|
elif 'Skill Focus' in req_name or 'Ability Focus' in req_name:
|
||||||
req_match = re.match(requirement_pattern, req_name)
|
req_match = re.match(requirement_pattern, req_name)
|
||||||
req_tree = Tree.objects.get(name=req_match.group(2))
|
req_tree = Tree.objects.get(name=req_match.group(2))
|
||||||
|
|
||||||
req_base_name = req_match.group(1)
|
req_base_name = req_match.group(1)
|
||||||
base_req = Perk.objects.get(name=req_base_name)
|
base_req = Perk.objects.get(name=req_base_name)
|
||||||
|
|
||||||
req = self.create_perk(name=req_name, effect=base_req.effect, level=base_req.level, perk_type=base_req.type, trees=[req_tree])
|
req = self.create_perk(name=req_name, effect=base_req.effect, level=base_req.level, perk_type=base_req.type, trees=[req_tree])
|
||||||
|
if 'Greater' in req_base_name:
|
||||||
|
greater_req_name = req_name[8:]
|
||||||
|
try:
|
||||||
|
greater_req = Perk.objects.get(name=greater_req_name)
|
||||||
|
except Perk.DoesNotExist:
|
||||||
|
greater_req_base_name = req_base_name[8:]
|
||||||
|
greater_base_req = Perk.objects.get(name=greater_req_base_name)
|
||||||
|
greater_req = self.create_perk(name=greater_req_name, effect=greater_base_req.effect, level=greater_base_req.level, perk_type=greater_base_req.type, trees=[req_tree])
|
||||||
|
|
||||||
|
req.parents.add(greater_req)
|
||||||
else:
|
else:
|
||||||
req = self.create_perk(name=req_name, level=0, perk_type=4)
|
req = self.create_perk(name=req_name, level=0, perk_type=4)
|
||||||
perk.parents.add(req)
|
perk.parents.add(req)
|
||||||
|
|
|
@ -23,10 +23,6 @@ export default class AuthApi {
|
||||||
return Axios.post(ENDPOINTS.LOGIN, data);
|
return Axios.post(ENDPOINTS.LOGIN, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static signup(data) {
|
|
||||||
return Axios.post(ENDPOINTS.USER, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static changePassword(data) {
|
static changePassword(data) {
|
||||||
return Axios.patch(ENDPOINTS.USER, data);
|
return Axios.patch(ENDPOINTS.USER, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,10 @@ export default class AuthApi {
|
||||||
return Axios.get(ENDPOINTS.USER);
|
return Axios.get(ENDPOINTS.USER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static createUser(data) {
|
||||||
|
return Axios.post(ENDPOINTS.USER, data);
|
||||||
|
}
|
||||||
|
|
||||||
static updatePerks(data) {
|
static updatePerks(data) {
|
||||||
return Axios.patch(ENDPOINTS.USER, data);
|
return Axios.patch(ENDPOINTS.USER, data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,10 @@ export default {
|
||||||
{ icon: 'fas fa-code-branch', text: 'Perk trees', to: { name: 'trees' } },
|
{ icon: 'fas fa-code-branch', text: 'Perk trees', to: { name: 'trees' } },
|
||||||
{ icon: 'fas fa-sign-out-alt', text: 'Logout', to: { name: 'logout' } },
|
{ icon: 'fas fa-sign-out-alt', text: 'Logout', to: { name: 'logout' } },
|
||||||
],
|
],
|
||||||
false: [{ icon: 'fas fa-sign-in-alt', text: 'Login', to: { name: 'login' } }],
|
false: [
|
||||||
|
{ icon: 'fas fa-sign-in-alt', text: 'Login', to: { name: 'login' } },
|
||||||
|
{ icon: 'fas fa-user-plus ', text: 'Sign up', to: { name: 'signup' } },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
|
@ -68,7 +68,7 @@
|
||||||
email: this.email,
|
email: this.email,
|
||||||
password: this.password,
|
password: this.password,
|
||||||
};
|
};
|
||||||
AuthController.register(data).then(() => {
|
AuthController.signup(data).then(() => {
|
||||||
this.$router.push({ name: 'index' });
|
this.$router.push({ name: 'index' });
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
if (error.response) {
|
if (error.response) {
|
||||||
|
@ -83,8 +83,9 @@
|
||||||
<style lang="stylus">
|
<style lang="stylus">
|
||||||
.signup-form-card
|
.signup-form-card
|
||||||
padding 2rem
|
padding 2rem
|
||||||
|
margin-top 5rem
|
||||||
|
|
||||||
.login-errors
|
.signup-errors
|
||||||
color red
|
color red
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<v-container class="perktree">
|
<v-container class="perktree">
|
||||||
<v-layout row wrap>
|
<v-layout row wrap>
|
||||||
<v-flex xl8 offset-xl2 sm12>
|
<v-flex xl10 offset-xl1 sm12>
|
||||||
<v-card>
|
<v-card>
|
||||||
<div id="perktree"></div>
|
<div id="perktree"></div>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
@ -129,10 +129,8 @@ export default {
|
||||||
const clickedNode = _.find(nodes, (n) => {
|
const clickedNode = _.find(nodes, (n) => {
|
||||||
return n.name === node.name;
|
return n.name === node.name;
|
||||||
});
|
});
|
||||||
if (clickedNode.effect) {
|
this.selectedPerk = clickedNode;
|
||||||
this.selectedPerk = clickedNode;
|
this.dialog = true;
|
||||||
this.dialog = true;
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.draw(graphData);
|
.draw(graphData);
|
||||||
},
|
},
|
||||||
|
|
|
@ -5,6 +5,8 @@
|
||||||
* Distributed under terms of the BSD-3-Clause license.
|
* Distributed under terms of the BSD-3-Clause license.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
|
||||||
import AuthApi from '../apis/auth.api';
|
import AuthApi from '../apis/auth.api';
|
||||||
import router from '../router';
|
import router from '../router';
|
||||||
import store from '../store';
|
import store from '../store';
|
||||||
|
@ -38,24 +40,22 @@ export default class AuthController {
|
||||||
}
|
}
|
||||||
|
|
||||||
static setupToken() {
|
static setupToken() {
|
||||||
const access = this.getLocalStorageToken().access;
|
const access = AuthController.getLocalStorageToken().access;
|
||||||
AuthApi.setAuthHeader(access);
|
if (access) {
|
||||||
store.commit('login');
|
AuthApi.setAuthHeader(access);
|
||||||
|
store.commit('login');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static login(data) {
|
static login(data) {
|
||||||
return AuthApi.login(data).then((response) => {
|
return AuthApi.login(data).then((response) => {
|
||||||
this.setLocalStorageToken(response.data);
|
AuthController.setLocalStorageToken(response.data);
|
||||||
this.setupToken(response.data);
|
AuthController.setupToken(response.data);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static signup(data) {
|
|
||||||
return AuthApi.signup(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static logout() {
|
static logout() {
|
||||||
this.clearLocalStorageToken();
|
AuthController.clearLocalStorageToken();
|
||||||
store.commit('logout');
|
store.commit('logout');
|
||||||
AuthApi.setAuthHeader('');
|
AuthApi.setAuthHeader('');
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ export default class AuthController {
|
||||||
}
|
}
|
||||||
|
|
||||||
static verifyToken() {
|
static verifyToken() {
|
||||||
const token = this.getLocalStorageToken().access;
|
const token = AuthController.getLocalStorageToken().access;
|
||||||
if (token === null) {
|
if (token === null) {
|
||||||
router.push('login');
|
router.push('login');
|
||||||
}
|
}
|
||||||
|
@ -73,22 +73,24 @@ export default class AuthController {
|
||||||
}
|
}
|
||||||
|
|
||||||
static refreshToken() {
|
static refreshToken() {
|
||||||
if (!this.getLocalStorageRefresh()) {
|
if (!AuthController.getLocalStorageRefresh()) {
|
||||||
return Promise.reject(new Error('No token'));
|
return Promise.reject(new Error('No token'));
|
||||||
}
|
}
|
||||||
|
|
||||||
const refresh = {
|
const refresh = {
|
||||||
refresh: this.getLocalStorageToken().refresh,
|
refresh: AuthController.getLocalStorageToken().refresh,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_.delay(AuthController.refreshToken, 240000);
|
||||||
|
|
||||||
return AuthApi.refreshToken(refresh).then((response) => {
|
return AuthApi.refreshToken(refresh).then((response) => {
|
||||||
this.setLocalStorageToken(response.data);
|
AuthController.setLocalStorageToken(response.data);
|
||||||
this.setupToken();
|
AuthController.setupToken();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
static getAuthStatus() {
|
static getAuthStatus() {
|
||||||
const token = this.getLocalStorageToken().access;
|
const token = AuthController.getLocalStorageToken().access;
|
||||||
return Boolean(token);
|
return Boolean(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,10 @@ export default class AuthController {
|
||||||
return UserApi.getUser();
|
return UserApi.getUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static signup(data) {
|
||||||
|
return UserApi.signup(data);
|
||||||
|
}
|
||||||
|
|
||||||
static updatePerks(perks) {
|
static updatePerks(perks) {
|
||||||
const data = {
|
const data = {
|
||||||
perks,
|
perks,
|
||||||
|
|
|
@ -9,7 +9,7 @@ import './plugins/vuetify';
|
||||||
import App from './components/app.vue';
|
import App from './components/app.vue';
|
||||||
import { config } from './config';
|
import { config } from './config';
|
||||||
import router from './router';
|
import router from './router';
|
||||||
import store from './store';
|
import store from './store/';
|
||||||
import AuthController from './controllers/auth.controller';
|
import AuthController from './controllers/auth.controller';
|
||||||
|
|
||||||
import 'roboto-fontface/css/roboto/roboto-fontface.css';
|
import 'roboto-fontface/css/roboto/roboto-fontface.css';
|
||||||
|
@ -27,9 +27,7 @@ const configureHttp = () => {
|
||||||
},
|
},
|
||||||
(error) => {
|
(error) => {
|
||||||
if (error.response && error.response.status === 401) {
|
if (error.response && error.response.status === 401) {
|
||||||
AuthController.refreshToken().then(() => {
|
AuthController.refreshToken().catch(() => {
|
||||||
router.push({ path: router.currentRoute.path });
|
|
||||||
}).catch(() => {
|
|
||||||
router.push({
|
router.push({
|
||||||
name: 'logout',
|
name: 'logout',
|
||||||
});
|
});
|
||||||
|
@ -42,12 +40,10 @@ const configureHttp = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const configureRaven = () => {
|
const configureRaven = () => {
|
||||||
if (config.getEnv() !== 'dev') {
|
Raven
|
||||||
Raven
|
.config('https://2b1b0eea285244289175e53d65421fac@sentry.theedgeofrage.com/3')
|
||||||
.config('https://2b1b0eea285244289175e53d65421fac@sentry.theedgeofrage.com/3')
|
.addPlugin(RavenVue, Vue)
|
||||||
.addPlugin(RavenVue, Vue)
|
.install();
|
||||||
.install();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
configureHttp();
|
configureHttp();
|
||||||
|
|
|
@ -37,7 +37,7 @@ const router = new Router({
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/signup',
|
path: '/signup',
|
||||||
name: 'signpu',
|
name: 'signup',
|
||||||
component: Signup,
|
component: Signup,
|
||||||
meta: {
|
meta: {
|
||||||
guest: true,
|
guest: true,
|
||||||
|
|
|
@ -1,17 +1,12 @@
|
||||||
/*
|
/*
|
||||||
* store.js
|
* auth.js
|
||||||
* Copyright (C) 2019 pavle <pavle.portic@tilda.center>
|
* Copyright (C) 2019 pavle <pavle.portic@tilda.center>
|
||||||
*
|
*
|
||||||
* Distributed under terms of the BSD-3-Clause license.
|
* Distributed under terms of the BSD-3-Clause license.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Vue from 'vue';
|
|
||||||
import Vuex from 'vuex';
|
|
||||||
|
|
||||||
Vue.use(Vuex);
|
|
||||||
|
|
||||||
const state = {
|
const state = {
|
||||||
authStatus: null,
|
authStatus: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
const getters = {
|
const getters = {
|
||||||
|
@ -27,9 +22,9 @@ const mutations = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default new Vuex.Store({
|
export default {
|
||||||
state,
|
state,
|
||||||
getters,
|
getters,
|
||||||
mutations,
|
mutations,
|
||||||
});
|
};
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
/*
|
||||||
|
* index.js
|
||||||
|
* Copyright (C) 2019 pavle <pavle.portic@tilda.center>
|
||||||
|
*
|
||||||
|
* Distributed under terms of the BSD-3-Clause license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Vue from 'vue';
|
||||||
|
import Vuex from 'vuex';
|
||||||
|
|
||||||
|
import perks from './perks';
|
||||||
|
import auth from './auth';
|
||||||
|
|
||||||
|
Vue.use(Vuex);
|
||||||
|
|
||||||
|
const storeData = {
|
||||||
|
modules: {
|
||||||
|
perks,
|
||||||
|
auth,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default new Vuex.Store(storeData);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* perks.js
|
||||||
|
* Copyright (C) 2019 pavle <pavle.portic@tilda.center>
|
||||||
|
*
|
||||||
|
* Distributed under terms of the BSD-3-Clause license.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
perks: [],
|
||||||
|
};
|
||||||
|
|
||||||
|
const getters = {
|
||||||
|
perks: (state) => state.perks,
|
||||||
|
};
|
||||||
|
|
||||||
|
const mutations = {
|
||||||
|
setPerks(perks) {
|
||||||
|
state.perks = perks;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
state,
|
||||||
|
getters,
|
||||||
|
mutations,
|
||||||
|
};
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
devServer: {
|
devServer: {
|
||||||
disableHostCheck: true,
|
disableHostCheck: true,
|
||||||
public: 'perktree.localhost',
|
public: 'perktree.localhost',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
Reference in New Issue