forked from verdnatura/salix-front
photo uplader updates
This commit is contained in:
parent
77f9cc1d80
commit
588a5ff674
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in New Issue