160 lines
4.3 KiB
Vue
160 lines
4.3 KiB
Vue
<template>
|
|
<div class="ui form">
|
|
<div
|
|
v-if="errors.length > 0"
|
|
role="alert"
|
|
class="ui negative message"
|
|
>
|
|
<h4 class="header">
|
|
<translate translate-context="Content/*/Error message.Title">
|
|
Your attachment cannot be saved
|
|
</translate>
|
|
</h4>
|
|
<ul class="list">
|
|
<li
|
|
v-for="(error, key) in errors"
|
|
:key="key"
|
|
>
|
|
{{ error }}
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<div class="ui field">
|
|
<span id="avatarLabel">
|
|
<slot />
|
|
</span>
|
|
<div class="ui stackable grid row">
|
|
<div class="three wide column">
|
|
<img
|
|
v-if="value && value === initialValue"
|
|
alt=""
|
|
:class="['ui', imageClass, 'image']"
|
|
:src="$store.getters['instance/absoluteUrl'](`api/v1/attachments/${value}/proxy?next=medium_square_crop`)"
|
|
>
|
|
<img
|
|
v-else-if="attachment"
|
|
alt=""
|
|
:class="['ui', imageClass, 'image']"
|
|
:src="$store.getters['instance/absoluteUrl'](`api/v1/attachments/${attachment.uuid}/proxy?next=medium_square_crop`)"
|
|
>
|
|
<div
|
|
v-else
|
|
:class="['ui', imageClass, 'static', 'large placeholder image']"
|
|
/>
|
|
</div>
|
|
<div class="eleven wide column">
|
|
<div class="file-input">
|
|
<label :for="attachmentId">
|
|
<translate translate-context="*/*/*">Upload New Picture…</translate>
|
|
</label>
|
|
<input
|
|
:id="attachmentId"
|
|
ref="attachment"
|
|
class="ui input"
|
|
type="file"
|
|
accept="image/x-png,image/jpeg"
|
|
@change="submit"
|
|
>
|
|
</div>
|
|
<div class="ui very small hidden divider" />
|
|
<p>
|
|
<translate translate-context="Content/*/Paragraph">
|
|
PNG or JPG. Dimensions should be between 1400x1400px and 3000x3000px. Maximum file size allowed is 5MB.
|
|
</translate>
|
|
</p>
|
|
<button
|
|
v-if="value"
|
|
class="ui basic tiny button"
|
|
@click.stop.prevent="remove(value)"
|
|
>
|
|
<translate translate-context="Content/Radio/Button.Label/Verb">
|
|
Remove
|
|
</translate>
|
|
</button>
|
|
<div
|
|
v-if="isLoading"
|
|
class="ui active inverted dimmer"
|
|
>
|
|
<div class="ui indeterminate text loader">
|
|
<translate translate-context="Content/*/*/Noun">
|
|
Uploading file…
|
|
</translate>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<script>
|
|
import axios from 'axios'
|
|
|
|
export default {
|
|
props: {
|
|
value: { type: String, default: null },
|
|
imageClass: { type: String, default: '', required: false }
|
|
},
|
|
data () {
|
|
return {
|
|
attachment: null,
|
|
isLoading: false,
|
|
errors: [],
|
|
initialValue: this.value,
|
|
attachmentId: Math.random().toString(36).substring(7)
|
|
}
|
|
},
|
|
watch: {
|
|
value (v) {
|
|
if (this.attachment && v === this.initialValue) {
|
|
// we had a reset to initial value
|
|
this.remove(this.attachment.uuid)
|
|
}
|
|
}
|
|
},
|
|
methods: {
|
|
submit () {
|
|
this.isLoading = true
|
|
this.errors = []
|
|
const self = this
|
|
this.file = this.$refs.attachment.files[0]
|
|
const formData = new FormData()
|
|
formData.append('file', this.file)
|
|
axios
|
|
.post('attachments/', formData, {
|
|
headers: {
|
|
'Content-Type': 'multipart/form-data'
|
|
}
|
|
})
|
|
.then(
|
|
response => {
|
|
this.isLoading = false
|
|
self.attachment = response.data
|
|
self.$emit('input', self.attachment.uuid)
|
|
},
|
|
error => {
|
|
self.isLoading = false
|
|
self.errors = error.backendErrors
|
|
}
|
|
)
|
|
},
|
|
remove (uuid) {
|
|
this.isLoading = true
|
|
this.errors = []
|
|
const self = this
|
|
axios.delete(`attachments/${uuid}/`)
|
|
.then(
|
|
response => {
|
|
this.isLoading = false
|
|
self.attachment = null
|
|
self.$emit('delete')
|
|
},
|
|
error => {
|
|
self.isLoading = false
|
|
self.errors = error.backendErrors
|
|
}
|
|
)
|
|
}
|
|
}
|
|
}
|
|
</script>
|