switch to Array v-model for AdressInputSelect

This commit is contained in:
Axolotle 2020-08-04 16:06:44 +02:00
parent 59908a46ed
commit b96bae08af
3 changed files with 51 additions and 80 deletions

View file

@ -3,7 +3,7 @@
<b-input
:id="id" :placeholder="placeholder"
:state="state" :aria-describedby="feedbackId"
v-model="reactiveInput" @input="updateValue"
v-model="value[0]" @update="$emit('input', value)"
/>
<b-input-group-append>
@ -11,7 +11,9 @@
</b-input-group-append>
<b-input-group-append>
<b-select v-model="reactiveOption" :options="options" @change="updateValue" />
<b-select
v-model="value[1]" :options="options" @change="$emit('input', value)"
/>
</b-input-group-append>
</b-input-group>
</template>
@ -19,64 +21,15 @@
<script>
export default {
name: 'AdressInputSelect',
props: {
// `value` is actually passed as the `v-model` directive
value: { type: String, required: true },
// `value` is actually passed thru the `v-model` directive
value: { type: Array, required: true },
options: { type: Array, required: true },
separator: { type: String, default: '@' },
placeholder: { type: String, default: null },
id: { type: String, default: null },
state: { type: null, default: null },
feedbackId: { type: String, default: null },
defaultOption: { type: Number, default: 0 }
},
data () {
// static value that are updated by the computed setters.
return {
input: '',
option: ''
}
},
// Those 'reactive' properties allows two-way value binding. If input and option where
// only static properties, it would be impossible to detect that `value` has changed
// from outside this scope.
computed: {
reactiveInput: {
get () {
return this.value.split(this.separator)[0]
},
set (value) {
// FIXME, ugly hack since the `reactiveOption` v-model isn't set when `value` change
if (this.reactiveOption !== this.option) {
this.option = this.reactiveOption
}
this.input = value
}
},
reactiveOption: {
get () {
return this.value.split(this.separator)[1] || this.options[this.defaultOption]
},
set (value) {
// FIXME, ugly hack since the `reactiveInput` v-model isn't set when `value` change
if (this.reactiveInput !== this.input) {
this.input = this.reactiveInput
}
this.option = value
}
}
},
methods: {
// Emit an input event of the concatened data.
// Since the consumer of this component will use the `v-model` directive, this event
// will automaticly update the value of the given variable.
updateValue () {
this.$emit('input', this.input + this.separator + this.option)
}
feedbackId: { type: String, default: null }
}
}
</script>

View file

