Merge pull request #512 from gradido/toaster

feat: Toaster to Display Messages
This commit is contained in:
Moriz Wahl 2021-06-14 15:57:16 +02:00 committed by GitHub
commit 9a257c2686
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 176 additions and 121 deletions

View File

@ -51,6 +51,7 @@
"nouislider": "^12.1.0",
"particles-bg-vue": "1.2.3",
"perfect-scrollbar": "^1.3.0",
"portal-vue": "^2.1.7",
"prettier": "^2.2.1",
"qrcode": "^1.4.4",
"quill": "^1.3.6",
@ -58,6 +59,7 @@
"sweetalert2": "^9.5.4",
"vee-validate": "^3.4.5",
"vue": "^2.6.11",
"vue-bootstrap-toasts": "^1.0.7",
"vue-bootstrap-typeahead": "^0.2.6",
"vue-chartjs": "^3.5.0",
"vue-cli-plugin-i18n": "^1.0.1",

View File

@ -3,6 +3,7 @@
<div class="">
<particles-bg type="custom" :config="config" :bg="true" />
<component :is="$route.meta.requiresAuth ? 'DashboardLayout' : 'AuthLayoutGDD'" />
<Toasts></Toasts>
</div>
</div>
</template>

View File

@ -98,7 +98,6 @@ const loginAPI = {
}
return apiPost(CONFIG.LOGIN_API_URL + 'updateUserInfos', payload)
},
changePassword: async (sessionId, email, password) => {
const payload = {
session_id: sessionId,

View File

@ -23,38 +23,95 @@
// Bootstrap (4.1.3) components
@import "~bootstrap/scss/root";
@import "~bootstrap/scss/reboot";
@import "~bootstrap/scss/type";
@import "~bootstrap/scss/images";
@import "~bootstrap/scss/code";
@import "~bootstrap/scss/grid";
@import "~bootstrap/scss/tables";
@import "~bootstrap/scss/forms";
@import "~bootstrap/scss/buttons";
@import "~bootstrap/scss/transitions";
@import "~bootstrap/scss/dropdown";
@import "~bootstrap/scss/alert";
@import "~bootstrap/scss/badge";
@import "~bootstrap/scss/breadcrumb";
@import "~bootstrap/scss/button-group";
@import "~bootstrap/scss/input-group";
@import "~bootstrap/scss/buttons";
@import "~bootstrap/scss/card";
@import "~bootstrap/scss/carousel";
@import "~bootstrap/scss/close";
@import "~bootstrap/scss/code";
@import "~bootstrap/scss/custom-forms";
@import "~bootstrap/scss/dropdown";
@import "~bootstrap/scss/forms";
@import "~bootstrap/scss/grid";
@import "~bootstrap/scss/images";
@import "~bootstrap/scss/input-group";
@import "~bootstrap/scss/jumbotron";
@import "~bootstrap/scss/list-group";
@import "~bootstrap/scss/media";
@import "~bootstrap/scss/modal";
@import "~bootstrap/scss/nav";
@import "~bootstrap/scss/navbar";
@import "~bootstrap/scss/card";
@import "~bootstrap/scss/breadcrumb";
@import "~bootstrap/scss/pagination";
@import "~bootstrap/scss/badge";
@import "~bootstrap/scss/jumbotron";
@import "~bootstrap/scss/alert";
@import "~bootstrap/scss/progress";
@import "~bootstrap/scss/media";
@import "~bootstrap/scss/list-group";
@import "~bootstrap/scss/close";
@import "~bootstrap/scss/modal";
@import "~bootstrap/scss/tooltip";
@import "~bootstrap/scss/popover";
@import "~bootstrap/scss/carousel";
@import "~bootstrap/scss/utilities";
@import "~bootstrap/scss/print";
@import "~bootstrap/scss/progress";
@import "~bootstrap/scss/reboot";
@import "~bootstrap/scss/root";
@import "~bootstrap/scss/tables";
@import "~bootstrap/scss/toasts";
@import "~bootstrap/scss/tooltip";
@import "~bootstrap/scss/transitions";
@import "~bootstrap/scss/type";
@import "~bootstrap/scss/utilities";
@import "~bootstrap/scss/variables";
// Utilities
@import "~bootstrap/scss/utilities/align";
@import "~bootstrap/scss/utilities/background";
@import "~bootstrap/scss/utilities/borders";
@import "~bootstrap/scss/utilities/clearfix";
@import "~bootstrap/scss/utilities/display";
@import "~bootstrap/scss/utilities/embed";
@import "~bootstrap/scss/utilities/flex";
@import "~bootstrap/scss/utilities/float";
@import "~bootstrap/scss/utilities/overflow";
@import "~bootstrap/scss/utilities/position";
@import "~bootstrap/scss/utilities/screenreaders";
@import "~bootstrap/scss/utilities/shadows";
@import "~bootstrap/scss/utilities/sizing";
@import "~bootstrap/scss/utilities/spacing";
@import "~bootstrap/scss/utilities/stretched-link";
@import "~bootstrap/scss/utilities/text";
@import "~bootstrap/scss/utilities/visibility";
// Mixins
@import "~bootstrap/scss/mixins/alert";
@import "~bootstrap/scss/mixins/badge";
@import "~bootstrap/scss/mixins/border-radius";
@import "~bootstrap/scss/mixins/box-shadow";
@import "~bootstrap/scss/mixins/breakpoints";
@import "~bootstrap/scss/mixins/buttons";
@import "~bootstrap/scss/mixins/caret";
@import "~bootstrap/scss/mixins/clearfix";
@import "~bootstrap/scss/mixins/deprecate";
@import "~bootstrap/scss/mixins/float";
@import "~bootstrap/scss/mixins/forms";
@import "~bootstrap/scss/mixins/gradients";
@import "~bootstrap/scss/mixins/grid-framework";
@import "~bootstrap/scss/mixins/grid";
@import "~bootstrap/scss/mixins/hover";
@import "~bootstrap/scss/mixins/image";
@import "~bootstrap/scss/mixins/list-group";
@import "~bootstrap/scss/mixins/lists";
@import "~bootstrap/scss/mixins/nav-divider";
@import "~bootstrap/scss/mixins/pagination";
@import "~bootstrap/scss/mixins/reset-text";
@import "~bootstrap/scss/mixins/resize";
@import "~bootstrap/scss/mixins/screen-reader";
@import "~bootstrap/scss/mixins/size";
@import "~bootstrap/scss/mixins/table-row";
@import "~bootstrap/scss/mixins/text-emphasis";
@import "~bootstrap/scss/mixins/text-hide";
@import "~bootstrap/scss/mixins/text-truncate";
@import "~bootstrap/scss/mixins/transition";
@import "~bootstrap/scss/mixins/visibility";
// Argon utilities and components

View File

@ -109,6 +109,9 @@
"chart":"Gemeinschaftsstunden Chart",
"new":"Neue Gemeinschaftsstunden eintragen",
"list":"Meine Gemeinschaftsstunden Liste"
},
"user-data": {
"change-success": "Deine Daten wurden gespeichert."
}
},
"navbar" : {

View File

@ -110,6 +110,9 @@
"chart":"Community Hours Chart",
"new":"Register new community hours",
"list":"My Community Hours List"
},
"user-data": {
"change-success": "Your data has been saved."
}
},
"navbar" : {

View File

@ -11,6 +11,10 @@ import GlobalDirectives from './globalDirectives'
// Sidebar on the right. Used as a local plugin in DashboardLayout.vue
import SideBar from '@/components/SidebarPlugin'
import PortalVue from 'portal-vue'
import VueBootstrapToasts from 'vue-bootstrap-toasts'
// vue-bootstrap
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
@ -47,8 +51,10 @@ export default {
Vue.use(GlobalDirectives)
Vue.use(SideBar)
Vue.use(Notifications)
Vue.use(PortalVue)
Vue.use(BootstrapVue)
Vue.use(IconsPlugin)
Vue.use(VueBootstrapToasts)
Vue.use(VueGoodTablePlugin)
Vue.use(VueMoment)
Vue.use(VueQrcodeReader)

View File

@ -34,7 +34,6 @@
:transactions="transactions"
:transactionCount="transactionCount"
:pending="pending"
:UserProfileTestData="UserProfileTestData"
@update-balance="updateBalance"
@update-transactions="updateTransactions"
></router-view>
@ -86,11 +85,6 @@ export default {
bookedBalance: 0,
transactionCount: 0,
pending: true,
UserProfileTestData: {
username: 'Mustermax',
desc:
'Max Mustermann seine Beschreibung. Max Mustermann seine Beschreibung. Max Mustermann seine Beschreibung. Max Mustermann seine Beschreibung. ',
},
}
},
methods: {

View File

@ -58,14 +58,12 @@ export default {
},
}
},
created() {},
methods: {
async onSubmit() {
const result = await loginAPI.sendEmail(this.form.email)
if (result.success) {
this.$router.push('/thx/password')
} else {
alert(result.result)
}
await loginAPI.sendEmail(this.form.email)
// always give success to avoid email spying
this.$router.push('/thx/password')
},
},
}

