feat: import prodect from file
Some checks failed
Spell Check / Spell Check with Typos (push) Failing after 6s

This commit is contained in:
Thanaphon Frappet 2025-04-22 13:58:26 +07:00
parent 74291c0552
commit 8d8ad40de1
3 changed files with 70 additions and 6 deletions

View file

@ -1,8 +1,10 @@
<script lang="ts" setup>
import { ref } from 'vue';
import MainButton from './MainButton.vue';
defineEmits<{
const emit = defineEmits<{
(e: 'click', v: MouseEvent): void;
(e: 'fileSelected', v: File[]): void;
}>();
defineProps<{
iconOnly?: boolean;
@ -10,15 +12,29 @@ defineProps<{
outlined?: boolean;
disabled?: boolean;
dark?: boolean;
importFile?: boolean;
label?: string;
icon?: string;
}>();
const inputRef = ref<HTMLInputElement | null>(null);
function triggerFileInput() {
inputRef.value?.click();
}
function handleFileChange(event: Event) {
const files = (event.target as HTMLInputElement).files;
if (files && files.length > 0) {
emit('fileSelected', Array.from(files));
}
}
</script>
<template>
<MainButton
@click="(e) => $emit('click', e)"
@click="(e) => (importFile ? triggerFileInput() : $emit('click', e))"
v-bind="{ ...$props, ...$attrs }"
:icon="icon || 'mdi-import'"
color="var(--info-bg)"
@ -26,4 +42,13 @@ defineProps<{
>
{{ label || $t('general.import') }}
</MainButton>
<input
ref="inputRef"
type="file"
@change="(e) => handleFileChange(e)"
hidden
accept=".xls, .xlsx , .csv"
multiple
/>
</template>

View file

@ -34,6 +34,7 @@ import {
UndoButton,
ToggleButton,
PasteButton,
ImportButton,
} from 'components/button';
import TableProduct from 'src/components/04_product-service/TableProduct.vue';
import PaginationPageSize from 'src/components/PaginationPageSize.vue';
@ -99,6 +100,8 @@ const {
createWork,
editWork,
deleteWork,
importProduct,
} = productServiceStore;
const currentCopy = ref<{
@ -107,6 +110,7 @@ const currentCopy = ref<{
}>();
const { workNameItems } = storeToRefs(productServiceStore);
const allStat = ref<{ mode: string; count: number }[]>([]);
const stat = ref<
{
icon: string;
@ -2262,7 +2266,6 @@ watch(
},
]"
></q-select>
<q-select
v-if="modeView === false"
id="select-field"
@ -2285,7 +2288,6 @@ watch(
multiple
dense
/>
<q-btn-toggle
v-model="modeView"
id="btn-mode"
@ -2760,6 +2762,26 @@ watch(
</AdvanceSearch>
</template>
</q-input>
<div
class="flex q-mr-auto q-pl-sm"
v-if="productAndServiceTab === 'product'"
>
<input ref="fileImport" type="file" hidden />
<ImportButton
type="file"
import-file
icon-only
@file-selected="
(file) => {
importProduct(
currentIdGroup,
file,
async () => await fetchListOfProduct(),
);
}
"
/>
</div>
<div class="row col-md-6" style="white-space: nowrap">
<q-select
@ -2785,7 +2807,6 @@ watch(
]"
@update:model-value="fetchStatus()"
></q-select>
<q-select
v-if="modeView === false"
:hide-dropdown-icon="$q.screen.lt.sm"
@ -2820,7 +2841,6 @@ watch(
multiple
dense
/>
<q-btn-toggle
v-model="modeView"
id="btn-mode"

View file

@ -194,6 +194,23 @@ const useProductServiceStore = defineStore('api-product-service', () => {
return false;
}
async function importProduct(
productGroupId: string,
files: File[],
fetch: (...args: unknown[]) => void,
) {
const importTasks = files.map((f) => {
const formData = new FormData();
formData.append('file', f);
return api.post('/product/import-product', formData, {
params: { productGroupId },
});
});
await Promise.all(importTasks);
fetch?.();
}
async function fetchListProductById(productId: string) {
const res = await api.get<Product>(`/product/${productId}`);
@ -549,6 +566,8 @@ const useProductServiceStore = defineStore('api-product-service', () => {
fetchImageListById,
addImageList,
deleteImageByName,
importProduct,
};
});