@ -124,7 +124,7 @@ export default {
username: '',
firstname: '',
lastname: '',
mail: '',
mail: ['', ''],
mailbox_quota: '',
password: '',
confirmation: ''
@ -148,7 +148,7 @@ export default {
computed: {
domains () {
return this.$store.state.data.domains
return this.$store.state.data.domains || []
}
},
@ -159,6 +159,7 @@ export default {
}
const data = JSON.parse(JSON.stringify(this.form))
data.mail = data.mail.join('@')
const quota = data.mailbox_quota
data.mailbox_quota = parseInt(quota) ? quota + 'M' : 0
@ -173,8 +174,8 @@ export default {
},
populateEmail () {
if (this.form.email === '') {
this.form.email = this.form.username
if (this.form.mail[0] === '') {
this.form.mail.splice(0, 1, this.form.username)
}
},
@ -193,9 +194,9 @@ export default {
validateEmail () {
// FIXME check allowed characters
const isValid = this.form.mail.split('@')[0].match('^[A-Za-z0-9-_]+$')
this.error.email = isValid ? '' : this.$i18n.t('form_errors.email_syntax')
this.isValid.email = isValid ? null : false
const isValid = this.form.mail.text.match('^[A-Za-z0-9-_]+$')
this.error.mail = isValid ? '' : this.$i18n.t('form_errors.email_syntax')
this.isValid.mail = isValid ? null : false
},
validatePassword () {
@ -206,8 +207,13 @@ export default {
},
created () {
this.$store.dispatch('FETCH_ALL', [{ uri: 'domains' }, { uri: 'users' }])
this.$store.dispatch('FETCH_ALL',
[{ uri: 'domains' }, { uri: 'users' }]
).then(([domains]) => {
this.form.mail.splice(1, 1, domains[0])
})
},
components: {
AdressInputSelect,
BasicForm

View file

@ -138,10 +138,10 @@ export default {
form: {
firstname: '',
lastname: '',
mail: '',
mail: [],
'mailbox-quota': '',
'mail-aliases': [],
'mail-forward': [],
'mail-forward': [''],
password: '',
confirmation: ''
},
@ -165,20 +165,24 @@ export default {
return this.$store.state.data.users_details[this.name]
},
domains () {
return this.$store.state.data.domains
return this.$store.state.data.domains || []
}
},
methods: {
onSubmit () {
console.log(this.form['mail-aliases'])
for (const key in this.isValid) {
if (this.isValid[key] === false) return
}
const data = {}
for (const key of ['firstname', 'lastname', 'mail']) {
const mail = this.form.mail.join('@')
if (mail !== this.user.mail) {
data.mail = mail
}
for (const key of ['firstname', 'lastname']) {
if (this.form[key] !== this.user[key]) data[key] = this.form[key]
}
@ -188,9 +192,11 @@ export default {
data.mailbox_quota = quota !== 'No quota' ? quota : 0
}
// Concat mail aliases that have a name
const mailAliases = this.form['mail-aliases'].filter(alias => alias[0]).map(alias => alias.join('@'))
const mails = {
add_mailalias: arrayDiff(this.form['mail-aliases'], this.user['mail-aliases']),
remove_mailalias: arrayDiff(this.user['mail-aliases'], this.form['mail-aliases']),
add_mailalias: arrayDiff(mailAliases, this.user['mail-aliases']),
remove_mailalias: arrayDiff(this.user['mail-aliases'], mailAliases),
add_mailforward: arrayDiff(this.form['mail-forward'], this.user['mail-forward']),
remove_mailforward: arrayDiff(this.user['mail-forward'], this.form['mail-forward'])
}
@ -203,6 +209,10 @@ export default {
return arr1.filter(item => ((arr2.indexOf(item) === -1) && (item !== '')))
}
// Redirect if nothing has changed
if (Object.keys(data).length === 0) {
return this.$router.push({ name: 'user-list' })
}
this.$store.dispatch('PUT',
{ uri: 'users', data, param: this.user.username, storeKey: 'users_details' }
).then(() => {
@ -215,8 +225,7 @@ export default {
validateEmail (mail) {
// FIXME check allowed characters
console.log('validate', mail)
const isValid = mail.split('@')[0].match('^[A-Za-z0-9-_]+$')
const isValid = mail[0].match('^[A-Za-z0-9-_]+$')
this.error.mail = isValid ? '' : this.$i18n.t('form_errors.email_syntax')
this.isValid.mail = isValid ? null : false
},
@ -232,15 +241,18 @@ export default {
this.$store.dispatch('FETCH_ALL', [
{ uri: 'domains' },
{ uri: 'users', param: this.name, storeKey: 'users_details' }
]).then(([domainsData, userData]) => {
this.form.firstname = userData.firstname
this.form.lastname = userData.lastname
this.form.mail = userData.mail
console.log('fetch', this.form.mail)
this.form['mail-aliases'] = userData['mail-aliases'] ? [...userData['mail-aliases'], ''] : ['']
this.form['mail-forward'] = userData['mail-forward'] ? [...userData['mail-forward'], ''] : ['']
if (userData['mailbox-quota'].limit !== 'No quota') {
this.form['mailbox-quota'] = userData['mailbox-quota'].limit.slice(0, -1)
]).then(([domains, user]) => {
this.form.firstname = user.firstname
this.form.lastname = user.lastname
this.form.mail = user.mail.split('@')
this.form['mail-aliases'] = user['mail-aliases']
? [...user['mail-aliases'].map(mail => mail.split('@')), ['', domains[0]]]
: [['', domains[0]]]
if (user['mail-forward']) {
this.form['mail-forward'] = [...user['mail-forward'], '']
}
if (user['mailbox-quota'].limit !== 'No quota') {
this.form['mailbox-quota'] = user['mailbox-quota'].limit.slice(0, -1)
}
})
},