refactor: edit upload

This commit is contained in:
Net 2024-09-18 10:58:08 +07:00
parent 23a92601cb
commit 5410dcecf7
2 changed files with 328 additions and 376 deletions

View file

@ -0,0 +1,227 @@
<script setup lang="ts">
import { QTableProps } from 'quasar';
import { computed, ref, watch, toRaw } from 'vue';
import TableComponents from 'src/components/TableComponents.vue';
import ShowAttachent from 'src/components/ShowAttachent.vue';
import DialogForm from 'components/DialogForm.vue';
const obj = defineModel<
{
_meta?: Record<string, any>;
name?: string;
group?: string;
url?: string;
file?: File;
}[]
>({
default: [],
});
const dialog = ref(false);
const splitAttachment = ref(50);
const currentIndex = ref(-1);
const currentIndexDropdownList = ref(0);
const props = defineProps<{
ocr?: (group: any, file: File) => void | Promise<void>;
getFileList?: (group: any) => Promise<typeof obj.value>;
readonly?: boolean;
hideAction?: boolean;
columns: QTableProps['columns'];
menu?: { label: string; value: string; _meta?: Record<string, any> }[];
}>();
function browse() {
inputFile?.click();
}
const inputFile = (() => {
const _element = document.createElement('input');
_element.type = 'file';
_element.accept = 'image/jpeg,image/png';
_element.addEventListener('change', change);
return _element;
})();
const selectedMenu = ref<NonNullable<typeof props.menu>[number]>();
function change(e: Event) {
const _element = e.target as HTMLInputElement | null;
const _file = _element?.files?.[0];
if (_file) {
if (!obj.value[currentIndex.value] && selectedMenu.value) {
currentIndex.value = obj.value.length;
obj.value = [
...obj.value,
{
_meta: structuredClone(toRaw(selectedMenu.value)._meta || {}),
group: selectedMenu.value?.value,
file: _file,
},
];
}
const reader = new FileReader();
reader.readAsDataURL(_file);
reader.onload = () => {
if (obj.value[currentIndex.value]) {
obj.value[currentIndex.value].url = reader.result as string;
}
};
}
dialog.value = true;
}
defineEmits<{
(e: 'submit', obj: any): void;
}>();
</script>
<template>
<div class="full-width row no-wrap wrapper" style="height: 250px">
<div class="col-3 full-height column no-wrap">
<div class="q-pa-sm text-center bordered" style="height: 50px">
<q-btn-dropdown
:disable="readonly"
icon="mdi-upload"
color="info"
label="อัปโหลดเอกสาร"
>
<q-list v-for="(v, i) in menu" :key="v.value">
<q-item
clickable
v-close-popup
@click="
() => {
selectedMenu = menu?.[i];
currentIndex = obj.length;
browse();
}
"
>
<q-item-section>
<q-item-label>{{ $t(v.label) }}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</div>
<div class="bordered-l bordered-b q-pa-sm col full-height scroll">
<template v-if="menu != undefined">
<q-item
clickable
v-for="v in menu"
:key="v.value"
dense
type="button"
class="no-padding items-center rounded full-width"
active-class="menu-active"
:active="selectedMenu?.value === v.value"
@click="
async () => {
selectedMenu = v;
if (getFileList) {
const res = await getFileList(
menu?.[currentIndexDropdownList].value || '',
);
console.log(res);
}
}
"
>
<span class="q-px-md ellipsis q-pa-sm" style="font-size: 16px">
{{ $t(v.label) }}
</span>
</q-item>
</template>
</div>
</div>
<div
v-if="obj"
class="bordered col surface-2 column justify-center items-center no-wrap scroll"
>
<slot name="content">
<template v-if="columns !== undefined">
<div class="full-height full-width q-pa-md">
<TableComponents
buttomDownload
:rows="
obj.map((v, index) => {
return {
branchNo: index + 1,
attachmentName: v.file?.name,
uploadDate: '',
};
})
"
:columns="columns"
></TableComponents>
</div>
</template>
</slot>
</div>
</div>
<DialogForm
style="position: absolute"
height="100vh"
weight="90%"
v-model:modal="dialog"
title="ดูตัวอย่าง"
hideCloseEvent
v-if="obj.length > 0"
:close="
() => {
obj.splice(currentIndex, 1);
dialog = false;
}
"
:submit="
() => {
dialog = false;
}
"
>
<q-splitter class="full-height" v-model="splitAttachment">
<template v-slot:before>
<div class="full-height">
<ShowAttachent
v-if="obj[currentIndex]"
:url="obj[currentIndex].url || ''"
:file="obj[currentIndex].file"
/>
</div>
</template>
<template v-slot:after>
<div class="q-pa-md">
<slot
v-if="obj[currentIndex]"
name="form"
:mode="obj[currentIndex].group"
:meta="obj[currentIndex]._meta"
/>
</div>
</template>
</q-splitter>
</DialogForm>
</template>
<style lang="scss">
.wrapper > * {
height: 300px;
}
.menu-active {
background-color: hsla(var(--info-bg) / 0.1);
color: hsl(var(--info-bg));
}
</style>