refactor: edit uploadfile

This commit is contained in:
Net 2024-09-23 17:46:23 +07:00
parent 633fc38160
commit 7a02cb19d7
2 changed files with 508 additions and 642 deletions

View file

@ -1,11 +1,6 @@
<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import {
SaveButton,
UndoButton,
CloseButton,
DeleteButton,
} from 'components/button';
import { DeleteButton } from 'components/button';
import { dialog } from 'stores/utils';
import { useI18n } from 'vue-i18n';
@ -13,18 +8,18 @@ import { VuePDF, usePDF } from '@tato30/vue-pdf';
const { t } = useI18n();
const currentFileSelected = ref<string>('');
const file = defineModel<
const obj = defineModel<
{
name?: string;
group?: string;
url?: string;
file?: File;
}[]
>('file', {
>({
default: [],
});
const currentFile = computed(() => file.value.at(currentIndex.value));
const currentFile = computed(() => obj.value.at(currentIndex.value));
const statusOcr = defineModel<boolean>('statusOcr', { default: false });
const currentMode = ref<string>('');
const currentIndex = ref(0);
@ -40,11 +35,11 @@ const props = withDefaults(
readonly?: boolean;
dropdownList?: { label: string; value: string }[];
hideAction?: boolean;
branch?: boolean;
autoSave?: boolean;
}>(),
{
autoSave: false,
treeFile: () => [],
branch: false,
},
);
@ -60,61 +55,82 @@ const inputFile = (() => {
return _element;
})();
function change(e: Event) {
async function change(e: Event) {
const _element = e.target as HTMLInputElement | null;
const _file = _element?.files?.[0];
currentIndex.value = file.value.length;
if (_file) {
currentIndex.value = file.value.length + 1;
if (!obj.value[currentIndex.value]) {
obj.value = [
...obj.value,
{
name: _file.name,
file: _file,
},
];
currentIndex.value = obj.value.length;
}
const reader = new FileReader();
reader.readAsDataURL(_file);
reader.onload = () => {
if (file.value[currentIndex.value]) {
file.value[currentIndex.value].url = reader.result as string;
console.log(file.value[currentIndex.value]);
if (obj.value[currentIndex.value]) {
obj.value[currentIndex.value].url = reader.result as string;
currentFileSelected.value = _file.name;
}
};
if (_file && file.value[currentIndex.value]) {
file.value[currentIndex.value].file = _file;
file.value[currentIndex.value].group =
props.dropdownList?.[currentIndexDropdownList.value].value;
} else {
const newName =
props.dropdownList?.[currentIndexDropdownList.value].value +
'-' +
_file.name;
file.value.push({
name: props.branch === true ? _file.name : newName,
group: props.dropdownList?.[currentIndexDropdownList.value].value,
file: _file,
});
currentFileSelected.value = props.branch === true ? _file.name : newName;
}
statusOcr.value = true;
if (props.branch === true) {
if (!!props.autoSave) {
emit(
'save',
props.dropdownList?.[currentIndexDropdownList.value].value || '',
inputFile?.files?.[0],
);
} else {
emit(
'sendOcr',
props.dropdownList?.[currentIndexDropdownList.value].value || '',
inputFile?.files?.[0],
);
}
}
}
// function change(e: Event) {
// const _element = e.target as HTMLInputElement | null;
// const _file = _element?.files?.[0];
// currentIndex.value = obj.value.length;
// if (_file) {
// currentIndex.value = obj.value.length + 1;
// const reader = new FileReader();
// reader.readAsDataURL(_file);
// reader.onload = () => {
// if (obj.value[currentIndex.value]) {
// obj.value[currentIndex.value].url = reader.result as string;
// console.log('asd');
// }
// };
// if (_file && obj.value[currentIndex.value]) {
// obj.value[currentIndex.value].file = _file;
// obj.value[currentIndex.value].group =
// props.dropdownList?.[currentIndexDropdownList.value].value;
// } else {
// obj.value.push({
// name: _file.name,
// group: props.dropdownList?.[currentIndexDropdownList.value].value,
// file: _file,
// });
// }
// if (!!props.autoSave) {
// emit(
// 'save',
// props.dropdownList?.[currentIndexDropdownList.value].value || '',
// inputFile?.files?.[0],
// );
// } else {
// }
// }
// }
watch(currentFileSelected, () => {
file.value.findIndex((v, i) => {
obj.value.findIndex((v, i) => {
if (v.name?.includes(currentFileSelected.value)) {
currentIndex.value = i;
@ -136,7 +152,7 @@ const emit = defineEmits<{
const { pdf, pages } = usePDF(computed(() => currentFile.value?.url));
function deleteFileOfBranch(filename: string) {
function deleteFileOfBranch(filename: string, index: number) {
dialog({
color: 'negative',
icon: 'mdi-alert',
@ -145,35 +161,11 @@ function deleteFileOfBranch(filename: string) {
persistent: true,
message: t('dialog.message.confirmDelete'),
action: async () => {
emit('deleteFile', filename);
},
cancel: () => {},
});
}
function deleteFile() {
const tempValue = props.treeFile.find(
(v: any) => v.label === t(currentMode.value),
);
if (!tempValue) return;
const idx = tempValue.file?.findIndex(
(v: any) => v.label === currentFileSelected.value,
);
dialog({
color: 'negative',
icon: 'mdi-alert',
title: t('dialog.title.confirmDelete'),
actionText: t('general.delete'),
persistent: true,
message: t('dialog.message.confirmDelete'),
action: async () => {
emit('deleteFile', currentFileSelected.value);
currentFileSelected.value = tempValue.file?.[idx - 1].label || '';
if (!!props.autoSave) {
emit('deleteFile', filename);
} else {
obj.value.splice(index, 1);
}
},
cancel: () => {},
@ -183,7 +175,7 @@ function deleteFile() {
<template>
<div class="full-width row no-wrap wrapper" style="height: 250px">
<div class="col full-height column no-wrap">
<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"
@ -192,34 +184,61 @@ function deleteFile() {
label="อัปโหลดเอกสาร"
@click="
() => {
if (branch) {
browse();
}
currentIndex = obj.length;
browse();
}
"
></q-btn-dropdown>
</div>
<div class="bordered-l bordered-b q-pa-sm full-height scroll">
<q-item
clickable
v-for="(v, i) in obj"
:key="v.name"
dense
type="button"
class="no-padding items-center rounded"
active-class="menu-active"
:active="currentFileSelected === v.name"
@click="
async () => {
currentFileSelected = v.name || '';
}
"
>
<q-list v-for="(v, i) in dropdownList" :key="v.value">
<q-item
clickable
v-close-popup
@click="
<div class="full-width row items-center justify-between">
<div class="ellipsis col-8">
<q-tooltip>{{ v.name }}</q-tooltip>
{{ v.name }}
</div>
<DeleteButton
iconOnly
@click.stop="
() => {
currentIndexDropdownList = i;
browse();
deleteFileOfBranch(v.name || '', i);
}
"
>
<q-item-section>
<q-item-label>{{ $t(v.label) }}</q-item-label>
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
</div>
/>
</div>
</q-item>
<div class="bordered-l bordered-b q-pa-sm col full-height scroll">
<q-tree
:nodes="treeFile || []"
<!-- <q-tree
:nodes="
Object.values(
obj.reduce<
Record<string, { label: string; file: { label: string }[] }>
>((a, b) => {
if (b.name && !a[b.name]) {
a[b.name] = {
label: b.name,
file: [],
};
}
return a;
}, {}) || {},
) || []
"
node-key="label"
label-key="label"
children-key="file"
@ -233,22 +252,20 @@ function deleteFile() {
<q-tooltip>{{ prop.node.label }}</q-tooltip>
{{ prop.node.label }}
</div>
<div v-if="branch">
<DeleteButton
iconOnly
@click.stop="
() => {
deleteFileOfBranch(prop.node.label);
}
"
/>
</div>
<DeleteButton
iconOnly
@click.stop="
() => {
deleteFileOfBranch(prop.node.label);
}
"
/>
</div>
</template>
</q-tree>
</q-tree> -->
</div>
</div>
<div v-if="!branch" class="col full-height column no-wrap">
<div class="col full-height column no-wrap">
<div
class="bordered row items-center justify-evenly q-pa-sm no-wrap"
style="height: 50px"
@ -302,92 +319,25 @@ function deleteFile() {
<div
class="flex flex-center surface-2 bordered-l bordered-r bordered-b full-height scroll"
>
<template v-if="statusOcr">
<q-spinner color="primary" size="3em" :thickness="2" />
</template>
<template v-else>
<VuePDF
v-if="
currentFile?.url?.split('?').at(0)?.endsWith('.pdf') ||
currentFile?.file?.type === 'application/pdf'
"
class="q-py-md"
:pdf="pdf"
:page="page"
:scale="scale"
/>
<q-img v-else class="q-py-md full-width" :src="currentFile?.url" />
</template>
<VuePDF
style="height: 100%"
v-if="
currentFile?.url?.split('?').at(0)?.endsWith('.pdf') ||
currentFile?.file?.type === 'application/pdf'
"
class="q-py-md"
:pdf="pdf"
:page="page"
:scale="scale"
/>
<q-img
v-else
class="q-py-md full-width"
:src="currentFile?.url"
style="height: 220px; max-width: 300px"
/>
</div>
</div>
<div v-if="!branch" class="col-5 full-height column no-wrap">
<div
class="bordered row items-center justify-between q-pa-sm"
style="height: 50px"
>
{{ currentMode && $t(currentMode) }}
<div class="row" v-if="!hideAction">
<UndoButton icon-only type="button" />
<SaveButton
icon-only
type="button"
@click="
$emit(
'save',
dropdownList?.[currentIndexDropdownList].value || '',
inputFile?.files?.[0],
)
"
/>
</div>
</div>
<div class="q-pa-sm bordered-r bordered-b full-height col scroll">
<slot name="form" :mode="currentMode.split('.').at(-1)" />
<div class="row items-center">
{{ currentFileSelected }}
<CloseButton
icon-only
v-if="!readonly && !!currentFileSelected"
type="button"
class="q-ml-sm"
@click="
() => {
deleteFile();
}
"
/>
</div>
</div>
</div>
<div
v-if="branch"
class="bordered col-8 surface-2 column justify-center items-center no-wrap scroll"
>
<VuePDF
style="height: 100%"
v-if="
currentFile?.url?.split('?').at(0)?.endsWith('.pdf') ||
currentFile?.file?.type === 'application/pdf'
"
class="q-py-md"
:pdf="pdf"
:page="page"
:scale="scale"
/>
<q-img
v-else
class="q-py-md full-width"
style="height: 220px; max-width: 300px"
:src="currentFile?.url"
/>
</div>
</div>
</template>