Add the logo fetching feature to the Create/Edit forms

This commit is contained in:
Bubka
2022-07-20 13:32:31 +02:00
parent 9b634dd55f
commit 3d7607cb53
10 changed files with 140 additions and 45 deletions

View File

@ -1,12 +1,13 @@
<template>
<button
:type="nativeType"
:disabled="isLoading"
:disabled="isLoading || isDisabled"
:class="{
'button': true,
[`${color}`]: true,
'is-loading': isLoading,
}">
}"
v-on:click="$emit('click')">
<slot />
</button>
</template>
@ -30,6 +31,11 @@
type: Boolean,
default: false
},
isDisabled: {
type: Boolean,
default: false
}
}
}

View File

@ -1,8 +1,8 @@
<template>
<div class="field" :class="{ 'with-offset' : hasOffset }">
<div class="field" :class="{ 'pt-3' : hasOffset }">
<label class="label" v-html="label"></label>
<div class="control">
<input :disabled="isDisabled" :id="fieldName" :type="inputType" class="input" v-model="form[fieldName]" :placeholder="placeholder" v-bind="$attrs" />
<input :disabled="isDisabled" :id="fieldName" :type="inputType" class="input" v-model="form[fieldName]" :placeholder="placeholder" v-bind="$attrs" v-on:change="$emit('field-changed', form[fieldName])"/>
</div>
<field-error :form="form" :field="fieldName" />
<p class="help" v-html="help" v-if="help"></p>

View File

@ -1,5 +1,5 @@
<template>
<div class="field" :class="{ 'with-offset' : hasOffset }">
<div class="field" :class="{ 'pt-3' : hasOffset }">
<label class="label" v-html="label"></label>
<div class="is-toggle buttons">
<label class="button is-dark" :disabled="isDisabled" v-for="choice in choices" :class="{ 'is-link' : form[fieldName] === choice.value }">

View File

