added loading utilities for every view

This commit is contained in:
Tim Gröger 2020-01-23 23:25:21 +01:00 committed by crimsen
parent 3bf0467726
commit ba5a50c35f
16 changed files with 2211 additions and 2032 deletions

4012
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,12 @@
<template> <template>
<div> <div>
<v-container>
<AddAmountSkeleton v-if="loading" />
</v-container>
<div v-for="user in users" :key="users.indexOf(user)"> <div v-for="user in users" :key="users.indexOf(user)">
<div v-if="isFiltered(user)"> <div v-if="isFiltered(user)">
<v-container> <v-container>
<v-card> <v-card :loading="user.loading">
<v-list-item> <v-list-item>
<v-list-item-title class="title" <v-list-item-title class="title"
>{{ user.firstname }} {{ user.lastname }}</v-list-item-title >{{ user.firstname }} {{ user.lastname }}</v-list-item-title
@ -117,9 +120,11 @@
<script> <script>
import { mapGetters, mapActions } from 'vuex' import { mapGetters, mapActions } from 'vuex'
import AddAmountSkeleton from '../user/Skeleton/AddAmountSkeleton'
export default { export default {
name: 'CreditLists', name: 'CreditLists',
components: { AddAmountSkeleton },
props: {}, props: {},
data() { data() {
return { return {
@ -151,7 +156,8 @@ export default {
computed: { computed: {
...mapGetters({ ...mapGetters({
users: 'barUsers/users', users: 'barUsers/users',
filter: 'barUsers/filter' filter: 'barUsers/filter',
loading: 'barUsers/usersLoading'
}) })
} }
} }

View File

@ -13,6 +13,7 @@
item-text="fullName" item-text="fullName"
prepend-inner-icon="search" prepend-inner-icon="search"
full-width full-width
:loading="loading"
:search-input.sync="filter" :search-input.sync="filter"
/> />
<v-btn text @click="addUser">Hinzufügen</v-btn> <v-btn text @click="addUser">Hinzufügen</v-btn>
@ -48,7 +49,10 @@ export default {
} }
}, },
computed: { computed: {
...mapGetters({ allUsers: 'barUsers/allUsers' }) ...mapGetters({
allUsers: 'barUsers/allUsers',
loading: 'barUsers/allUsersLoading'
})
}, },
watch: { watch: {
filter(val) { filter(val) {

View File

@ -27,6 +27,7 @@
item-text="fullName" item-text="fullName"
prepend-inner-icon="search" prepend-inner-icon="search"
full-width full-width
:loading="allUsersLoading"
:search-input.sync="filter" :search-input.sync="filter"
/> />
<v-btn <v-btn
@ -62,10 +63,12 @@
</v-expand-transition> </v-expand-transition>
</v-card> </v-card>
</v-expand-transition> </v-expand-transition>
<TableSkeleton v-if="loading" />
<div v-for="user in users" :key="users.indexOf(user)"> <div v-for="user in users" :key="users.indexOf(user)">
<v-card <v-card
v-if="user.creditList[year] && isFiltered(user)" v-if="user.creditList[year] && isFiltered(user)"
style="margin-top: 3px" style="margin-top: 3px"
:loading="user.loading"
> >
<v-card-title>{{ user.lastname }}, {{ user.firstname }}</v-card-title> <v-card-title>{{ user.lastname }}, {{ user.firstname }}</v-card-title>
<Table v-bind:user="user" v-bind:year="year" /> <Table v-bind:user="user" v-bind:year="year" />
@ -206,9 +209,10 @@
<script> <script>
import Table from './Table' import Table from './Table'
import { mapGetters, mapActions } from 'vuex' import { mapGetters, mapActions } from 'vuex'
import TableSkeleton from './Skeleton/TableSkeleton'
export default { export default {
name: 'Overview', name: 'Overview',
components: { Table }, components: { TableSkeleton, Table },
props: {}, props: {},
data() { data() {
return { return {
@ -369,7 +373,9 @@ export default {
errorMails: 'finanzerUsers/errorMails', errorMails: 'finanzerUsers/errorMails',
year: 'finanzerUsers/year', year: 'finanzerUsers/year',
years: 'finanzerUsers/years', years: 'finanzerUsers/years',
months: 'finanzerUsers/months' months: 'finanzerUsers/months',
loading: 'finanzerUsers/usersLoading',
allUsersLoading: 'finanzerUsers/allUsersLoading'
}) })
} }
} }

View File

@ -4,8 +4,10 @@
<v-card-title> <v-card-title>
<v-skeleton-loader type="heading" /> <v-skeleton-loader type="heading" />
</v-card-title> </v-card-title>
<v-skeleton-loader type="table-thead" /> <v-container>
<v-skeleton-loader type="table-row-divider@3" /> <v-skeleton-loader type="table-thead"/>
<v-skeleton-loader type="table-row-divider@3"/>
</v-container>
<v-container fluid> <v-container fluid>
<v-row align="start" align-content="start"> <v-row align="start" align-content="start">
<v-col> <v-col>
@ -37,8 +39,9 @@
</v-row> </v-row>
<v-card outlined> <v-card outlined>
<v-row> <v-row>
<v-skeleton-loader type="list-item" /> <v-card-title>
<v-spacer /> <v-skeleton-loader style="margin: 3px; margin-left: 10px" type="chip"/>
</v-card-title>
</v-row> </v-row>
</v-card> </v-card>
</v-col> </v-col>

View File

@ -1,6 +1,7 @@
<template> <template>
<v-container v-if="user"> <v-container >
<v-card> <AddAmountSkeleton v-if="loading" />
<v-card v-if="!loading">
<v-list-item> <v-list-item>
<v-list-item-title class="title" <v-list-item-title class="title"
>{{ user.firstname }} {{ user.lastname }}</v-list-item-title >{{ user.firstname }} {{ user.lastname }}</v-list-item-title
@ -99,8 +100,10 @@
<script> <script>
import {mapGetters, mapActions} from 'vuex' import {mapGetters, mapActions} from 'vuex'
import AddAmountSkeleton from './Skeleton/AddAmountSkeleton'
export default { export default {
name: 'AddAmount', name: 'AddAmount',
components: { AddAmountSkeleton },
data() { data() {
return { return {
color: 'green accent-4' color: 'green accent-4'
@ -123,7 +126,8 @@ export default {
computed: { computed: {
...mapGetters({ ...mapGetters({
user: 'user/user', user: 'user/user',
year: 'user/year' year: 'user/year',
loading: 'user/loading'
}), }),
} }
} }

View File

@ -9,10 +9,12 @@
style="margin-top: 3px" style="margin-top: 3px"
append-icon="search" append-icon="search"
outlined outlined
type="number"
:rules="[isNumber]" :rules="[isNumber]"
></v-text-field> ></v-text-field>
</v-toolbar-items> </v-toolbar-items>
</v-toolbar> </v-toolbar>
<CreditOverviewSkeleton v-if="loading" />
<div v-for="year in years" :key="years.indexOf(year)"> <div v-for="year in years" :key="years.indexOf(year)">
<v-card style="margin-top: 3px" v-if="isFiltered(year)"> <v-card style="margin-top: 3px" v-if="isFiltered(year)">
<v-card-title>{{ year }}</v-card-title> <v-card-title>{{ year }}</v-card-title>
@ -67,9 +69,10 @@
<script> <script>
import { mapGetters } from 'vuex' import { mapGetters } from 'vuex'
import Table from '../finanzer/Table' import Table from '../finanzer/Table'
import CreditOverviewSkeleton from './Skeleton/CreditOverviewSkeleton'
export default { export default {
name: 'CreditOverview', name: 'CreditOverview',
components: { Table }, components: { CreditOverviewSkeleton, Table },
data() { data() {
return { return {
isNumber: value => Number.isInteger(parseInt(value === '' ? 0 : value)) || "Muss eine Zahl sein.", isNumber: value => Number.isInteger(parseInt(value === '' ? 0 : value)) || "Muss eine Zahl sein.",
@ -89,7 +92,8 @@ export default {
}, },
computed: { computed: {
...mapGetters({ ...mapGetters({
user: 'user/user' user: 'user/user',
loading: 'user/loading'
}), }),
years() { years() {
let years = [] let years = []

View File

@ -0,0 +1,50 @@
<template>
<v-card>
<v-card-title>
<v-skeleton-loader type="heading" />
</v-card-title>
<v-card-text>
<v-row>
<v-col cols="10">
<v-row>
<v-col>
<v-skeleton-loader type="button" />
</v-col>
<v-col>
<v-skeleton-loader type="button" />
</v-col>
<v-col>
<v-skeleton-loader type="button" />
</v-col>
</v-row>
<v-row>
<v-col>
<v-skeleton-loader type="button" />
</v-col>
<v-col>
<v-skeleton-loader type="button" />
</v-col>
<v-col>
<v-skeleton-loader type="button" />
</v-col>
</v-row>
</v-col>
<v-col align-self="center">
<v-row>
<v-list-item>
<v-skeleton-loader type="chip" />
</v-list-item>
</v-row>
</v-col>
</v-row>
</v-card-text>
</v-card>
</template>
<script>
export default {
name: 'AddAmountSkeleton'
}
</script>
<style scoped></style>

View File

@ -0,0 +1,35 @@
<template>
<v-card style="margin-top: 3px">
<v-card-title><v-skeleton-loader type="heading"/></v-card-title>
<v-container>
<v-skeleton-loader type="table-thead" />
<v-skeleton-loader type="table-row-divider@3" />
</v-container>
<v-container fluid>
<v-col>
<v-row>
<v-col>
<v-skeleton-loader type="chip" />
</v-col>
<v-col>
<v-skeleton-loader type="chip" />
</v-col>
<v-col>
<v-skeleton-loader type="chip" />
</v-col>
<v-col>
<v-skeleton-loader type="chip" />
</v-col>
</v-row>
</v-col>
</v-container>
</v-card>
</template>
<script>
export default {
name: 'CreditOverviewSkeleton'
}
</script>
<style scoped></style>

View File

@ -9,7 +9,7 @@
<v-card-text> <v-card-text>
<v-expand-transition> <v-expand-transition>
<v-row align="center" justify="center" v-if="day.loading"> <v-row align="center" justify="center" v-if="day.loading">
<v-progress-circular indeterminate color="black" /> <v-progress-circular indeterminate color="grey" />
</v-row> </v-row>
</v-expand-transition> </v-expand-transition>
<v-expand-transition> <v-expand-transition>

View File

@ -4,7 +4,9 @@ import url from '@/plugins/routes'
const state = { const state = {
users: [], users: [],
allUsers: [], allUsers: [],
filter: '' filter: '',
usersLoading: false,
allUsersLoading: false
} }
const mutations = { const mutations = {
@ -36,12 +38,21 @@ const mutations = {
lastname: users[user].lastname, lastname: users[user].lastname,
locked: users[user].locked, locked: users[user].locked,
amount: users[user].amount, amount: users[user].amount,
type: users[user].type type: users[user].type,
loading: false
}) })
} }
} }
mutations.sortUsers(state) mutations.sortUsers(state)
}, },
updateUser: (state, data) => {
let index = state.users.indexOf(
state.users.find(a => {
return a.username === data.username
})
)
if (data.loading !== undefined) state.users[index].loading = data.loading
},
sortUsers: state => { sortUsers: state => {
state.users = state.users.sort((a, b) => { state.users = state.users.sort((a, b) => {
if (a.lastname > b.lastname) return 1 if (a.lastname > b.lastname) return 1
@ -53,12 +64,19 @@ const mutations = {
}, },
setFilter: (state, filter) => { setFilter: (state, filter) => {
state.filter = filter state.filter = filter
},
setUsersLoading: (state, value) => {
state.usersLoading = value
},
setAllUsersLoading: (state, value) => {
state.allUsersLoading = value
} }
} }
const actions = { const actions = {
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
async getUsers({ commit, rootState, dispatch }) { async getUsers({ commit, rootState, dispatch }) {
commit('setUsersLoading', true)
try { try {
const response = await axios.get(url.bar, { const response = await axios.get(url.bar, {
headers: { Token: rootState.login.user.accessToken } headers: { Token: rootState.login.user.accessToken }
@ -68,8 +86,10 @@ const actions = {
if (e.response) if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true }) if (e.response.status === 401) dispatch('logout', null, { root: true })
} }
commit('setUsersLoading', false)
}, },
async addAmount({ commit, rootState, dispatch }, data) { async addAmount({ commit, rootState, dispatch }, data) {
commit('updateUser', {username: data.username, loading: true})
try { try {
const response = await axios.post( const response = await axios.post(
url.barAddAmount, url.barAddAmount,
@ -81,8 +101,10 @@ const actions = {
if (e.response) if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true }) if (e.response.status === 401) dispatch('logout', null, { root: true })
} }
commit('updateUser', {username: data.username, loading: false})
}, },
async addCreditList({ commit, rootState, dispatch }, data) { async addCreditList({ commit, rootState, dispatch }, data) {
commit('updateUser', {username: data.username, loading: true})
try { try {
const response = await axios.post( const response = await axios.post(
url.barGetUser, url.barGetUser,
@ -94,8 +116,10 @@ const actions = {
if (e.response) if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true }) if (e.response.status === 401) dispatch('logout', null, { root: true })
} }
commit('updateUser', {username: data.username, loading: false})
}, },
async getAllUsers({ commit, rootState, dispatch }) { async getAllUsers({ commit, rootState, dispatch }) {
commit('setAllUsersLoading', true)
try { try {
const response = await axios.post( const response = await axios.post(
url.searchUser, url.searchUser,
@ -107,6 +131,7 @@ const actions = {
if (e.response) if (e.response)
if (e.response.data === 401) dispatch('logout', null, { root: true }) if (e.response.data === 401) dispatch('logout', null, { root: true })
} }
commit('setAllUsersLoading', false)
}, },
setFilter({ commit }, data) { setFilter({ commit }, data) {
commit('setFilter', data) commit('setFilter', data)
@ -122,7 +147,13 @@ const getters = {
}, },
filter: state => { filter: state => {
return state.filter return state.filter
} },
usersLoading: state => {
return state.usersLoading
},
allUsersLoading: state => {
return state.allUsersLoading
},
} }
export default { export default {

View File

@ -75,7 +75,8 @@ const mutations = {
locked: users[user].locked, locked: users[user].locked,
autoLock: users[user].autoLock, autoLock: users[user].autoLock,
creditList: list, creditList: list,
expand: false expand: false,
loading: false
}) })
} }
} }
@ -204,6 +205,7 @@ const mutations = {
if (data.locked !== undefined) state.users[index].locked = data.locked if (data.locked !== undefined) state.users[index].locked = data.locked
if (data.limit !== undefined) state.users[index].limit = data.limit if (data.limit !== undefined) state.users[index].limit = data.limit
if (data.autoLock !== undefined) state.users[index].autoLock = data.autoLock if (data.autoLock !== undefined) state.users[index].autoLock = data.autoLock
if (data.loading !== undefined) state.users[index].loading = data.loading
}, },
setMails: (state, data) => { setMails: (state, data) => {
state.errorMails = data state.errorMails = data
@ -265,6 +267,7 @@ const actions = {
commit('setActiveUser', username) commit('setActiveUser', username)
}, },
async addAmount({ commit, rootState, dispatch }, data) { async addAmount({ commit, rootState, dispatch }, data) {
commit('updateUsers', {username: data.user.username, loading: true})
try { try {
const response = await axios.post( const response = await axios.post(
url.finanzerAddAmount, url.finanzerAddAmount,
@ -288,8 +291,10 @@ const actions = {
if (err.response.status === 401) if (err.response.status === 401)
dispatch('logout', null, { root: true }) dispatch('logout', null, { root: true })
} }
commit('updateUsers', {username: data.user.username, loading: false})
}, },
async addCredit({ commit, rootState, dispatch }, data) { async addCredit({ commit, rootState, dispatch }, data) {
commit('updateUsers', {username: data.user.username, loading: true})
try { try {
const response = await axios.post( const response = await axios.post(
url.finanzerAddCredit, url.finanzerAddCredit,
@ -313,6 +318,7 @@ const actions = {
if (err.response.status === 401) if (err.response.status === 401)
dispatch('logout', null, { root: true }) dispatch('logout', null, { root: true })
} }
commit('updateUsers', {username: data.user.username, loading: false})
}, },
async doLock({ commit, rootState, dispatch }, data) { async doLock({ commit, rootState, dispatch }, data) {
try { try {

View File

@ -5,6 +5,8 @@ import url from '@/plugins/routes'
const state = { const state = {
user: { user: {
username: null, username: null,
firstname: null,
lastname: null,
accessToken: null, accessToken: null,
group: null group: null
}, },
@ -30,12 +32,16 @@ const mutations = {
state.user.username = data.username state.user.username = data.username
state.user.accessToken = data.accessToken state.user.accessToken = data.accessToken
state.user.group = data.group state.user.group = data.group
state.user.firstname = data.firstname
state.user.lastname = data.lastname
} }
}, },
logout(state) { logout(state) {
state.user.accessToken = null state.user.accessToken = null
state.user.username = null state.user.username = null
state.user.group = null state.user.group = null
state.user.firstname = null
state.user.lastname = null
} }
} }
@ -44,12 +50,15 @@ const actions = {
commit('loginStart') commit('loginStart')
try { try {
const response = await axios.post(url.login, { ...loginData }) const response = await axios.post(url.login, { ...loginData })
console.log(response.data)
localStorage.setItem( localStorage.setItem(
'user', 'user',
JSON.stringify({ JSON.stringify({
username: response.data.username, username: response.data.username,
accessToken: response.data.token, accessToken: response.data.token,
group: response.data.group group: response.data.group,
firstname: response.data.firstname,
lastname: response.data.lastname
}) })
) )
commit('loginStop', null) commit('loginStop', null)
@ -66,7 +75,9 @@ const actions = {
commit('updateAccessToken', { commit('updateAccessToken', {
username: null, username: null,
accessToken: null, accessToken: null,
group: null group: null,
firstname: null,
lastname: null
}) })
} }
}, },
@ -84,6 +95,9 @@ const actions = {
} }
const getters = { const getters = {
loggingIn: state => {
return state.loggingIn
},
getGroup: state => { getGroup: state => {
return state.user.group return state.user.group
}, },
@ -122,6 +136,9 @@ const getters = {
}, },
isLoggedIn: state => { isLoggedIn: state => {
return state.user.accessToken ? true : false return state.user.accessToken ? true : false
},
user: state => {
return state.user
} }
} }

View File

@ -3,7 +3,8 @@ import url from '@/plugins/routes'
const state = { const state = {
user: null, user: null,
creditList: [] creditList: [],
loading: false
} }
const mutations = { const mutations = {
@ -117,11 +118,15 @@ const mutations = {
sum.nov_amount + sum.nov_amount +
sum.dez_amount sum.dez_amount
return sum return sum
},
setLoading(state, value) {
state.loading = value
} }
} }
const actions = { const actions = {
async getUser({ commit, rootState, dispatch }) { async getUser({ commit, rootState, dispatch }) {
commit("setLoading", true)
try { try {
const response = await axios.get(url.userMain, { const response = await axios.get(url.userMain, {
headers: { Token: rootState.login.user.accessToken } headers: { Token: rootState.login.user.accessToken }
@ -131,6 +136,7 @@ const actions = {
if (e.response) if (e.response)
if (e.response.status === 401) dispatch('logout', null, { root: true }) if (e.response.status === 401) dispatch('logout', null, { root: true })
} }
commit("setLoading", false)
}, },
async addAmount({ commit, rootState, dispatch }, amount) { async addAmount({ commit, rootState, dispatch }, amount) {
try { try {
@ -158,6 +164,9 @@ const getters = {
if (currentYear > year) year = currentYear if (currentYear > year) year = currentYear
} }
return year return year
},
loading: state => {
return state.loading
} }
} }

View File

@ -37,6 +37,9 @@
@input="resetLoginError" @input="resetLoginError"
/> />
</v-form> </v-form>
<div class="text-center">
<v-progress-circular indeterminate v-if="loggingIn" />
</div>
</v-card-text> </v-card-text>
<v-alert v-if="loginError" dense type="error">{{ <v-alert v-if="loginError" dense type="error">{{
loginError loginError
@ -74,7 +77,7 @@ export default {
} }
}, },
methods: mapActions(['doLogin', 'resetLoginError']), methods: mapActions(['doLogin', 'resetLoginError']),
computed: mapGetters(['loginError']) computed: mapGetters(['loginError', 'loggingIn'])
} }
</script> </script>

View File

@ -14,14 +14,14 @@
<v-list-item-icon> <v-list-item-icon>
<v-icon>person</v-icon> <v-icon>person</v-icon>
</v-list-item-icon> </v-list-item-icon>
<v-list-item-title>Account</v-list-item-title> <v-list-item-title>{{user.firstname}} {{user.lastname}}</v-list-item-title>
</v-list-item> </v-list-item>
<v-list-item v-if="isBar" class="title" link to="/main/bar/geruecht"> <v-list-item v-if="isBar" class="title" link to="/main/bar/geruecht">
<v-list-item-icon> <v-list-item-icon>
<v-icon>local_bar</v-icon> <v-icon>local_bar</v-icon>
</v-list-item-icon> </v-list-item-icon>
<v-list-item-title> <v-list-item-title>
Gerüchte Bar
</v-list-item-title> </v-list-item-title>
</v-list-item> </v-list-item>
<v-list-item v-if="isFinanzer" class="title" link to="/main/finanzer/overview"> <v-list-item v-if="isFinanzer" class="title" link to="/main/finanzer/overview">
@ -70,7 +70,8 @@ export default {
isBar: 'isBar', isBar: 'isBar',
isUser: 'isUser', isUser: 'isUser',
isFinanzer: 'isFinanzer', isFinanzer: 'isFinanzer',
isLoggedIn: 'isLoggedIn' isLoggedIn: 'isLoggedIn',
user: 'user'
}) })
} }
} }