View File

@ -108,14 +108,14 @@ export default {
if (result.success) {
this.password = ''
/*
this.$store.dispatch('login', {
sessionId: result.result.data.session_id,
email: result.result.data.user.email,
})
*/
this.$store.dispatch('login', {
sessionId: result.result.data.session_id,
email: result.result.data.user.email,
})
*/
this.$router.push('/thx/reset')
} else {
alert(result.result.message)
this.$toast.error(result.result.message)
}
},
async authenticate() {
@ -126,7 +126,7 @@ export default {
this.sessionId = result.result.data.session_id
this.email = result.result.data.user.email
} else {
alert(result.result.message)
this.$toast.error(result.result.message)
}
},
},

View File

@ -1,23 +0,0 @@
import { shallowMount } from '@vue/test-utils'
import UserProfile from './UserProfile'
const localVue = global.localVue
describe('UserProfile', () => {
let wrapper
const Wrapper = () => {
return shallowMount(UserProfile, { localVue })
}
describe('shallowMount', () => {
beforeEach(() => {
wrapper = Wrapper()
})
it('renders the component', () => {
expect(wrapper.findComponent({ name: 'user-card' }).exists()).toBeTruthy()
})
})
})

View File

@ -1,28 +0,0 @@
<template>
<div>
<div class="header pb-8 pt-5 pt-lg-8 d-flex align-items-center profile-header">
<b-container fluid></b-container>
</div>
<b-container fluid class="mt--6">
<b-row>
<b-col xl="12" class="order-xl-2 mb-5">
<user-card :balance="balance"></user-card>
</b-col>
</b-row>
</b-container>
</div>
</template>
<script>
import UserCard from './UserProfile/UserCard.vue'
export default {
components: {
UserCard,
},
props: {
balance: { type: Number, default: 0 },
},
}
</script>
<style></style>