@ -25,6 +25,8 @@ import {
faTh,
faList,
faTimesCircle,
faUpload,
faGlobe,
} from '@fortawesome/free-solid-svg-icons'
import {
@ -54,6 +56,8 @@ library.add(
faTh,
faList,
faTimesCircle,
faUpload,
faGlobe,
);
Vue.component('font-awesome-icon', FontAwesomeIcon)

View File

@ -60,27 +60,42 @@
<!-- account -->
<form-field :form="form" fieldName="account" inputType="text" :label="$t('twofaccounts.account')" :placeholder="$t('twofaccounts.forms.account.placeholder')" />
<!-- icon upload -->
<div class="field">
<label class="label">{{ $t('twofaccounts.icon') }}</label>
<div class="file is-dark">
<label class="file-label">
<input class="file-input" type="file" accept="image/*" v-on:change="uploadIcon" ref="iconInput">
<span class="file-cta">
<span class="file-icon">
<font-awesome-icon :icon="['fas', 'image']" />
</span>
<span class="file-label">{{ $t('twofaccounts.forms.choose_image') }}</span>
<label class="label">{{ $t('twofaccounts.icon') }}</label>
<div class="field is-grouped">
<!-- i'm lucky button -->
<div class="control">
<v-button @click="fetchLogo" :color="'is-dark'" :nativeType="'button'" :isDisabled="form.service.length < 3">
<span class="icon is-small">
<font-awesome-icon :icon="['fas', 'globe']" />
</span>
</label>
<span class="tag is-black is-large" v-if="tempIcon">
<img class="icon-preview" :src="'/storage/icons/' + tempIcon" >
<button class="delete is-small" @click.prevent="deleteIcon"></button>
</span>
<span>{{ $t('twofaccounts.forms.i_m_lucky') }}</span>
</v-button>
</div>
<!-- upload button -->
<div class="control">
<div class="file is-dark">
<label class="file-label">
<input class="file-input" type="file" accept="image/*" v-on:change="uploadIcon" ref="iconInput">
<span class="file-cta">
<span class="file-icon">
<font-awesome-icon :icon="['fas', 'upload']" />
</span>
<span class="file-label">{{ $t('twofaccounts.forms.choose_image') }}</span>
</span>
</label>
<span class="tag is-black is-large" v-if="tempIcon">
<img class="icon-preview" :src="'/storage/icons/' + tempIcon" >
<button class="delete is-small" @click.prevent="deleteIcon"></button>
</span>
</div>
</div>
</div>
<field-error :form="form" field="icon" class="help-for-file" />
<div class="field">
<field-error :form="form" field="icon" class="help-for-file" />
<p class="help" v-html="$t('twofaccounts.forms.i_m_lucky_legend')"></p>
</div>
<!-- otp type -->
<form-toggle @otp_type="SetFormState" class="has-uppercased-button" :form="form" :choices="otp_types" fieldName="otp_type" :label="$t('twofaccounts.forms.otp_type.label')" :help="$t('twofaccounts.forms.otp_type.help')" :hasOffset="true" />
<form-toggle @otp_type="setFormState" class="has-uppercased-button" :form="form" :choices="otp_types" fieldName="otp_type" :label="$t('twofaccounts.forms.otp_type.label')" :help="$t('twofaccounts.forms.otp_type.help')" :hasOffset="true" />
<div v-if="form.otp_type">
<!-- secret -->
<label class="label" v-html="$t('twofaccounts.forms.secret.label')"></label>
@ -345,7 +360,21 @@
const { data } = await this.form.upload('/api/v1/icons', imgdata)
this.tempIcon = data.filename;
},
fetchLogo() {
this.axios.post('/api/v1/icons/default', {service: this.form.service}, {returnError: true}).then(response => {
if (response.status === 201) {
// clean possible already uploaded temp icon
this.deleteIcon()
this.tempIcon = response.data.filename;
}
else this.$notify({type: 'is-warning', text: this.$t('errors.no_logo_found_for_x', {service: this.form.service}) })
})
.catch(error => {
this.$notify({type: 'is-warning', text: this.$t('errors.no_logo_found_for_x', {service: this.form.service}) })
});
},
deleteIcon(event) {
@ -376,7 +405,7 @@
console.log('error', value)
},
SetFormState (event) {
setFormState (event) {
this.form.otp_type = event
this.form.service = event === 'steamtotp' ? 'Steam' : ''
this.secretIsBase32Encoded = event === 'steamtotp' ? 1 : this.secretIsBase32Encoded

View File

@ -5,26 +5,41 @@
<form-field :isDisabled="form.otp_type === 'steamtotp'" :form="form" fieldName="service" inputType="text" :label="$t('twofaccounts.service')" :placeholder="$t('twofaccounts.forms.service.placeholder')" autofocus />
<!-- account -->
<form-field :form="form" fieldName="account" inputType="text" :label="$t('twofaccounts.account')" :placeholder="$t('twofaccounts.forms.account.placeholder')" />
<!-- icon -->
<div class="field">
<label class="label">{{ $t('twofaccounts.icon') }}</label>
<div class="file is-dark">
<label class="file-label">
<input class="file-input" type="file" accept="image/*" v-on:change="uploadIcon" ref="iconInput">
<span class="file-cta">
<span class="file-icon">
<font-awesome-icon :icon="['fas', 'image']" />
</span>
<span class="file-label">{{ $t('twofaccounts.forms.choose_image') }}</span>
<!-- icon upload -->
<label class="label">{{ $t('twofaccounts.icon') }}</label>
<div class="field is-grouped">
<!-- i'm lucky button -->
<div class="control">
<v-button @click="fetchLogo" :color="'is-dark'" :nativeType="'button'" :isDisabled="form.service.length < 3">
<span class="icon is-small">
<font-awesome-icon :icon="['fas', 'globe']" />
</span>
</label>
<span class="tag is-black is-large" v-if="tempIcon">
<img class="icon-preview" :src="'/storage/icons/' + tempIcon" >
<button class="delete is-small" @click.prevent="deleteIcon"></button>
</span>
<span>{{ $t('twofaccounts.forms.i_m_lucky') }}</span>
</v-button>
</div>
<!-- upload button -->
<div class="control">
<div class="file is-dark">
<label class="file-label">
<input class="file-input" type="file" accept="image/*" v-on:change="uploadIcon" ref="iconInput">
<span class="file-cta">
<span class="file-icon">
<font-awesome-icon :icon="['fas', 'upload']" />
</span>
<span class="file-label">{{ $t('twofaccounts.forms.choose_image') }}</span>
</span>
</label>
<span class="tag is-black is-large" v-if="tempIcon">
<img class="icon-preview" :src="'/storage/icons/' + tempIcon" >
<button class="delete is-small" @click.prevent="deleteIcon"></button>
</span>
</div>
</div>
</div>
<field-error :form="form" field="icon" class="help-for-file" />
<div class="field">
<field-error :form="form" field="icon" class="help-for-file" />
<p class="help" v-html="$t('twofaccounts.forms.i_m_lucky_legend')"></p>
</div>
<!-- otp type -->
<form-toggle class="has-uppercased-button" :isDisabled="true" :form="form" :choices="otp_types" fieldName="otp_type" :label="$t('twofaccounts.forms.otp_type.label')" :help="$t('twofaccounts.forms.otp_type.help')" :hasOffset="true" />
<div v-if="form.otp_type">
@ -256,6 +271,21 @@
},
fetchLogo() {
this.axios.post('/api/v1/icons/default', {service: this.form.service}, {returnError: true}).then(response => {
if (response.status === 201) {
// clean possible already uploaded temp icon
this.deleteIcon()
this.tempIcon = response.data.filename;
}
else this.$notify({type: 'is-warning', text: this.$t('errors.no_logo_found_for_x', {service: this.form.service}) })
})
.catch(error => {
this.$notify({type: 'is-warning', text: this.$t('errors.no_logo_found_for_x', {service: this.form.service}) })
});
},
deleteIcon(event) {
if( this.tempIcon && this.tempIcon !== this.form.icon ) {