feat(claim_photo): drag&drop

This commit is contained in:
Alex Moreno 2023-02-20 15:12:48 +01:00
parent 38a6b93a5d
commit ed2aedd9d4
3 changed files with 140 additions and 86 deletions

View File

@ -296,8 +296,9 @@ export default {
returnOfMaterial: 'Return of material authorization (RMA)', returnOfMaterial: 'Return of material authorization (RMA)',
}, },
photo: { photo: {
fileDescription: fileDescription: 'Claim id {claimId} from client {clientName} id {clientId}',
'Reclamacion ID {claimId} del cliente {clientName} id {clientId}', noData: 'There are no images/videos, click here or drag and drop the file',
dragDrop: 'Drag and drop it here',
}, },
}, },
invoiceOut: { invoiceOut: {

View File

@ -295,7 +295,10 @@ export default {
returnOfMaterial: 'Autorización de retorno de materiales (RMA)', returnOfMaterial: 'Autorización de retorno de materiales (RMA)',
}, },
photo: { photo: {
fileDescription: 'Claim id {claimId} from client {clientName} id {clientId}', fileDescription:
'Reclamacion ID {claimId} del cliente {clientName} id {clientId}',
noData: 'No hay imágenes/videos, haz click aquí o arrastra y suelta el archivo',
dragDrop: 'Arrástralo y sueltalo aquí',
}, },
}, },
invoiceOut: { invoiceOut: {

View File

@ -10,7 +10,6 @@ import { useI18n } from 'vue-i18n';
import { useSession } from 'src/composables/useSession'; import { useSession } from 'src/composables/useSession';
import FetchData from 'components/FetchData.vue'; import FetchData from 'components/FetchData.vue';
// import FormModel from 'components/FormModel.vue';
const router = useRouter(); const router = useRouter();
const { t } = useI18n(); const { t } = useI18n();
@ -19,31 +18,43 @@ const token = session.getToken();
const quasar = useQuasar(); const quasar = useQuasar();
const claimId = computed(function () { const claimId = computed(function () {
return router.currentRoute.value.params.id; return 1;
}); });
const claimDms = ref([]); const claimDms = ref([]);
const client = ref({});
const claimDmsRef = ref(); const claimDmsRef = ref();
const dmsType = ref({}); const dmsType = ref({});
const config = ref({}); const config = ref({});
const dms = ref({}); const dragFile = ref(false);
const dragFileTimeout = ref();
const claimDmsFilter = ref({ const claimDmsFilter = ref({
include: [ include: [
{ {
relation: 'dms', relation: 'client',
scope: {
fields: ['id', 'name'],
},
},
{
relation: 'claimDms',
scope: {
include: {
relation: 'dms',
scope: {
fields: ['contentType'],
},
},
},
}, },
], ],
where: { claimFk: claimId.value }, where: { id: claimId.value },
}); });
const multimediaDialog = ref(); const multimediaDialog = ref();
const multimediaMaximizedDialog = ref(); const multimediaMaximizedDialog = ref();
const multimediaSlide = ref(); const multimediaSlide = ref();
function getImagePath(media) {
return `http://localhost:9000/api/Claims/${media.dmsFk}/downloadFile?access_token=${token}`;
}
function openDialog(dmsId) { function openDialog(dmsId) {
multimediaSlide.value = dmsId; multimediaSlide.value = dmsId;
multimediaDialog.value = true; multimediaDialog.value = true;
@ -63,9 +74,8 @@ function viewDeleteDms(dmsId) {
} }
async function deleteDms(index) { async function deleteDms(index) {
console.log(index);
const dmsId = claimDms.value[index].dmsFk; const dmsId = claimDms.value[index].dmsFk;
await axios.post(`ClaimDms/${dmsId}/removeFile`); // await axios.post(`ClaimDms/${dmsId}/removeFile`);
quasar.notify({ quasar.notify({
message: t('globals.dataDeleted'), message: t('globals.dataDeleted'),
type: 'positive', type: 'positive',
@ -75,11 +85,12 @@ async function deleteDms(index) {
} }
function setClaimDms(data) { function setClaimDms(data) {
claimDms.value = data.map((media) => { claimDms.value = data.claimDms.map((media) => {
media.isVideo = media.dms.contentType == 'video/mp4'; media.isVideo = media.dms.contentType == 'video/mp4';
media.url = getImagePath(media); media.url = `${window.location.origin}/api/Claims/${media.dmsFk}/downloadFile?access_token=${token}`;
return media; return media;
}); });
client.value = data.client;
} }
async function uploadFile() { async function uploadFile() {
@ -90,42 +101,35 @@ async function uploadFile() {
element.click(); element.click();
element.addEventListener('change', () => { element.addEventListener('change', () => {
setDefaultParams();
create(element.files).then(() => claimDmsRef.value.fetch()); create(element.files).then(() => claimDmsRef.value.fetch());
}); });
} }
function setDefaultParams() {
console.log(config.value);
console.log(dmsType.value);
console.log(claimDms.value);
dms.value = {
hasFile: false,
hasFileAttached: false,
reference: claimId.value,
warehouseId: config.value.warehouseFk,
companyId: config.value.companyFk,
dmsTypeId: dmsType.value.id,
description: t('claim.photo.fileDescription', {
claimId: claimId.value,
clientName: claimDms.value.clientName,
clientId: claimDms.value.clientFk,
}).toUpperCase(),
};
console.log(dms.value);
}
async function create(files) { async function create(files) {
const formData = new FormData(); const formData = new FormData();
for (let i = 0; i < files.length; i++) formData.append(files[i].name, files[i]); for (let i = 0; i < files.length; i++) formData.append(files[i].name, files[i]);
const query = `claims/${claimId.value}/uploadFile`; const query = `claims/${claimId.value}/uploadFile`;
const dms = {
hasFile: false,
hasFileAttached: false,
reference: claimId.value,
warehouseId: config.value.warehouseFk,
companyId: config.value.companyFk,
dmsTypeId: dmsType.value.id,
description: t('claim.photo.fileDescription', {
claimId: claimId.value,
clientName: client.value.name,
clientId: client.value.id,
}).toUpperCase(),
};
await axios({ await axios({
method: 'POST', method: 'POST',
url: query, url: query,
data: formData, data: formData,
params: dms.value, params: dms,
}); });
quasar.notify({ quasar.notify({
@ -134,12 +138,23 @@ async function create(files) {
icon: 'check', icon: 'check',
}); });
} }
function onDrop($data) {
dragFile.value = false;
create($data.dataTransfer.files).then(() => claimDmsRef.value.fetch());
}
function onDrag() {
clearTimeout(dragFileTimeout.value);
dragFileTimeout.value = setTimeout(() => (dragFile.value = false), 500);
dragFile.value = true;
}
</script> </script>
<template> <template>
<fetch-data <fetch-data
url="ClaimDms" url="Claims"
:filter="claimDmsFilter" :filter="claimDmsFilter"
@on-fetch="(data) => setClaimDms(data)" @on-fetch="([data]) => setClaimDms(data)"
limit="20" limit="20"
auto-load auto-load
ref="claimDmsRef" ref="claimDmsRef"
@ -155,61 +170,91 @@ async function create(files) {
@on-fetch="(data) => (config = data)" @on-fetch="(data) => (config = data)"
auto-load auto-load
/> />
<div class="multimediaParent bg-transparent"> <div
<div v-for="(media, index) of claimDms" :key="index" class="relative-position"> :class="['container', { dragFile }]"
<q-btn @drop.prevent="onDrop"
icon="delete" @dragenter.prevent
color="primary" @dragover.prevent="onDrag"
text-color="white" >
size="md" <div
class="all-pointer-events absolute delete-button zindex" class="flex flex-center items-center text-grey q-mt-md column"
@click.stop="viewDeleteDms(index)" v-if="dragFile"
round >
/> <q-icon size="xl" name="file_download" />
<q-icon <h5>
name="play_arrow" <!-- {{ t('claim.photo.dragDrop') }} -->
color="primary" </h5>
size="xl" </div>
class="absolute-center zindex" <div
v-if="media.isVideo" class="text-center text-grey q-mt-md cursor-pointer"
@click.stop="openDialog(media.dmsFk)" v-if="!claimDms?.length && !dragFile"
flat @click="uploadFile()"
>
<q-icon size="xl" name="image"></q-icon>
<q-icon size="xl" name="movie"></q-icon>
<h5>
<!-- {{ t('claim.photo.noData') }} -->
</h5>
</div>
<div class="multimediaParent bg-transparent" v-if="claimDms?.length && !dragFile">
<div
v-for="(media, index) of claimDms"
:key="index"
class="relative-position"
> >
<q-tooltip>Video</q-tooltip> <q-btn
</q-icon> icon="delete"
<q-card class="multimedia relative-position"> color="primary"
<q-img text-color="white"
:src="media.url" size="md"
class="rounded-borders cursor-pointer fit" class="all-pointer-events absolute delete-button zindex"
@click="openDialog(media.dmsFk)" @click.stop="viewDeleteDms(index)"
v-if="!media.isVideo" round
>
</q-img>
<video
:src="media.url"
class="rounded-borders cursor-pointer fit"
muted="muted"
v-if="media.isVideo"
@click="openDialog(media.dmsFk)"
/> />
</q-card> <q-icon
name="play_circle"
color="primary"
size="xl"
class="absolute-center zindex"
v-if="media.isVideo"
@click.stop="openDialog(media.dmsFk)"
>
<q-tooltip>Video</q-tooltip>
</q-icon>
<q-card class="multimedia relative-position">
<q-img
:src="media.url"
class="rounded-borders cursor-pointer fit"
@click="openDialog(media.dmsFk)"
v-if="!media.isVideo"
>
</q-img>
<video
:src="media.url"
class="rounded-borders cursor-pointer fit"
muted="muted"
v-if="media.isVideo"
@click="openDialog(media.dmsFk)"
/>
</q-card>
</div>
</div> </div>
</div> </div>
<teleport-slot v-if="!quasar.platform.is.mobile" to="#header-actions"> <!-- <teleport-slot v-if="!quasar.platform.is.mobile" to="#header-actions">
<div class="row q-gutter-x-sm"> <div class="row q-gutter-x-sm">
<q-btn @click="uploadFile()" icon="add" color="primary" dense rounded> <q-btn @click="uploadFile()" icon="add" color="primary" dense rounded>
<q-tooltip bottom> {{ t('globals.add') }} </q-tooltip> <q-tooltip bottom> {{ t('globals.add') }} </q-tooltip>
</q-btn> </q-btn>
<q-separator vertical /> <q-separator vertical />
</div> </div>
</teleport-slot> </teleport-slot> -->
<teleport-slot to=".q-footer"> <!-- <teleport-slot to=".q-footer">
<q-tabs align="justify" inline-label narrow-indicator> <q-tabs align="justify" inline-label narrow-indicator>
<q-tab @click="uploadFile()" icon="add_circle" :label="t('globals.add')" /> <q-tab @click="uploadFile()" icon="add_circle" :label="t('globals.add')" />
</q-tabs> </q-tabs>
</teleport-slot> </teleport-slot> -->
<!-- MULTIMEDIA DIALOG START--> <!-- MULTIMEDIA DIALOG START-->
<q-dialog <q-dialog
@ -233,12 +278,9 @@ async function create(files) {
fit="scale-down" fit="scale-down"
v-if="!media.isVideo" v-if="!media.isVideo"
/> />
<q-video <video class="q-ma-none fit" v-if="media.isVideo" controls muted autoplay>
class="q-ma-none fit" <source :src="media.url" type="video/mp4" />
:src="media.url" </video>
v-if="media.isVideo"
muted
/>
</q-carousel-slide> </q-carousel-slide>
</q-carousel> </q-carousel>
</q-dialog> </q-dialog>
@ -246,6 +288,10 @@ async function create(files) {
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.container {
min-height: 80vh;
min-width: 80%;
}
.q-dialog__inner--minimized > div { .q-dialog__inner--minimized > div {
max-width: 80%; max-width: 80%;
} }
@ -290,6 +336,10 @@ async function create(files) {
.zindex { .zindex {
z-index: 1; z-index: 1;
} }
.dragFile {
border: 2px dashed $color-spacer;
}
</style> </style>
<i18n> <i18n>