View File

@ -9,8 +9,8 @@
<b-row class="text-right">
<b-col class="mb-3">
<b-icon
v-if="editUserdata"
@click="editUserdata = !editUserdata"
v-if="showUserData"
@click="showUserData = !showUserData"
class="pointer"
icon="pencil"
>
@ -19,7 +19,7 @@
<b-icon
v-else
@click="editUserdata = !editUserdata"
@click="cancelEdit"
class="pointer"
icon="x-circle"
variant="danger"
@ -34,8 +34,8 @@
<b-col class="col-lg-3 col-md-12 col-sm-12 text-md-left text-lg-right">
<small>{{ $t('form.firstname') }}</small>
</b-col>
<b-col v-if="editUserdata" class="col-sm-10 col-md-9">
{{ $store.state.firstName }}
<b-col v-if="showUserData" class="col-sm-10 col-md-9">
{{ form.firstName }}
</b-col>
<b-col v-else class="col-md-9 col-sm-10">
<b-input type="text" v-model="form.firstName"></b-input>
@ -45,8 +45,8 @@
<b-col class="col-lg-3 col-md-12 col-sm-12 text-md-left text-lg-right">
<small>{{ $t('form.lastname') }}</small>
</b-col>
<b-col v-if="editUserdata" class="col-sm-10 col-md-9">
{{ $store.state.lastName }}
<b-col v-if="showUserData" class="col-sm-10 col-md-9">
{{ form.lastName }}
</b-col>
<b-col v-else class="col-md-9 col-sm-10">
<b-input type="text" v-model="form.lastName"></b-input>
@ -56,15 +56,15 @@
<b-col class="col-lg-3 col-md-10 col-sm-10 text-md-left text-lg-right">
<small>{{ $t('form.description') }}</small>
</b-col>
<b-col v-if="editUserdata" class="col-sm-10 col-md-9">
{{ $store.state.description }}
<b-col v-if="showUserData" class="col-sm-10 col-md-9">
{{ form.description }}
</b-col>
<b-col v-else class="col-sm-10 col-md-9">
<b-textarea rows="3" max-rows="6" v-model="form.description"></b-textarea>
</b-col>
</b-row>
<b-row class="text-right" v-if="!editUserdata">
<b-row class="text-right" v-if="!showUserData">
<b-col>
<div class="text-right" ref="submitButton">
<b-button
@ -89,12 +89,9 @@ import loginAPI from '../../../apis/loginAPI'
export default {
name: 'FormUserData',
props: {
UserProfileTestData: { type: Object },
},
data() {
return {
editUserdata: true,
showUserData: true,
sessionId: this.$store.state.sessionId,
form: {
firstName: this.$store.state.firstName,
@ -105,6 +102,12 @@ export default {
}
},
methods: {
cancelEdit() {
this.form.firstName = this.$store.state.firstName
this.form.lastName = this.$store.state.lastName
this.form.description = this.$store.state.description
this.showUserData = true
},
loadSubmitButton() {
if (
this.form.firstName !== this.$store.state.firstName ||
@ -116,7 +119,8 @@ export default {
this.loading = true
}
},
async onSubmit() {
async onSubmit(event) {
event.preventDefault()
const result = await loginAPI.updateUserInfos(
this.$store.state.sessionId,
this.$store.state.email,
@ -130,10 +134,10 @@ export default {
this.$store.commit('firstName', this.form.firstName)
this.$store.commit('lastName', this.form.lastName)
this.$store.commit('description', this.form.description)
this.editUserdata = true
alert('Deine Daten wurden gespeichert und sind geändert.')
this.showUserData = true
this.$toast.success(this.$t('site.profil.user-data.change-success'))
} else {
alert(result.result.message)
this.$toast.error(result.result.message)
}
},
},

View File

@ -73,9 +73,6 @@ export default {
},
}
},
props: {
UserProfileTestData: { type: Object },
},
methods: {
async onSubmit() {
const result = await loginAPI.changeUsernameProfile(

View File

@ -0,0 +1,38 @@
import { shallowMount } from '@vue/test-utils'
import UserProfileOverview from './UserProfileOverview'
const localVue = global.localVue
describe('UserProfileOverview', () => {
let wrapper
const mocks = {
$t: jest.fn((t) => t),
}
const Wrapper = () => {
return shallowMount(UserProfileOverview, { localVue, mocks })
}
describe('shallow Mount', () => {
beforeEach(() => {
wrapper = Wrapper()
})
it('has a user card', () => {
expect(wrapper.findComponent({ name: 'UserCard' }).exists()).toBeTruthy()
})
it('has a user data form', () => {
expect(wrapper.findComponent({ name: 'FormUserData' }).exists()).toBeTruthy()
})
it('has a user name form', () => {
expect(wrapper.findComponent({ name: 'FormUsername' }).exists()).toBeTruthy()
})
it('has a user password form', () => {
expect(wrapper.findComponent({ name: 'FormUserPasswort' }).exists()).toBeTruthy()
})
})
})

View File

@ -1,7 +1,7 @@
<template>
<b-container fluid>
<user-card :balance="balance" :transactionCount="transactionCount"></user-card>
<form-user-data :UserProfileTestData="UserProfileTestData" />
<form-user-data />
<form-username />
<form-user-passwort />
</b-container>
@ -22,7 +22,6 @@ export default {
props: {
balance: { type: Number, default: 0 },
transactionCount: { type: Number, default: 0 },
UserProfileTestData: { type: Object },
},
}
</script>

View File

@ -13268,6 +13268,11 @@ vm-browserify@^1.0.1:
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
vue-bootstrap-toasts@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/vue-bootstrap-toasts/-/vue-bootstrap-toasts-1.0.7.tgz#111c38855941e8eb0538e21f41c173e2af67dd53"
integrity sha512-JhurJOAwdNcINQ/QlT701sx0r447YTGpvtxtmZNC9pwDvEqp2I0Pyv15jS4neWwYHkA1gXB42nBsDRcWcj1hlg==
vue-bootstrap-typeahead@^0.2.6:
version "0.2.6"
resolved "https://registry.yarnpkg.com/vue-bootstrap-typeahead/-/vue-bootstrap-typeahead-0.2.6.tgz#8c1999a00bf4bf9fc906bae3a462482482cbc297"