aircox/assets/src/components/ASelectFile.vue

169 lines
5.2 KiB
Vue

<template>
<a-modal ref="modal" :title="title">
<template #bar>
<button type="button" class="button small mr-3" v-if="panel == LIST"
@click="showPanel(UPLOAD)">
<span class="icon">
<i class="fa fa-upload"></i>
</span>
<span>{{ labels.upload }}</span>
</button>
<button type="button" class="button small mr-3" v-else
@click="showPanel(LIST)">
<span class="icon">
<i class="fa fa-list"></i>
</span>
<span>{{ labels.list }}</span>
</button>
</template>
<template #default>
<div class="a-select-file">
<a-file-upload ref="upload" v-if="panel == UPLOAD"
:url="uploadUrl"
:label="uploadLabel" :field-name="uploadFieldName"
@load="uploadDone">
<template #form="data">
<slot name="upload-form" v-bind="data"></slot>
</template>
<template #preview="data">
<slot name="upload-preview" v-bind="data"></slot>
</template>
</a-file-upload>
<div ref="list" v-show="panel == LIST"
:class="['a-select-file-list', listClass]">
<!-- tiles -->
<div v-if="prevUrl">
<a href="#" @click="load(prevUrl)">
{{ labels.show_previous }}
</a>
</div>
<template v-for="item in items" v-bind:key="item.id">
<div :class="['file-preview', this.item && item.id == this.item.id && 'active']" @click="select(item)">
<slot :item="item" :load="load" :lastUrl="lastUrl"></slot>
<a-action-button v-if="deleteUrl"
class="has-text-danger small float-right"
icon="fa fa-trash"
:confirm="labels.confirm_delete"
method="DELETE"
:url="deleteUrl.replace('123', item.id)"
@done="load(lastUrl)">
</a-action-button>
</div>
</template>
<div v-if="nextUrl">
<a href="#" @click="load(nextUrl)">
{{ labels.show_next }}
</a>
</div>
</div>
</div>
</template>
<template #footer>
<slot name="footer" :item="item">
<span class="mr-3" v-if="item">{{ item.name }}</span>
</slot>
<button type="button" v-if="panel == LIST" class="button align-right"
@click="selected">
{{ labels.select_file }}
</button>
</template>
</a-modal>
</template>
<script>
import AModal from "./AModal"
import AActionButton from "./AActionButton"
import AFileUpload from "./AFileUpload"
export default {
emit: ["select"],
components: {AActionButton, AFileUpload, AModal},
props: {
title: { type: String },
labels: Object,
listClass: {type: String, default: ""},
// List url
listUrl: { type: String },
// URL to delete an item, where "123" is replaced by
// the item id.
deleteUrl: {type: String },
uploadUrl: { type: String },
uploadFieldName: { type: String, default: "file" },
uploadLabel: { type: String, default: "Upload a file" },
},
data() {
return {
LIST: 0,
UPLOAD: 1,
panel: 0,
item: null,
items: [],
nextUrl: "",
prevUrl: "",
lastUrl: "",
}
},
methods: {
open() {
this.$refs.modal.open()
},
close() {
this.$refs.modal.close()
},
showPanel(panel) {
this.panel = panel
},
load(url) {
return fetch(url || this.listUrl).then(
response => response.ok ? response.json() : Promise.reject(response)
).then(data => {
this.lastUrl = url
this.nextUrl = data.next
this.prevUrl = data.previous
this.items = data.results
this.showPanel(this.LIST)
this.$forceUpdate()
this.$refs.list.scroll(0, 0)
return this.items
})
},
//! Select an item
select(item) {
this.item = item;
},
//! User click on select button (confirm selection)
selected() {
this.$emit("select", this.item)
this.close()
},
uploadDone(reload=false) {
reload && this.load().then(items => {
this.item = items[0]
})
},
},
mounted() {
this.load()
},
}
</script>