Vuex (#126)
Merge branch 'master' into feature/vuex Cleanup Move namespaces handling to store Move fullpage setting to store Move online/offline handling to store Remove debug log Fix loading namepaces Rename errorMsg Handle registering through the store Use store to determine wether or not a user is authenticated on login page Use store in edit team Use store to get the current user's avatar Use store to figure out if the current user belongs to a team Use store to figure out if the current user is list admin Use store to get user info when listing labels Use store to get username on home Use store to figure out if the user is namespace admin Use the store for configuration Use the store to check if a user is authenticated everywhere Only renew token if the user is logged in Fix renewing auth from jwt token Move logout to store Move renew token to store Move log in to store Only show enabled migrators Only show registration button if registration is enabled Put all config information from the backend in the store Remove old config handler Move config state to seperate module Add vuex and get the motd through it Co-authored-by: kolaente <k@knt.li> Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/126
This commit is contained in:
@ -1,21 +1,26 @@
|
||||
<template>
|
||||
<div class="content has-text-centered">
|
||||
<h2>Hi {{user.infos.username}}!</h2>
|
||||
<h2>Hi {{userInfo.username}}!</h2>
|
||||
<p>Click on a list or namespace on the left to get started.</p>
|
||||
<router-link class="button is-primary is-right noshadow is-outlined" :to="{name: 'migrateStart'}">Import your data into Vikunja</router-link>
|
||||
<router-link
|
||||
class="button is-primary is-right noshadow is-outlined"
|
||||
:to="{name: 'migrateStart'}"
|
||||
v-if="migratorsEnabled"
|
||||
>
|
||||
Import your data into Vikunja
|
||||
</router-link>
|
||||
<TaskOverview :show-all="true"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import auth from '../auth'
|
||||
import router from '../router'
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: "Home",
|
||||
data() {
|
||||
return {
|
||||
user: auth.user,
|
||||
loading: false,
|
||||
currentDate: new Date(),
|
||||
tasks: []
|
||||
@ -23,14 +28,14 @@
|
||||
},
|
||||
beforeMount() {
|
||||
// Check if the user is already logged in, if so, redirect him to the homepage
|
||||
if (!auth.user.authenticated) {
|
||||
if (!this.authenticated) {
|
||||
router.push({name: 'login'})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
logout() {
|
||||
auth.logout()
|
||||
},
|
||||
},
|
||||
computed: mapState({
|
||||
migratorsEnabled: state => state.config.availableMigrators !== null && state.config.availableMigrators.length > 0,
|
||||
authenticated: state => state.auth.authenticated,
|
||||
userInfo: state => state.auth.info,
|
||||
}),
|
||||
}
|
||||
</script>
|
||||
|
@ -11,11 +11,11 @@
|
||||
<span
|
||||
v-for="l in labels" :key="l.id"
|
||||
class="tag"
|
||||
:class="{'disabled': user.infos.id !== l.createdBy.id}"
|
||||
:class="{'disabled': userInfo.id !== l.createdBy.id}"
|
||||
:style="{'background': l.hexColor, 'color': l.textColor}"
|
||||
>
|
||||
<span
|
||||
v-if="user.infos.id !== l.createdBy.id"
|
||||
v-if="userInfo.id !== l.createdBy.id"
|
||||
v-tooltip.bottom="'You are not allowed to edit this label because you dont own it.'">
|
||||
{{ l.title }}
|
||||
</span>
|
||||
@ -25,7 +25,7 @@
|
||||
v-else>
|
||||
{{ l.title }}
|
||||
</a>
|
||||
<a class="delete is-small" @click="deleteLabel(l)" v-if="user.infos.id === l.createdBy.id"></a>
|
||||
<a class="delete is-small" @click="deleteLabel(l)" v-if="userInfo.id === l.createdBy.id"></a>
|
||||
</span>
|
||||
</div>
|
||||
<div class="column is-4" v-if="isLabelEdit">
|
||||
@ -102,10 +102,10 @@
|
||||
<script>
|
||||
import verte from 'verte'
|
||||
import 'verte/dist/verte.css'
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
import LabelService from '../../services/label'
|
||||
import LabelModel from '../../models/label'
|
||||
import auth from '../../auth'
|
||||
|
||||
export default {
|
||||
name: 'ListLabels',
|
||||
@ -118,7 +118,6 @@
|
||||
labels: [],
|
||||
labelEditLabel: LabelModel,
|
||||
isLabelEdit: false,
|
||||
user: auth.user,
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@ -126,6 +125,9 @@
|
||||
this.labelEditLabel = new LabelModel()
|
||||
this.loadLabels()
|
||||
},
|
||||
computed: mapState({
|
||||
userInfo: state => state.auth.info
|
||||
}),
|
||||
methods: {
|
||||
loadLabels() {
|
||||
const getAllLabels = (page = 1) => {
|
||||
@ -183,7 +185,7 @@
|
||||
})
|
||||
},
|
||||
editLabel(label) {
|
||||
if (label.createdBy.id !== this.user.infos.id) {
|
||||
if (label.createdBy.id !== this.userInfo.id) {
|
||||
return
|
||||
}
|
||||
this.labelEditLabel = label
|
||||
|
@ -68,7 +68,7 @@
|
||||
<component :is="manageUsersComponent" :id="list.id" type="list" shareType="user" :userIsAdmin="userIsAdmin"></component>
|
||||
<component :is="manageTeamsComponent" :id="list.id" type="list" shareType="team" :userIsAdmin="userIsAdmin"></component>
|
||||
|
||||
<link-sharing :list-id="$route.params.id"/>
|
||||
<link-sharing :list-id="$route.params.id" v-if="linkSharingEnabled"/>
|
||||
|
||||
<modal
|
||||
v-if="showDeleteModal"
|
||||
@ -85,7 +85,6 @@
|
||||
import verte from 'verte'
|
||||
import 'verte/dist/verte.css'
|
||||
|
||||
import auth from '../../auth'
|
||||
import router from '../../router'
|
||||
import manageSharing from '../sharing/userTeam'
|
||||
import LinkSharing from '../sharing/linkSharing'
|
||||
@ -102,8 +101,6 @@
|
||||
listService: ListService,
|
||||
|
||||
showDeleteModal: false,
|
||||
user: auth.user,
|
||||
userIsAdmin: false, // FIXME: we should be able to know somehow if the user is admin, not only based on if he's the owner
|
||||
|
||||
manageUsersComponent: '',
|
||||
manageTeamsComponent: '',
|
||||
@ -115,12 +112,6 @@
|
||||
manageSharing,
|
||||
verte,
|
||||
},
|
||||
beforeMount() {
|
||||
// Check if the user is already logged in, if so, redirect him to the homepage
|
||||
if (!auth.user.authenticated) {
|
||||
router.push({name: 'home'})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.listService = new ListService()
|
||||
this.loadList()
|
||||
@ -129,15 +120,20 @@
|
||||
// call again the method if the route changes
|
||||
'$route': 'loadList'
|
||||
},
|
||||
computed: {
|
||||
linkSharingEnabled() {
|
||||
return this.$store.state.config.linkSharingEnabled
|
||||
},
|
||||
userIsAdmin() {
|
||||
return this.list.owner && this.list.owner.id === this.$store.state.auth.info.id
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
loadList() {
|
||||
let list = new ListModel({id: this.$route.params.id})
|
||||
this.listService.get(list)
|
||||
.then(r => {
|
||||
this.$set(this, 'list', r)
|
||||
if (r.owner.id === this.user.infos.id) {
|
||||
this.userIsAdmin = true
|
||||
}
|
||||
// This will trigger the dynamic loading of components once we actually have all the data to pass to them
|
||||
this.manageTeamsComponent = 'manageSharing'
|
||||
this.manageUsersComponent = 'manageSharing'
|
||||
@ -149,15 +145,7 @@
|
||||
submit() {
|
||||
this.listService.update(this.list)
|
||||
.then(r => {
|
||||
// Update the list in the parent
|
||||
for (const n in this.$parent.namespaces) {
|
||||
let lists = this.$parent.namespaces[n].lists
|
||||
for (const l in lists) {
|
||||
if (lists[l].id === r.id) {
|
||||
this.$set(this.$parent.namespaces[n].lists, l, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
this.$store.commit('namespaces/setListInNamespaceById', r)
|
||||
this.success({message: 'The list was successfully updated.'}, this)
|
||||
})
|
||||
.catch(e => {
|
||||
|
@ -32,10 +32,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import auth from '../../auth'
|
||||
import router from '../../router'
|
||||
import ListService from '../../services/list'
|
||||
import ListModel from '../../models/list'
|
||||
import {IS_FULLPAGE} from '../../store/mutation-types'
|
||||
|
||||
export default {
|
||||
name: "NewList",
|
||||
@ -46,16 +46,10 @@
|
||||
listService: ListService,
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
// Check if the user is already logged in, if so, redirect him to the homepage
|
||||
if (!auth.user.authenticated) {
|
||||
router.push({name: 'home'})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.list = new ListModel()
|
||||
this.listService = new ListService()
|
||||
this.$parent.setFullPage();
|
||||
this.$store.commit(IS_FULLPAGE, true)
|
||||
},
|
||||
methods: {
|
||||
newList() {
|
||||
@ -68,7 +62,8 @@
|
||||
this.list.namespaceId = this.$route.params.id
|
||||
this.listService.create(this.list)
|
||||
.then(response => {
|
||||
this.$parent.loadNamespaces()
|
||||
response.namespaceId = this.list.namespaceId
|
||||
this.$store.commit('namespaces/addListToNamespace', response)
|
||||
this.success({message: 'The list was successfully created.'}, this)
|
||||
router.push({name: 'list.index', params: {listId: response.id}})
|
||||
})
|
||||
|
@ -22,12 +22,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import auth from '../../auth'
|
||||
import router from '../../router'
|
||||
|
||||
import ListModel from '../../models/list'
|
||||
import ListService from '../../services/list'
|
||||
import authType from '../../models/authTypes'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@ -37,12 +35,6 @@
|
||||
listLoaded: 0,
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
// Check if the user is already logged in, if so, redirect him to the homepage
|
||||
if (!auth.user.authenticated && auth.user.infos.type !== authType.LINK_SHARE) {
|
||||
router.push({name: 'home'})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.listService = new ListService()
|
||||
this.list = new ListModel()
|
||||
|
@ -3,9 +3,9 @@
|
||||
<h1>Import your data from other services to Vikunja</h1>
|
||||
<p>Click on the logo of one of the third-party services below to get started.</p>
|
||||
<div class="migration-services-overview">
|
||||
<router-link :to="{name: 'migrateWunderlist'}">
|
||||
<img src="/images/migration/wunderlist.png" alt="Wunderlist"/>
|
||||
Wunderlist
|
||||
<router-link :to="{name: 'migrate.'+m}" v-for="m in availableMigrators" :key="m">
|
||||
<img :src="`/images/migration/${m}.png`" :alt="m"/>
|
||||
{{ m }}
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
@ -13,6 +13,11 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'migrate'
|
||||
name: 'migrate',
|
||||
computed: {
|
||||
availableMigrators() {
|
||||
return this.$store.state.config.availableMigrators
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
@ -83,7 +83,6 @@
|
||||
import verte from 'verte'
|
||||
import 'verte/dist/verte.css'
|
||||
|
||||
import auth from '../../auth'
|
||||
import router from '../../router'
|
||||
import manageSharing from '../sharing/userTeam'
|
||||
|
||||
@ -96,13 +95,11 @@
|
||||
data() {
|
||||
return {
|
||||
namespaceService: NamespaceService,
|
||||
userIsAdmin: false,
|
||||
manageUsersComponent: '',
|
||||
manageTeamsComponent: '',
|
||||
|
||||
namespace: NamespaceModel,
|
||||
showDeleteModal: false,
|
||||
user: auth.user,
|
||||
}
|
||||
},
|
||||
components: {
|
||||
@ -111,11 +108,6 @@
|
||||
verte,
|
||||
},
|
||||
beforeMount() {
|
||||
// Check if the user is already logged in, if so, redirect him to the homepage
|
||||
if (!auth.user.authenticated) {
|
||||
router.push({name: 'home'})
|
||||
}
|
||||
|
||||
this.namespace.id = this.$route.params.id
|
||||
},
|
||||
created() {
|
||||
@ -127,15 +119,17 @@
|
||||
// call again the method if the route changes
|
||||
'$route': 'loadNamespace'
|
||||
},
|
||||
computed: {
|
||||
userIsAdmin() {
|
||||
return this.namespace.owner && this.namespace.owner.id === this.$store.state.auth.info.id
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
loadNamespace() {
|
||||
let namespace = new NamespaceModel({id: this.$route.params.id})
|
||||
this.namespaceService.get(namespace)
|
||||
.then(r => {
|
||||
this.$set(this, 'namespace', r)
|
||||
if (r.owner.id === this.user.infos.id) {
|
||||
this.userIsAdmin = true
|
||||
}
|
||||
// This will trigger the dynamic loading of components once we actually have all the data to pass to them
|
||||
this.manageTeamsComponent = 'manageSharing'
|
||||
this.manageUsersComponent = 'manageSharing'
|
||||
@ -148,12 +142,7 @@
|
||||
this.namespaceService.update(this.namespace)
|
||||
.then(r => {
|
||||
// Update the namespace in the parent
|
||||
for (const n in this.$parent.namespaces) {
|
||||
if (this.$parent.namespaces[n].id === r.id) {
|
||||
r.lists = this.$parent.namespaces[n].lists
|
||||
this.$set(this.$parent.namespaces, n, r)
|
||||
}
|
||||
}
|
||||
this.$store.commit('namespaces/setNamespaceById', r)
|
||||
this.success({message: 'The namespace was successfully updated.'}, this)
|
||||
})
|
||||
.catch(e => {
|
||||
|
@ -34,10 +34,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import auth from '../../auth'
|
||||
import router from '../../router'
|
||||
import NamespaceModel from "../../models/namespace";
|
||||
import NamespaceService from "../../services/namespace";
|
||||
import {IS_FULLPAGE} from '../../store/mutation-types'
|
||||
|
||||
export default {
|
||||
name: "NewNamespace",
|
||||
@ -48,16 +48,10 @@
|
||||
namespaceService: NamespaceService,
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
// Check if the user is already logged in, if so, redirect him to the homepage
|
||||
if (!auth.user.authenticated) {
|
||||
router.push({name: 'home'})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.namespace = new NamespaceModel()
|
||||
this.namespaceService = new NamespaceService()
|
||||
this.$parent.setFullPage();
|
||||
this.$store.commit(IS_FULLPAGE, true)
|
||||
},
|
||||
methods: {
|
||||
newNamespace() {
|
||||
@ -68,10 +62,10 @@
|
||||
this.showError = false
|
||||
|
||||
this.namespaceService.create(this.namespace)
|
||||
.then(() => {
|
||||
this.$parent.loadNamespaces()
|
||||
.then(r => {
|
||||
this.$store.commit('namespaces/addNamespace', r)
|
||||
this.success({message: 'The namespace was successfully created.'}, this)
|
||||
router.push({name: 'home'})
|
||||
router.back()
|
||||
})
|
||||
.catch(e => {
|
||||
this.error(e, this)
|
||||
|
@ -75,7 +75,7 @@
|
||||
</template>
|
||||
</td>
|
||||
<td class="actions">
|
||||
<button @click="linkIdToDelete = s.id; showDeleteModal = true" class="button is-danger icon-only">
|
||||
<button @click="() => {linkIdToDelete = s.id; showDeleteModal = true}" class="button is-danger icon-only">
|
||||
<span class="icon">
|
||||
<icon icon="trash-alt"/>
|
||||
</span>
|
||||
@ -106,6 +106,7 @@
|
||||
import LinkShareModel from '../../models/linkShare'
|
||||
|
||||
import copy from 'copy-to-clipboard'
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'linkSharing',
|
||||
@ -138,6 +139,9 @@
|
||||
this.load()
|
||||
}
|
||||
},
|
||||
computed: mapState({
|
||||
frontendUrl: state => state.config.frontendUrl,
|
||||
}),
|
||||
methods: {
|
||||
load() {
|
||||
// If listId == 0 the list on the calling component wasn't already loaded, so we just bail out here
|
||||
@ -183,7 +187,7 @@
|
||||
copy(text)
|
||||
},
|
||||
getShareLink(hash) {
|
||||
return this.$config.frontend_url + 'share/' + hash + '/auth'
|
||||
return this.frontendUrl + 'share/' + hash + '/auth'
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import auth from '../../auth'
|
||||
import router from '../../router'
|
||||
|
||||
export default {
|
||||
@ -25,7 +24,7 @@
|
||||
},
|
||||
methods: {
|
||||
auth() {
|
||||
auth.linkShareAuth(this.$route.params.share)
|
||||
this.$store.dispatch('auth/linkShareAuth', this.$route.params.share)
|
||||
.then((r) => {
|
||||
this.loading = false
|
||||
router.push({name: 'list.list', params: {listId: r.list_id}})
|
||||
|
@ -42,7 +42,7 @@
|
||||
<template v-if="shareType === 'user'">
|
||||
<td>{{s.username}}</td>
|
||||
<td>
|
||||
<template v-if="s.id === currentUser.id">
|
||||
<template v-if="s.id === userInfo.id">
|
||||
<b class="is-success">You</b>
|
||||
</template>
|
||||
</td>
|
||||
@ -105,8 +105,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import auth from '../../auth'
|
||||
import multiselect from 'vue-multiselect'
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
import UserNamespaceService from '../../services/userNamespace'
|
||||
import UserNamespaceModel from '../../models/userNamespace'
|
||||
@ -156,7 +156,6 @@
|
||||
rights: rights,
|
||||
selectedRight: rights.READ,
|
||||
|
||||
currentUser: auth.user.infos,
|
||||
typeString: '',
|
||||
sharables: [], // This holds either teams or users who this namepace or list is shared with
|
||||
showDeleteModal: false,
|
||||
@ -165,6 +164,9 @@
|
||||
components: {
|
||||
multiselect
|
||||
},
|
||||
computed: mapState({
|
||||
userInfo: state => state.auth.info
|
||||
}),
|
||||
created() {
|
||||
|
||||
if (this.shareType === 'user') {
|
||||
|
@ -39,7 +39,7 @@
|
||||
</div>
|
||||
<div class="media comment">
|
||||
<figure class="media-left">
|
||||
<img class="image is-avatar" :src="user.infos.getAvatarUrl(48)" alt="" width="48" height="48"/>
|
||||
<img class="image is-avatar" :src="userAvatar" alt="" width="48" height="48"/>
|
||||
</figure>
|
||||
<div class="media-content">
|
||||
<div class="form">
|
||||
@ -67,7 +67,6 @@
|
||||
<script>
|
||||
import TaskCommentService from '../../../services/taskComment'
|
||||
import TaskCommentModel from '../../../models/taskComment'
|
||||
import auth from '../../../auth'
|
||||
|
||||
export default {
|
||||
name: 'comments',
|
||||
@ -80,7 +79,6 @@
|
||||
data() {
|
||||
return {
|
||||
comments: [],
|
||||
user: auth.user,
|
||||
|
||||
showDeleteModal: false,
|
||||
commentToDelete: TaskCommentModel,
|
||||
@ -107,6 +105,11 @@
|
||||
this.loadComments()
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
userAvatar() {
|
||||
return this.$store.state.auth.info.getAvatarUrl(48)
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
loadComments() {
|
||||
this.taskCommentService.getAll({taskId: this.taskId})
|
||||
|
@ -107,7 +107,7 @@
|
||||
<tr v-for="m in team.members" :key="m.id">
|
||||
<td>{{m.username}}</td>
|
||||
<td>
|
||||
<template v-if="m.id === user.infos.id">
|
||||
<template v-if="m.id === userInfo.id">
|
||||
<b class="is-success">You</b>
|
||||
</template>
|
||||
</td>
|
||||
@ -127,7 +127,7 @@
|
||||
</td>
|
||||
<td class="actions" v-if="userIsAdmin">
|
||||
<button @click="toggleUserType(m)" class="button buttonright is-primary"
|
||||
v-if="m.id !== user.infos.id">
|
||||
v-if="m.id !== userInfo.id">
|
||||
Make
|
||||
<template v-if="!m.admin">
|
||||
Admin
|
||||
@ -137,7 +137,7 @@
|
||||
</template>
|
||||
</button>
|
||||
<button @click="() => {member = m; showUserDeleteModal = true}" class="button is-danger"
|
||||
v-if="m.id !== user.infos.id">
|
||||
v-if="m.id !== userInfo.id">
|
||||
<span class="icon is-small">
|
||||
<icon icon="trash-alt"/>
|
||||
</span>
|
||||
@ -173,9 +173,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import auth from '../../auth'
|
||||
import router from '../../router'
|
||||
import multiselect from 'vue-multiselect'
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
import TeamService from '../../services/team'
|
||||
import TeamModel from '../../models/team'
|
||||
@ -196,7 +196,6 @@
|
||||
|
||||
showDeleteModal: false,
|
||||
showUserDeleteModal: false,
|
||||
user: auth.user,
|
||||
userIsAdmin: false,
|
||||
|
||||
newMember: UserModel,
|
||||
@ -209,12 +208,6 @@
|
||||
components: {
|
||||
multiselect,
|
||||
},
|
||||
beforeMount() {
|
||||
// Check if the user is already logged in, if so, redirect him to the homepage
|
||||
if (!auth.user.authenticated) {
|
||||
router.push({name: 'home'})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.teamService = new TeamService()
|
||||
this.teamMemberService = new TeamMemberService()
|
||||
@ -225,9 +218,11 @@
|
||||
// call again the method if the route changes
|
||||
'$route': 'loadTeam'
|
||||
},
|
||||
computed: mapState({
|
||||
userInfo: state => state.auth.info,
|
||||
}),
|
||||
methods: {
|
||||
loadTeam() {
|
||||
// this.member = new TeamMemberModel({teamId: this.teamId})
|
||||
this.team = new TeamModel({id: this.teamId})
|
||||
this.teamService.get(this.team)
|
||||
.then(response => {
|
||||
@ -235,7 +230,7 @@
|
||||
let members = response.members
|
||||
for (const m in members) {
|
||||
members[m].teamId = this.teamId
|
||||
if (members[m].id === this.user.infos.id && members[m].admin) {
|
||||
if (members[m].id === this.userInfo.id && members[m].admin) {
|
||||
this.userIsAdmin = true
|
||||
}
|
||||
}
|
||||
|
@ -18,8 +18,6 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import auth from '../../auth'
|
||||
import router from '../../router'
|
||||
import TeamService from '../../services/team'
|
||||
|
||||
export default {
|
||||
@ -30,12 +28,6 @@
|
||||
teams: [],
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
// Check if the user is already logged in, if so, redirect him to the homepage
|
||||
if (!auth.user.authenticated) {
|
||||
router.push({name: 'home'})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.teamService = new TeamService()
|
||||
this.loadTeams()
|
||||
|
@ -32,10 +32,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import auth from '../../auth'
|
||||
import router from '../../router'
|
||||
import TeamModel from '../../models/team'
|
||||
import TeamService from '../../services/team'
|
||||
import {IS_FULLPAGE} from '../../store/mutation-types'
|
||||
|
||||
export default {
|
||||
name: "NewTeam",
|
||||
@ -46,16 +46,10 @@
|
||||
showError: false,
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
// Check if the user is already logged in, if so, redirect him to the homepage
|
||||
if (!auth.user.authenticated) {
|
||||
router.push({name: 'home'})
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.teamService = new TeamService()
|
||||
this.team = new TeamModel()
|
||||
this.$parent.setFullPage();
|
||||
this.$store.commit(IS_FULLPAGE, true)
|
||||
},
|
||||
methods: {
|
||||
newTeam() {
|
||||
|
@ -9,31 +9,61 @@
|
||||
<div class="field">
|
||||
<label class="label" for="username">Username</label>
|
||||
<div class="control">
|
||||
<input v-focus type="text" id="username" class="input" name="username" placeholder="e.g. frederick" ref="username" required/>
|
||||
<input
|
||||
v-focus type="text"
|
||||
id="username"
|
||||
class="input"
|
||||
name="username"
|
||||
placeholder="e.g. frederick"
|
||||
ref="username"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field">
|
||||
<label class="label" for="password">Password</label>
|
||||
<div class="control">
|
||||
<input type="password" class="input" id="password" name="password" placeholder="e.g. ••••••••••••" ref="password" required/>
|
||||
<input
|
||||
type="password"
|
||||
class="input"
|
||||
id="password"
|
||||
name="password"
|
||||
placeholder="e.g. ••••••••••••"
|
||||
ref="password"
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field" v-if="needsTotpPasscode">
|
||||
<label class="label" for="totpPasscode">Two Factor Authentication Code</label>
|
||||
<div class="control">
|
||||
<input type="text" class="input" id="totpPasscode" placeholder="e.g. 123456" ref="totpPasscode" required v-focus/>
|
||||
<input
|
||||
type="text"
|
||||
class="input"
|
||||
id="totpPasscode"
|
||||
placeholder="e.g. 123456"
|
||||
ref="totpPasscode"
|
||||
required
|
||||
v-focus
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="field is-grouped">
|
||||
<div class="control is-expanded">
|
||||
<button type="submit" class="button is-primary" v-bind:class="{ 'is-loading': loading}">Login
|
||||
</button>
|
||||
<router-link :to="{ name: 'register' }" class="button" v-if="registrationEnabled">Register
|
||||
</router-link>
|
||||
</div>
|
||||
<div class="control">
|
||||
<button type="submit" class="button is-primary" v-bind:class="{ 'is-loading': loading}">Login</button>
|
||||
<router-link :to="{ name: 'register' }" class="button">Register</router-link>
|
||||
<router-link :to="{ name: 'getPasswordReset' }" class="reset-password-link">Reset your password</router-link>
|
||||
<router-link :to="{ name: 'getPasswordReset' }" class="reset-password-link">Reset your
|
||||
password
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notification is-danger" v-if="errorMsg">
|
||||
{{ errorMsg }}
|
||||
<div class="notification is-danger" v-if="errorMessage">
|
||||
{{ errorMessage }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@ -41,18 +71,17 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import auth from '../../auth'
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
import router from '../../router'
|
||||
import {HTTP} from '../../http-common'
|
||||
import message from '../../message'
|
||||
import {ERROR_MESSAGE, LOADING} from '../../store/mutation-types'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
errorMsg: '',
|
||||
confirmedEmailSuccess: false,
|
||||
loading: false,
|
||||
needsTotpPasscode: false,
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
@ -69,19 +98,25 @@
|
||||
})
|
||||
.catch(e => {
|
||||
cancel()
|
||||
this.errorMsg = e.response.data.message
|
||||
this.$store.commit(ERROR_MESSAGE, e.response.data.message)
|
||||
})
|
||||
}
|
||||
|
||||
// Check if the user is already logged in, if so, redirect him to the homepage
|
||||
if (auth.user.authenticated) {
|
||||
if (this.authenticated) {
|
||||
router.push({name: 'home'})
|
||||
}
|
||||
},
|
||||
computed: mapState({
|
||||
registrationEnabled: state => state.config.registrationEnabled,
|
||||
loading: LOADING,
|
||||
errorMessage: ERROR_MESSAGE,
|
||||
needsTotpPasscode: state => state.auth.needsTotpPasscode,
|
||||
authenticated: state => state.auth.authenticated,
|
||||
}),
|
||||
methods: {
|
||||
submit() {
|
||||
this.loading = true
|
||||
this.errorMsg = ''
|
||||
this.$store.commit(ERROR_MESSAGE, '')
|
||||
// Some browsers prevent Vue bindings from working with autofilled values.
|
||||
// To work around this, we're manually getting the values here instead of relying on vue bindings.
|
||||
// For more info, see https://kolaente.dev/vikunja/frontend/issues/78
|
||||
@ -90,11 +125,15 @@
|
||||
password: this.$refs.password.value,
|
||||
}
|
||||
|
||||
if(this.needsTotpPasscode) {
|
||||
if (this.needsTotpPasscode) {
|
||||
credentials.totpPasscode = this.$refs.totpPasscode.value
|
||||
}
|
||||
|
||||
auth.login(this, credentials, 'home')
|
||||
this.$store.dispatch('auth/login', credentials)
|
||||
.then(() => {
|
||||
router.push({name: 'home'})
|
||||
})
|
||||
.catch(() => {})
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -105,7 +144,7 @@
|
||||
margin: 0 0.4em 0 0;
|
||||
}
|
||||
|
||||
.reset-password-link{
|
||||
.reset-password-link {
|
||||
display: inline-block;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
@ -37,8 +37,8 @@
|
||||
<div class="notification is-info" v-if="loading">
|
||||
Loading...
|
||||
</div>
|
||||
<div class="notification is-danger" v-if="errorMsg !== ''">
|
||||
{{ errorMsg }}
|
||||
<div class="notification is-danger" v-if="errorMessage !== ''">
|
||||
{{ errorMessage }}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@ -46,8 +46,9 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import auth from '../../auth'
|
||||
import router from '../../router'
|
||||
import {mapState} from 'vuex'
|
||||
import {ERROR_MESSAGE, LOADING} from '../../store/mutation-types'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
@ -58,35 +59,37 @@
|
||||
password: '',
|
||||
password2: '',
|
||||
},
|
||||
errorMsg: '',
|
||||
loading: false
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
// Check if the user is already logged in, if so, redirect him to the homepage
|
||||
if (auth.user.authenticated) {
|
||||
if (this.authenticated) {
|
||||
router.push({name: 'home'})
|
||||
}
|
||||
},
|
||||
computed: mapState({
|
||||
authenticated: state => state.auth.authenticated,
|
||||
loading: LOADING,
|
||||
errorMessage: ERROR_MESSAGE,
|
||||
}),
|
||||
methods: {
|
||||
submit() {
|
||||
this.loading = true
|
||||
|
||||
this.errorMsg = ''
|
||||
this.$store.commit(LOADING, true)
|
||||
this.$store.commit(ERROR_MESSAGE, '')
|
||||
|
||||
if (this.credentials.password2 !== this.credentials.password) {
|
||||
this.loading = false
|
||||
this.errorMsg = 'Passwords don\'t match.'
|
||||
this.$store.commit(ERROR_MESSAGE, 'Passwords don\'t match.')
|
||||
this.$store.commit(LOADING, false)
|
||||
return
|
||||
}
|
||||
|
||||
let credentials = {
|
||||
const credentials = {
|
||||
username: this.credentials.username,
|
||||
email: this.credentials.email,
|
||||
password: this.credentials.password
|
||||
}
|
||||
|
||||
auth.register(this, credentials, 'home')
|
||||
this.$store.dispatch('auth/register', credentials)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user