email input component

This commit is contained in:
Moriz Wahl 2021-06-29 11:54:38 +02:00
parent f5966eb807
commit 0bde83eb75
3 changed files with 150 additions and 45 deletions

View File

@ -0,0 +1,71 @@
import { mount } from '@vue/test-utils'
import InputEmail from './InputEmail'
const localVue = global.localVue
describe('InputEmail', () => {
let wrapper
const propsData = {
name: 'input-field-name',
label: 'input-field-label',
placeholder: 'input-field-placeholder',
value: '',
}
const Wrapper = () => {
return mount(InputEmail, { localVue, propsData })
}
describe('mount', () => {
beforeEach(() => {
wrapper = Wrapper()
})
it('has an input field', () => {
expect(wrapper.find('input').exists()).toBeTruthy()
})
describe('properties', () => {
it('has the name "input-field-name"', () => {
expect(wrapper.find('input').attributes('name')).toEqual('input-field-name')
})
it('has the id "input-field-name-input-field"', () => {
expect(wrapper.find('input').attributes('id')).toEqual('input-field-name-input-field')
})
it('has the placeholder "input-field-placeholder"', () => {
expect(wrapper.find('input').attributes('placeholder')).toEqual('input-field-placeholder')
})
it('has the value ""', () => {
expect(wrapper.vm.currentValue).toEqual('')
})
it('has the label "input-field-label"', () => {
expect(wrapper.find('label').text()).toEqual('input-field-label')
})
it('has the label for "input-field-name-input-field"', () => {
expect(wrapper.find('label').attributes('for')).toEqual('input-field-name-input-field')
})
})
describe('input value changes', () => {
it('emits input with new value', async () => {
await wrapper.find('input').setValue('12')
expect(wrapper.emitted('input')).toBeTruthy()
expect(wrapper.emitted('input')).toEqual([['12']])
})
})
describe('value property changes', () => {
it('updates data model', async () => {
await wrapper.setProps({ value: 'user@example.org' })
expect(wrapper.vm.currentValue).toEqual('user@example.org')
})
})
})
})

View File

@ -0,0 +1,73 @@
<template>
<validation-provider
tag="div"
:rules="rules"
:name="name"
v-slot="{ errors, valid, validated, ariaInput, ariaMsg }"
>
<b-form-group :label="label" :label-for="labelFor">
<b-input-group>
<b-form-input
v-model="currentValue"
v-bind="ariaInput"
:id="labelFor"
:name="name"
:placeholder="placeholder"
type="email"
:state="validated ? valid : false"
trim
class="email-form-input"
></b-form-input>
<b-form-invalid-feedback v-bind="ariaMsg">
{{ errors[0] }}
</b-form-invalid-feedback>
</b-input-group>
</b-form-group>
</validation-provider>
</template>
<script>
export default {
name: 'InputEmail',
props: {
rules: {
default: () => {
return {
required: true,
email: true,
}
},
},
name: { type: String, default: 'email' },
label: { type: String, default: 'Email' },
placeholder: { type: String, default: 'Email' },
value: { required: true, type: String },
},
data() {
return {
currentValue: '',
}
},
computed: {
labelFor() {
return this.name + '-input-field'
},
},
watch: {
currentValue() {
this.$emit('input', this.currentValue)
},
value() {
if (this.value !== this.currentValue) this.currentValue = this.value
},
},
}
</script>
<style>
.email-form-input {
border-right-style: solid !important;
border-right-width: 1px !important;
padding-right: 12px !important;
border-top-right-radius: 6px !important;
border-bottom-right-radius: 6px !important;
}
</style>

View File

@ -13,7 +13,6 @@
</div>
</b-container>
</div>
<!-- Page content -->
<b-container class="mt--8">
<b-row class="justify-content-center">
<b-col lg="5" md="7">
@ -22,47 +21,14 @@
<div class="text-center text-muted mb-4">
<small>{{ $t('login') }}</small>
</div>
<validation-observer ref="observer" v-slot="{ passes }">
<b-form @submit.stop.prevent="passes(onSubmit)">
<validation-provider
name="Email"
:rules="{ required: true, email: true }"
v-slot="validationContext"
>
<b-form-group class="mb-3" label="Email" label-for="login-email">
<b-form-input
id="login-email"
name="example-input-1"
v-model="form.email"
placeholder="Email"
:state="getValidationState(validationContext)"
aria-describedby="login-email-live-feedback"
></b-form-input>
<b-form-invalid-feedback id="login-email-live-feedback">
{{ validationContext.errors[0] }}
</b-form-invalid-feedback>
</b-form-group>
</validation-provider>
<validation-observer ref="observer" v-slot="{ handleSubmit }">
<b-form @submit.stop.prevent="handleSubmit(onSubmit)">
<input-email v-model="form.email"></input-email>
<input-password
:label="$t('form.password')"
:placeholder="$t('form.password')"
v-model="form.password"
></input-password>
<b-alert v-show="loginfail" show dismissible variant="warning">
<span class="alert-text bv-example-row">
<b-row>
<b-col class="col-9 text-left text-dark">
<strong>
{{ $t('error.no-account') }}
</strong>
</b-col>
</b-row>
</span>
</b-alert>
<div class="text-center mt-4">
<b-button type="submit" variant="primary">{{ $t('login') }}</b-button>
</div>
@ -91,31 +57,26 @@
import loginAPI from '../../apis/loginAPI'
import CONFIG from '../../config'
import InputPassword from '../../components/Inputs/InputPassword'
import InputEmail from '../../components/Inputs/InputEmail'
export default {
name: 'login',
components: {
InputPassword,
InputEmail,
},
data() {
return {
form: {
email: '',
password: '',
// rememberMe: false
},
loginfail: false,
allowRegister: CONFIG.ALLOW_REGISTER,
passwordVisible: false,
}
},
methods: {
getValidationState({ dirty, validated, valid = null }) {
return dirty || validated ? valid : null
},
async onSubmit() {
// error info ausschalten
this.loginfail = false
const loader = this.$loading.show({
container: this.$refs.submitButton,
})
@ -129,7 +90,7 @@ export default {
loader.hide()
} else {
loader.hide()
this.loginfail = true
this.$toast.error(this.$t('error.no-account'))
}
},
},