0
0
Fork 0

photo uplader updates

This commit is contained in:
William Buezas 2024-01-31 09:31:20 -03:00
parent 77f9cc1d80
commit 588a5ff674
3 changed files with 99 additions and 72 deletions

View File

@ -12,30 +12,23 @@ import 'croppie/croppie.css';
import useNotify from 'src/composables/useNotify.js'; import useNotify from 'src/composables/useNotify.js';
import axios from 'axios'; import axios from 'axios';
const props = defineProps({}); const emit = defineEmits(['closeForm']);
const props = defineProps({
id: {
type: String,
default: '',
},
collection: {
type: String,
default: '',
},
});
const { t } = useI18n(); const { t } = useI18n();
const { notify } = useNotify(); const { notify } = useNotify();
const editPhotoFormData = reactive({ const uploadMethodsOptions = [
uploadMethod: 'computer',
file: null,
url: null,
viewportType: {
code: 'normal',
description: t('Normal'),
viewport: {
width: 400,
height: 400,
},
output: {
width: 1200,
height: 1200,
},
},
});
const options = [
{ label: t('Select from computer'), value: 'computer' }, { label: t('Select from computer'), value: 'computer' },
{ label: t('Import from external URL'), value: 'URL' }, { label: t('Import from external URL'), value: 'URL' },
]; ];
@ -79,12 +72,22 @@ const viewportTypes = [
}, },
]; ];
const uploadMethodSelected = ref('computer');
const viewPortTypeSelected = ref(viewportTypes[0]);
const allowedContentTypes = ref(''); const allowedContentTypes = ref('');
const photoContainerRef = ref(null); const photoContainerRef = ref(null);
const editor = ref(null); const editor = ref(null);
const newPhoto = reactive({
id: props.id,
collection: props.collection,
file: null,
url: null,
blob: null,
});
const displayEditor = () => { const displayEditor = () => {
const viewportType = editPhotoFormData.viewportType; const viewportType = viewPortTypeSelected.value;
const viewport = viewportType.viewport; const viewport = viewportType.viewport;
const boundaryWidth = viewport.width + 200; const boundaryWidth = viewport.width + 200;
const boundaryHeight = viewport.height + 200; const boundaryHeight = viewport.height + 200;
@ -100,17 +103,17 @@ const displayEditor = () => {
const viewportSelection = computed({ const viewportSelection = computed({
get() { get() {
return editPhotoFormData.viewportType; return viewPortTypeSelected.value;
}, },
set(val) { set(val) {
editPhotoFormData.viewportType = val; viewPortTypeSelected.value = val;
const hasFile = editPhotoFormData.file || editPhotoFormData.url; const hasFile = newPhoto.files || newPhoto.url;
if (!val || !hasFile) return; if (!val || !hasFile) return;
let file; let file;
if (editPhotoFormData.uploadMethod == 'computer') file = editPhotoFormData.file; if (uploadMethodSelected.value == 'computer') file = newPhoto.files;
else if (editPhotoFormData.uploadMethod == 'URL') file = editPhotoFormData.url; else if (uploadMethodSelected.value == 'URL') file = newPhoto.url;
updatePhotoPreview(file); updatePhotoPreview(file);
}, },
@ -119,12 +122,13 @@ const viewportSelection = computed({
const updatePhotoPreview = (value) => { const updatePhotoPreview = (value) => {
if (value) { if (value) {
displayEditor(); displayEditor();
if (editPhotoFormData.uploadMethod == 'computer') { if (uploadMethodSelected.value == 'computer') {
editPhotoFormData.file = value; newPhoto.files = value;
const reader = new FileReader(); const reader = new FileReader();
reader.onload = (e) => editor.value.bind({ url: e.target.result }); reader.onload = (e) => editor.value.bind({ url: e.target.result });
reader.readAsDataURL(value); reader.readAsDataURL(value);
} else if (editPhotoFormData.uploadMethod == 'URL') { } else if (uploadMethodSelected.value == 'URL') {
newPhoto.url = value;
const img = new Image(); const img = new Image();
img.crossOrigin = 'Anonymous'; img.crossOrigin = 'Anonymous';
img.src = value; img.src = value;
@ -149,47 +153,44 @@ const rotateRight = () => {
const onUploadAccept = () => { const onUploadAccept = () => {
try { try {
if (!this.newPhoto.files) throw new Error(`Select an image`); if (!newPhoto.files && !newPhoto.url) {
notify(t('Select an image'), 'negative');
return;
}
const options = { const options = {
type: 'blob', type: 'blob',
}; };
return this.editor
editor.value
.result(options) .result(options)
.then((blob) => (this.newPhoto.blob = blob)) .then((result) => {
.then(() => this.makeRequest()); const file = new File([result], newPhoto.files?.name || '');
} catch (e) { newPhoto.blob = file;
this.vnApp.showError(this.$t(e.message)); })
return false; .then(() => makeRequest());
} catch (err) {
console.error('Error uploading image');
} finally {
emit('closeForm');
} }
}; };
const makeRequest = async () => { const makeRequest = async () => {
// const options = { const formData = new FormData();
// method: 'POST', const now = Date.vnNew();
// url: `Images/upload`, const timestamp = now.getTime();
// params: this.newPhoto, const fileName = `${newPhoto.files?.name}_${timestamp}`;
// headers: { 'Content-Type': undefined }, formData.append('blob', newPhoto.blob, fileName);
// timeout: this.canceler.promise,
// transformRequest: ([file]) => {
// const formData = new FormData();
// const now = Date.vnNew();
// const timestamp = now.getTime();
// const fileName = `${file.name}_${timestamp}`;
// formData.append('blob', this.newPhoto.blob, fileName); await axios.post('Images/upload', formData, {
params: newPhoto,
headers: {
'Content-Type': 'multipart/form-data',
},
});
// return formData; notify(t('globals.dataSaved'), 'positive');
// },
// data: this.newPhoto.files,
// };
await axios.post('Images/upload');
this.$http(options)
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')))
.then(() => this.emit('response'))
.finally(() => (this.canceler = null));
}; };
</script> </script>
@ -200,7 +201,7 @@ const makeRequest = async () => {
@on-fetch="(data) => (allowedContentTypes = data.join(', '))" @on-fetch="(data) => (allowedContentTypes = data.join(', '))"
auto-load auto-load
/> />
<QForm class="all-pointer-events"> <QForm @submit="onUploadAccept()" class="all-pointer-events">
<QCard class="q-pa-lg"> <QCard class="q-pa-lg">
<span ref="closeButton" class="close-icon" v-close-popup> <span ref="closeButton" class="close-icon" v-close-popup>
<QIcon name="close" size="sm" /> <QIcon name="close" size="sm" />
@ -208,7 +209,7 @@ const makeRequest = async () => {
<h1 class="title">{{ t('Edit photo') }}</h1> <h1 class="title">{{ t('Edit photo') }}</h1>
<div class="row q-gutter-lg"> <div class="row q-gutter-lg">
<div <div
v-show="editPhotoFormData.file || editPhotoFormData.url" v-show="newPhoto.files || newPhoto.url"
class="row q-gutter-lg items-center" class="row q-gutter-lg items-center"
> >
<QIcon <QIcon
@ -242,18 +243,19 @@ const makeRequest = async () => {
<VnRow class="row q-gutter-md q-mb-md"> <VnRow class="row q-gutter-md q-mb-md">
<div class="col"> <div class="col">
<QOptionGroup <QOptionGroup
:options="options" :options="uploadMethodsOptions"
type="radio" type="radio"
v-model="editPhotoFormData.uploadMethod" v-model="uploadMethodSelected"
/> />
</div> </div>
</VnRow> </VnRow>
<VnRow class="row q-gutter-md q-mb-md"> <VnRow class="row q-gutter-md q-mb-md">
<div class="col"> <div class="col">
<QFile <QFile
v-if="editPhotoFormData.uploadMethod === 'computer'" v-if="uploadMethodSelected === 'computer'"
:label="t('File')" :label="t('File')"
:multiple="false" :multiple="false"
v-model="newPhoto.files"
@update:model-value="updatePhotoPreview($event)" @update:model-value="updatePhotoPreview($event)"
:accept="allowedContentTypes" :accept="allowedContentTypes"
class="required" class="required"
@ -279,8 +281,8 @@ const makeRequest = async () => {
</template> </template>
</QFile> </QFile>
<VnInput <VnInput
v-if="editPhotoFormData.uploadMethod === 'URL'" v-if="uploadMethodSelected === 'URL'"
v-model="editPhotoFormData.url" v-model="newPhoto.url"
@update:model-value="updatePhotoPreview($event)" @update:model-value="updatePhotoPreview($event)"
placeholder="https://" placeholder="https://"
/> />
@ -297,6 +299,25 @@ const makeRequest = async () => {
/> />
</div> </div>
</VnRow> </VnRow>
<div class="q-mt-lg row justify-end">
<QBtn
:label="t('globals.save')"
type="submit"
color="primary"
:disabled="isLoading"
:loading="isLoading"
/>
<QBtn
:label="t('globals.cancel')"
type="reset"
color="primary"
flat
class="q-ml-sm"
:disabled="isLoading"
:loading="isLoading"
v-close-popup
/>
</div>
</div> </div>
</div> </div>
</QCard> </QCard>
@ -331,4 +352,5 @@ es:
This photo provider doesn't allow remote downloads: Este proveedor de fotos no permite descargas remotas This photo provider doesn't allow remote downloads: Este proveedor de fotos no permite descargas remotas
Rotate left: Girar a la izquierda Rotate left: Girar a la izquierda
Rotate right: Girar a la derecha Rotate right: Girar a la derecha
Select an image: Selecciona una imagen
</i18n> </i18n>

View File

@ -63,6 +63,7 @@ const warehouseFk = computed({
}, },
}); });
const showWarehouseIconTooltip = ref(true); const showWarehouseIconTooltip = ref(true);
const showEditPhotoForm = ref(false);
onMounted(() => { onMounted(() => {
warehouseFk.value = user.value.warehouseFk; warehouseFk.value = user.value.warehouseFk;
@ -124,8 +125,8 @@ const openRegularizeStockForm = () => {
regularizeStockFormDialog.value.show(); regularizeStockFormDialog.value.show();
}; };
const openEditPhotoForm = () => { const toggleEditPictureForm = () => {
editPhotoFormDialog.value.show(); showEditPhotoForm.value = !showEditPhotoForm.value;
}; };
const cloneItem = async () => { const cloneItem = async () => {
@ -212,11 +213,15 @@ const openCloneDialog = async () => {
size="lg" size="lg"
round round
class="edit-photo-btn" class="edit-photo-btn"
@click="openEditPhotoForm()" @click="toggleEditPictureForm()"
> >
<QIcon name="edit" size="sm" /> <QIcon name="edit" size="sm" />
<QDialog ref="editPhotoFormDialog"> <QDialog ref="editPhotoFormDialog" v-model="showEditPhotoForm">
<EditPictureForm /> <EditPictureForm
collection="catalog"
:id="entityId"
@close-form="toggleEditPictureForm()"
/>
</QDialog> </QDialog>
</QBtn> </QBtn>
</div> </div>

View File

@ -155,11 +155,11 @@ onMounted(async () => {
</QDrawer> </QDrawer>
<QTable <QTable
:rows="rows" :rows="rows"
hide-bottom
row-key="id" row-key="id"
hide-header hide-header
:pagination="{ rowsPerPage: 0 }" :pagination="{ rowsPerPage: 0 }"
class="full-width q-mt-md" class="full-width q-mt-md"
:no-data-label="t('No results')"
> >
<template #body="{ row }"> <template #body="{ row }">
<QTr> <QTr>