mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
identifier input field
This commit is contained in:
parent
7f91c378c1
commit
2320486d6c
@ -50,6 +50,7 @@
|
|||||||
"prettier": "^2.2.1",
|
"prettier": "^2.2.1",
|
||||||
"qrcanvas-vue": "2.1.1",
|
"qrcanvas-vue": "2.1.1",
|
||||||
"regenerator-runtime": "^0.13.7",
|
"regenerator-runtime": "^0.13.7",
|
||||||
|
"uuid": "^9.0.0",
|
||||||
"vee-validate": "^3.4.5",
|
"vee-validate": "^3.4.5",
|
||||||
"vue": "2.6.12",
|
"vue": "2.6.12",
|
||||||
"vue-apollo": "^3.0.7",
|
"vue-apollo": "^3.0.7",
|
||||||
|
|||||||
@ -51,10 +51,10 @@
|
|||||||
<b-row>
|
<b-row>
|
||||||
<b-col cols="12" v-if="radioSelected === sendTypes.send">
|
<b-col cols="12" v-if="radioSelected === sendTypes.send">
|
||||||
<div v-if="!gradidoID">
|
<div v-if="!gradidoID">
|
||||||
<input-email
|
<input-identifier
|
||||||
:name="$t('form.recipient')"
|
:name="$t('form.recipient')"
|
||||||
:label="$t('form.recipient')"
|
:label="$t('form.recipient')"
|
||||||
:placeholder="$t('form.email')"
|
:placeholder="$t('form.identifier')"
|
||||||
v-model="form.identifier"
|
v-model="form.identifier"
|
||||||
:disabled="isBalanceDisabled"
|
:disabled="isBalanceDisabled"
|
||||||
@onValidation="onValidation"
|
@onValidation="onValidation"
|
||||||
@ -125,108 +125,108 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { SEND_TYPES } from '@/pages/Send'
|
import { SEND_TYPES } from '@/pages/Send'
|
||||||
import InputEmail from '@/components/Inputs/InputEmail'
|
import InputIdentifier from '@/components/Inputs/InputIdentifier'
|
||||||
import InputAmount from '@/components/Inputs/InputAmount'
|
import InputAmount from '@/components/Inputs/InputAmount'
|
||||||
import InputTextarea from '@/components/Inputs/InputTextarea'
|
import InputTextarea from '@/components/Inputs/InputTextarea'
|
||||||
import { user as userQuery } from '@/graphql/queries'
|
import { user as userQuery } from '@/graphql/queries'
|
||||||
import { isEmpty } from 'lodash'
|
import { isEmpty } from 'lodash'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TransactionForm',
|
name: 'TransactionForm',
|
||||||
components: {
|
components: {
|
||||||
InputEmail,
|
InputIdentifier,
|
||||||
InputAmount,
|
InputAmount,
|
||||||
InputTextarea,
|
InputTextarea,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
balance: { type: Number, default: 0 },
|
balance: { type: Number, default: 0 },
|
||||||
identifier: { type: String, default: '' },
|
identifier: { type: String, default: '' },
|
||||||
amount: { type: Number, default: 0 },
|
amount: { type: Number, default: 0 },
|
||||||
memo: { type: String, default: '' },
|
memo: { type: String, default: '' },
|
||||||
selected: { type: String, default: 'send' },
|
selected: { type: String, default: 'send' },
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
form: {
|
form: {
|
||||||
identifier: this.identifier,
|
identifier: this.identifier,
|
||||||
amount: this.amount ? String(this.amount) : '',
|
amount: this.amount ? String(this.amount) : '',
|
||||||
memo: this.memo,
|
memo: this.memo,
|
||||||
},
|
},
|
||||||
radioSelected: this.selected,
|
radioSelected: this.selected,
|
||||||
userName: '',
|
userName: '',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onValidation() {
|
onValidation() {
|
||||||
this.$refs.formValidator.validate()
|
this.$refs.formValidator.validate()
|
||||||
},
|
},
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
if (this.gradidoID) this.form.identifier = this.gradidoID
|
if (this.gradidoID) this.form.identifier = this.gradidoID
|
||||||
this.$emit('set-transaction', {
|
this.$emit('set-transaction', {
|
||||||
selected: this.radioSelected,
|
selected: this.radioSelected,
|
||||||
identifier: this.form.identifier,
|
identifier: this.form.identifier,
|
||||||
amount: Number(this.form.amount.replace(',', '.')),
|
amount: Number(this.form.amount.replace(',', '.')),
|
||||||
memo: this.form.memo,
|
memo: this.form.memo,
|
||||||
userName: this.userName,
|
userName: this.userName,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
onReset(event) {
|
onReset(event) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
this.form.identifier = ''
|
this.form.identifier = ''
|
||||||
this.form.amount = ''
|
this.form.amount = ''
|
||||||
this.form.memo = ''
|
this.form.memo = ''
|
||||||
this.$refs.formValidator.validate()
|
this.$refs.formValidator.validate()
|
||||||
if (this.$route.query && !isEmpty(this.$route.query))
|
if (this.$route.query && !isEmpty(this.$route.query))
|
||||||
this.$router.replace({ query: undefined })
|
this.$router.replace({ query: undefined })
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
apollo: {
|
apollo: {
|
||||||
UserName: {
|
UserName: {
|
||||||
query() {
|
query() {
|
||||||
return userQuery
|
return userQuery
|
||||||
},
|
},
|
||||||
fetchPolicy: 'network-only',
|
fetchPolicy: 'network-only',
|
||||||
variables() {
|
variables() {
|
||||||
return { identifier: this.gradidoID }
|
return { identifier: this.gradidoID }
|
||||||
},
|
},
|
||||||
skip() {
|
skip() {
|
||||||
return !this.gradidoID
|
return !this.gradidoID
|
||||||
},
|
},
|
||||||
update({ user }) {
|
update({ user }) {
|
||||||
this.userName = `${user.firstName} ${user.lastName}`
|
this.userName = `${user.firstName} ${user.lastName}`
|
||||||
},
|
},
|
||||||
error({ message }) {
|
error({ message }) {
|
||||||
this.toastError(message)
|
this.toastError(message)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
disabled() {
|
disabled() {
|
||||||
if (
|
if (
|
||||||
this.form.identifier.length > 5 &&
|
this.form.identifier.length > 5 &&
|
||||||
parseInt(this.form.amount) <= parseInt(this.balance) &&
|
parseInt(this.form.amount) <= parseInt(this.balance) &&
|
||||||
this.form.memo.length > 5 &&
|
this.form.memo.length > 5 &&
|
||||||
this.form.memo.length <= 255
|
this.form.memo.length <= 255
|
||||||
) {
|
) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
},
|
},
|
||||||
isBalanceDisabled() {
|
isBalanceDisabled() {
|
||||||
return this.balance <= 0 ? 'disabled' : false
|
return this.balance <= 0 ? 'disabled' : false
|
||||||
},
|
},
|
||||||
sendTypes() {
|
sendTypes() {
|
||||||
return SEND_TYPES
|
return SEND_TYPES
|
||||||
},
|
},
|
||||||
gradidoID() {
|
gradidoID() {
|
||||||
return this.$route.query && this.$route.query.gradidoID
|
return this.$route.query && this.$route.query.gradidoID
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
if (this.form.identifier !== '') this.$refs.formValidator.validate()
|
if (this.form.identifier !== '') this.$refs.formValidator.validate()
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
span.errors {
|
span.errors {
|
||||||
|
|||||||
69
frontend/src/components/Inputs/InputIdentifier.vue
Normal file
69
frontend/src/components/Inputs/InputIdentifier.vue
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<template>
|
||||||
|
<validation-provider
|
||||||
|
tag="div"
|
||||||
|
:rules="rules"
|
||||||
|
:name="name"
|
||||||
|
v-slot="{ errors, valid, validated, ariaInput, ariaMsg }"
|
||||||
|
>
|
||||||
|
<b-form-group :label="label" :label-for="labelFor" data-test="input-email">
|
||||||
|
<b-form-input
|
||||||
|
v-model="currentValue"
|
||||||
|
v-bind="ariaInput"
|
||||||
|
data-test="input-identifier"
|
||||||
|
:id="labelFor"
|
||||||
|
:name="name"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
type="text"
|
||||||
|
:state="validated ? valid : false"
|
||||||
|
trim
|
||||||
|
class="bg-248"
|
||||||
|
:disabled="disabled"
|
||||||
|
autocomplete="off"
|
||||||
|
></b-form-input>
|
||||||
|
<b-form-invalid-feedback v-bind="ariaMsg">
|
||||||
|
{{ errors[0] }}
|
||||||
|
</b-form-invalid-feedback>
|
||||||
|
</b-form-group>
|
||||||
|
</validation-provider>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'InputEmail',
|
||||||
|
props: {
|
||||||
|
rules: {
|
||||||
|
default: () => {
|
||||||
|
return {
|
||||||
|
required: true,
|
||||||
|
validIdentifier: true,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
name: { type: String, required: true },
|
||||||
|
label: { type: String, required: true },
|
||||||
|
placeholder: { type: String, required: true },
|
||||||
|
value: { type: String, required: true },
|
||||||
|
disabled: { type: Boolean, required: false, default: false },
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
currentValue: this.value,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
labelFor() {
|
||||||
|
return this.name + '-input-field'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
currentValue() {
|
||||||
|
this.$emit('input', this.currentValue)
|
||||||
|
},
|
||||||
|
value() {
|
||||||
|
if (this.value !== this.currentValue) {
|
||||||
|
this.currentValue = this.value
|
||||||
|
}
|
||||||
|
this.$emit('onValidation')
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@ -142,6 +142,7 @@
|
|||||||
"from": "Von",
|
"from": "Von",
|
||||||
"generate_now": "Jetzt generieren",
|
"generate_now": "Jetzt generieren",
|
||||||
"hours": "Stunden",
|
"hours": "Stunden",
|
||||||
|
"identifier": "Email, Nutzername oder Gradido ID",
|
||||||
"lastname": "Nachname",
|
"lastname": "Nachname",
|
||||||
"memo": "Nachricht",
|
"memo": "Nachricht",
|
||||||
"message": "Nachricht",
|
"message": "Nachricht",
|
||||||
@ -174,7 +175,8 @@
|
|||||||
"is-not": "Du kannst dir selbst keine Gradidos überweisen",
|
"is-not": "Du kannst dir selbst keine Gradidos überweisen",
|
||||||
"username-allowed-chars": "Der Nutzername darf nur aus Buchstaben (ohne Umlaute), Zahlen, Binde- oder Unterstrichen bestehen.",
|
"username-allowed-chars": "Der Nutzername darf nur aus Buchstaben (ohne Umlaute), Zahlen, Binde- oder Unterstrichen bestehen.",
|
||||||
"username-hyphens": "Binde- oder Unterstriche müssen zwischen Buchstaben oder Zahlen stehen.",
|
"username-hyphens": "Binde- oder Unterstriche müssen zwischen Buchstaben oder Zahlen stehen.",
|
||||||
"username-unique": "Der Nutzername ist bereits vergeben."
|
"username-unique": "Der Nutzername ist bereits vergeben.",
|
||||||
|
"valid-identifier": "Muss eine Email, ein Nutzernamen oder eine gradido ID sein."
|
||||||
},
|
},
|
||||||
"your_amount": "Dein Betrag"
|
"your_amount": "Dein Betrag"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -142,6 +142,7 @@
|
|||||||
"from": "from",
|
"from": "from",
|
||||||
"generate_now": "Generate now",
|
"generate_now": "Generate now",
|
||||||
"hours": "Hours",
|
"hours": "Hours",
|
||||||
|
"identifier": "Email, username or gradido ID",
|
||||||
"lastname": "Lastname",
|
"lastname": "Lastname",
|
||||||
"memo": "Message",
|
"memo": "Message",
|
||||||
"message": "Message",
|
"message": "Message",
|
||||||
@ -174,7 +175,8 @@
|
|||||||
"is-not": "You cannot send Gradidos to yourself",
|
"is-not": "You cannot send Gradidos to yourself",
|
||||||
"username-allowed-chars": "The username may contain letters, numbers, hyphens or underscores.",
|
"username-allowed-chars": "The username may contain letters, numbers, hyphens or underscores.",
|
||||||
"username-hyphens": "Hyphens or underscores must be in between letters or numbers.",
|
"username-hyphens": "Hyphens or underscores must be in between letters or numbers.",
|
||||||
"username-unique": "This username is already taken."
|
"username-unique": "This username is already taken.",
|
||||||
|
"valid-identifier": "Must be a valid email, username or gradido ID."
|
||||||
},
|
},
|
||||||
"your_amount": "Your amount"
|
"your_amount": "Your amount"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -2,6 +2,12 @@ import { configure, extend } from 'vee-validate'
|
|||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
import { required, email, min, max, is_not } from 'vee-validate/dist/rules'
|
import { required, email, min, max, is_not } from 'vee-validate/dist/rules'
|
||||||
import { checkUsername } from '@/graphql/queries'
|
import { checkUsername } from '@/graphql/queries'
|
||||||
|
import { validate as validateUuid, version as versionUuid } from 'uuid'
|
||||||
|
|
||||||
|
// taken from vee-validate
|
||||||
|
const emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
|
||||||
|
|
||||||
|
const usernameRegex = /^(?=.{3,20}$)[a-zA-Z0-9]+(?:[_-][a-zA-Z0-9])*$/
|
||||||
|
|
||||||
export const loadAllRules = (i18nCallback, apollo) => {
|
export const loadAllRules = (i18nCallback, apollo) => {
|
||||||
configure({
|
configure({
|
||||||
@ -158,4 +164,14 @@ export const loadAllRules = (i18nCallback, apollo) => {
|
|||||||
},
|
},
|
||||||
message: (_, values) => i18nCallback.t('form.validation.username-unique', values),
|
message: (_, values) => i18nCallback.t('form.validation.username-unique', values),
|
||||||
})
|
})
|
||||||
|
|
||||||
|
extend('validIdentifier', {
|
||||||
|
validate(value) {
|
||||||
|
const isEmail = !!value.match(emailRegex)
|
||||||
|
const isUsername = !!value.match(usernameRegex)
|
||||||
|
// const isGradidoId = validateUuid(value) && versionUuid(value) === 4
|
||||||
|
return isEmail || isUsername // || isGradidoId
|
||||||
|
},
|
||||||
|
message: (_, values) => i18nCallback.t('form.validation.valid-identifier', values),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14176,6 +14176,11 @@ uuid@^8.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
|
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
|
||||||
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
|
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
|
||||||
|
|
||||||
|
uuid@^9.0.0:
|
||||||
|
version "9.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5"
|
||||||
|
integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==
|
||||||
|
|
||||||
v8-compile-cache@^2.0.3, v8-compile-cache@^2.3.0:
|
v8-compile-cache@^2.0.3, v8-compile-cache@^2.3.0:
|
||||||
version "2.3.0"
|
version "2.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
|
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user