170 lines
4.9 KiB
Vue
170 lines
4.9 KiB
Vue
<script lang="ts" setup>
|
|
import { onMounted, ref, watch } from 'vue';
|
|
import { DeleteButton, EditButton, SaveButton, UndoButton } from '../button';
|
|
// import { useI18n } from 'vue-i18n';
|
|
// import { storeToRefs } from 'pinia';
|
|
|
|
// import useProductServiceStore from 'stores/product-service';
|
|
|
|
import NoData from '../NoData.vue';
|
|
|
|
const nameList = defineModel<{ id: string; name: string; isEdit: boolean }[]>(
|
|
'nameList',
|
|
{ required: true },
|
|
);
|
|
|
|
const refForm = ref();
|
|
const cloneList = ref();
|
|
const isAdd = ref(false);
|
|
const inputName = ref<HTMLInputElement[]>([]);
|
|
|
|
function nameExist(name: string) {
|
|
const listToCheck = cloneList.value.filter((clone) => !clone.isEdit);
|
|
const alreadyExist = listToCheck.find((clone) => clone.name === name);
|
|
|
|
return alreadyExist ? true : false;
|
|
}
|
|
|
|
function isWorkNameEdit() {
|
|
return cloneList.value.some((i: { isEdit: boolean }) => i.isEdit === true);
|
|
}
|
|
|
|
async function assignClone() {
|
|
cloneList.value = await JSON.parse(JSON.stringify(nameList.value));
|
|
}
|
|
|
|
defineExpose({
|
|
isWorkNameEdit,
|
|
});
|
|
|
|
defineEmits<{
|
|
(e: 'delete', id: string, noDialog?: boolean): void;
|
|
(e: 'edit', id: string, data: { name: string }): void;
|
|
(e: 'add', data: { name: string; productId: []; order: number }): void;
|
|
}>();
|
|
|
|
onMounted(async () => {
|
|
await assignClone();
|
|
});
|
|
|
|
watch(
|
|
() => nameList.value.length,
|
|
async () => {
|
|
await assignClone();
|
|
if (!isAdd.value) return;
|
|
cloneList.value[cloneList.value.length - 1].isEdit = true;
|
|
setTimeout(() => {
|
|
inputName.value[cloneList.value.length - 1].focus();
|
|
isAdd.value = false;
|
|
}, 150);
|
|
},
|
|
);
|
|
</script>
|
|
<template>
|
|
<div v-if="cloneList" class="full-width column no-wrap full-height">
|
|
<div class="bordered rounded surface-1 flex col column justify-between">
|
|
<q-list v-if="cloneList.length > 0" class="full-width col scroll">
|
|
<q-item
|
|
class="items-center row q-px-lg"
|
|
v-for="(item, index) in cloneList"
|
|
:key="index"
|
|
>
|
|
<q-form
|
|
ref="refForm"
|
|
greedy
|
|
@submit.prevent
|
|
@validation-success="
|
|
() => {
|
|
$emit('edit', item.id, { name: item.name });
|
|
item.isEdit = false;
|
|
}
|
|
"
|
|
class="row full-width"
|
|
>
|
|
<q-input
|
|
lazy-rules="ondemand"
|
|
ref="inputName"
|
|
:for="`input-work-name-${index}`"
|
|
dense
|
|
class="col q-mr-md"
|
|
v-model="item.name"
|
|
placeholder="ชื่องาน"
|
|
:borderless="!item.isEdit"
|
|
:readonly="!item.isEdit"
|
|
:outlined="item.isEdit"
|
|
:rules="[
|
|
(val: string) => val.length > 2 || $t('form.error.required'),
|
|
(val: string) =>
|
|
(val.length > 0 && !nameExist(val)) ||
|
|
$t('productService.service.workAlreadyExist'),
|
|
]"
|
|
hide-bottom-space
|
|
></q-input>
|
|
<EditButton
|
|
v-if="!item.isEdit"
|
|
icon-only
|
|
id="btn-edit-work-name"
|
|
:disabled="isWorkNameEdit()"
|
|
@click="item.isEdit = true"
|
|
/>
|
|
<SaveButton
|
|
v-else
|
|
icon-only
|
|
id="btn-save-work-name"
|
|
type="submit"
|
|
@click.stop
|
|
/>
|
|
<DeleteButton
|
|
v-if="!item.isEdit"
|
|
icon-only
|
|
id="btn-delete-work-name"
|
|
:disabled="isWorkNameEdit()"
|
|
@click="$emit('delete', item.id)"
|
|
/>
|
|
<UndoButton
|
|
v-else
|
|
icon-only
|
|
id="btn-undo-work-name"
|
|
@click="
|
|
() => {
|
|
assignClone();
|
|
if (nameList[nameList.length - 1].name === '') {
|
|
$emit('delete', cloneList[cloneList.length - 1].id, true);
|
|
cloneList = cloneList.filter((item) => item.name !== '');
|
|
nameList = nameList.filter((item) => item.name !== '');
|
|
}
|
|
}
|
|
"
|
|
/>
|
|
</q-form>
|
|
</q-item>
|
|
</q-list>
|
|
<div v-else class="flex col justify-center items-center">
|
|
<NoData />
|
|
</div>
|
|
<div class="bordered-t full-width">
|
|
<q-item
|
|
clickable
|
|
:disable="isWorkNameEdit()"
|
|
@click="
|
|
() => {
|
|
$emit('add', { name: '', productId: [], order: 1 }),
|
|
(isAdd = true);
|
|
}
|
|
"
|
|
>
|
|
<span class="q-px-lg flex items-center app-text-muted-2">
|
|
<q-icon name="mdi-plus" class="q-mr-md" />
|
|
{{ $t('productService.service.addWork') }}
|
|
</span>
|
|
</q-item>
|
|
</div>
|
|
</div>
|
|
<!-- <div
|
|
v-else
|
|
class="bordered rounded surface-1 flex justify-center items-center col"
|
|
>
|
|
<NoData />
|
|
</div> -->
|
|
</div>
|
|
</template>
|