Merge branch 'dev/phat-2' into develop

This commit is contained in:
puriphatt 2024-04-19 13:55:42 +07:00
commit 73ed30e704
3 changed files with 132 additions and 16 deletions

View file

@ -1,9 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import useUserStore from 'src/stores/user'; import useUserStore from 'src/stores/user';
import { UserAttachmentDelete } from 'src/stores/user/types';
import { dialog } from 'src/stores/utils';
import { dateFormat } from 'src/utils/datetime'; import { dateFormat } from 'src/utils/datetime';
import { watch } from 'vue';
const userStore = useUserStore(); const userStore = useUserStore();
const userId = defineModel<string>('userId');
const userType = defineModel<string>('userType'); const userType = defineModel<string>('userType');
const registrationNo = defineModel<string | null>('registrationNo'); const registrationNo = defineModel<string | null>('registrationNo');
const startDate = defineModel<Date | null>('startDate'); const startDate = defineModel<Date | null>('startDate');
@ -21,15 +25,43 @@ const importNationality = defineModel<string | null | undefined>(
'importNationality', 'importNationality',
); );
const trainingPlace = defineModel<string | null | undefined>('trainingPlace'); const trainingPlace = defineModel<string | null | undefined>('trainingPlace');
const checkPoint = defineModel<string>('checkPoint'); const checkpoint = defineModel<string>('checkPoint');
const checkPointEN = defineModel<string>('checkPointEN'); const checkpointEN = defineModel<string>('checkPointEN');
const idenDoc = defineModel<File>('idenDoc'); const agencyFile = defineModel<File[]>('agencyFile');
const agencyFileList =
defineModel<{ name: string; url: string }[]>('agencyFileList');
defineProps<{ defineProps<{
dense?: boolean; dense?: boolean;
outlined?: boolean; outlined?: boolean;
readonly?: boolean; readonly?: boolean;
}>(); }>();
function openNewTab(url: string) {
window.open(url, '_blank');
}
function deleteFile(name: string) {
dialog({
color: 'negative',
icon: 'mdi-trash-can-outline',
title: 'ยืนยันการลบเอกสารประจำตัว',
actionText: 'ตกลง',
persistent: true,
message: 'คุณต้องการลบเอกสารประจำตัว ใช่หรือไม่',
action: async () => {
if (!userId.value) return;
const payload: UserAttachmentDelete = {
file: [name],
};
userStore.deleteAttachment(userId.value, payload);
const result = await userStore.fetchAttachment(userId.value);
if (result) {
agencyFileList.value = result;
}
},
});
}
</script> </script>
<template> <template>
<div v-if="userType" class="col-3 app-text-muted"> ข้อมูลการทำงาน</div> <div v-if="userType" class="col-3 app-text-muted"> ข้อมูลการทำงาน</div>
@ -225,7 +257,7 @@ defineProps<{
:borderless="readonly" :borderless="readonly"
label="ด่าน" label="ด่าน"
class="col-6" class="col-6"
v-model="checkPoint" v-model="checkpoint"
/> />
<q-input <q-input
:dense="dense" :dense="dense"
@ -234,18 +266,50 @@ defineProps<{
:borderless="readonly" :borderless="readonly"
label="ด่าน ENG" label="ด่าน ENG"
class="col-6" class="col-6"
v-model="checkPointEN" v-model="checkpointEN"
/> />
<q-file <q-file
:dense="dense" :dense="dense"
:outlined="readonly ? false : outlined" :outlined="readonly ? false : outlined"
:readonly="readonly" :readonly="readonly"
:borderless="readonly" :borderless="readonly"
multiple
append
label="แบบเอกสารประจำตัว" label="แบบเอกสารประจำตัว"
class="col-12" class="col-12"
v-model="idenDoc" v-model="agencyFile"
type="textarea"
/> />
<div v-if="agencyFileList && agencyFileList?.length > 0" class="col-12">
<q-list bordered separator class="rounded" style="padding: 0">
<q-item
v-for="item in agencyFileList"
clickable
:key="item.url"
class="items-center row"
@click="() => openNewTab(item.url)"
>
<q-item-section>
<div class="row items-center justify-between">
<div class="col">
{{ item.name }}
</div>
<q-btn
v-if="!readonly && userId"
rounded
flat
dense
unelevated
size="md"
icon="mdi-trash-can-outline"
class="app-text-negative"
@click.stop="deleteFile(item.name)"
/>
</div>
</q-item-section>
</q-item>
</q-list>
</div>
</div> </div>
</div> </div>
</template> </template>

View file

@ -99,6 +99,7 @@ defineProps<{
} }
.tooltip .tooltip-text { .tooltip .tooltip-text {
border: 1px solid var(--_bg-box-content);
width: 250px; width: 250px;
height: 200px; height: 200px;
background-color: var(--_bg-tooltip-branch); background-color: var(--_bg-tooltip-branch);
@ -120,8 +121,7 @@ defineProps<{
left: var(--_main-page-branch-tooltip); left: var(--_main-page-branch-tooltip);
border-width: 8px; border-width: 8px;
border-style: solid; border-style: solid;
border-color: var(--_bg-tooltip-branch-arrow) transparent transparent border-color: var(--_bg-box-content) transparent transparent transparent;
transparent;
transform: rotate(270deg); transform: rotate(270deg);
} }

View file

@ -5,7 +5,12 @@ import useUserStore from 'stores/user';
import useBranchStore from 'src/stores/branch'; import useBranchStore from 'src/stores/branch';
import { dialog } from 'src/stores/utils'; import { dialog } from 'src/stores/utils';
import { User, UserCreate, UserTypeStats } from 'src/stores/user/types'; import {
User,
UserAttachmentCreate,
UserCreate,
UserTypeStats,
} from 'src/stores/user/types';
import { BranchUserStats } from 'src/stores/branch/types'; import { BranchUserStats } from 'src/stores/branch/types';
import useAddressStore from 'src/stores/address'; import useAddressStore from 'src/stores/address';
@ -20,7 +25,7 @@ import FormInformation from 'src/components/02_personnel-management/FormInformat
import FormPerson from 'src/components/02_personnel-management/FormPerson.vue'; import FormPerson from 'src/components/02_personnel-management/FormPerson.vue';
import FormByType from 'src/components/02_personnel-management/FormByType.vue'; import FormByType from 'src/components/02_personnel-management/FormByType.vue';
import DrawerInfo from 'src/components/DrawerInfo.vue'; import DrawerInfo from 'src/components/DrawerInfo.vue';
import infoForm from 'src/components/02_personnel-management/infoForm.vue'; import InfoForm from 'src/components/02_personnel-management/InfoForm.vue';
import { computed } from 'vue'; import { computed } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
@ -61,6 +66,8 @@ const defaultFormData = {
responsibleArea: null, responsibleArea: null,
username: '', username: '',
status: 'CREATED', status: 'CREATED',
checkpoint: null,
checkpointEN: null,
}; };
const currentUser = ref<User>(); const currentUser = ref<User>();
@ -83,6 +90,8 @@ const code = ref<string>();
const formDialogRef = ref(); const formDialogRef = ref();
const userStats = ref<BranchUserStats[]>(); const userStats = ref<BranchUserStats[]>();
const typeStats = ref<UserTypeStats>(); const typeStats = ref<UserTypeStats>();
const agencyFile = ref<File[]>([]);
const agencyFileList = ref<{ name: string; url: string }[]>([]);
const formData = ref<UserCreate>({ const formData = ref<UserCreate>({
provinceId: null, provinceId: null,
districtId: null, districtId: null,
@ -190,6 +199,14 @@ async function openDialog(action?: 'FORM' | 'INFO', idEdit?: string) {
if (idEdit && userData.value) { if (idEdit && userData.value) {
assignFormData(idEdit); assignFormData(idEdit);
if (formData.value.userType === 'AGENCY') {
const result = await userStore.fetchAttachment(idEdit);
if (result) {
agencyFileList.value = result;
}
}
} }
} }
@ -205,6 +222,7 @@ function onClose() {
brId.value = ''; brId.value = '';
userId.value = ''; userId.value = '';
urlProfile.value = ''; urlProfile.value = '';
agencyFile.value = [];
profileSubmit.value = false; profileSubmit.value = false;
modal.value = false; modal.value = false;
infoDrawer.value = false; infoDrawer.value = false;
@ -215,8 +233,6 @@ function onClose() {
} }
async function onSubmit() { async function onSubmit() {
console.log('hello');
formData.value.profileImage = profileFile.value as File; formData.value.profileImage = profileFile.value as File;
if (isEdit.value === true && userId.value) { if (isEdit.value === true && userId.value) {
dialog({ dialog({
@ -234,7 +250,6 @@ async function onSubmit() {
status: !statusToggle.value ? 'INACTIVE' : 'ACTIVE', status: !statusToggle.value ? 'INACTIVE' : 'ACTIVE',
} as const; } as const;
await userStore.editById(userId.value, formDataEdit); await userStore.editById(userId.value, formDataEdit);
onClose();
if ( if (
hqId.value && hqId.value &&
@ -249,12 +264,25 @@ async function onSubmit() {
); );
} }
if (userId.value && formDataEdit.userType === 'AGENCY') {
if (!agencyFile.value) return;
const payload: UserAttachmentCreate = {
file: agencyFile.value,
};
if (payload?.file) {
await userStore.addAttachment(userId.value, payload);
}
}
userStore.fetchList({ userStore.fetchList({
includeBranch: true, includeBranch: true,
query: !!inputSearch.value ? inputSearch.value : undefined, query: !!inputSearch.value ? inputSearch.value : undefined,
userType: selectorLabel.value ?? undefined, userType: selectorLabel.value ?? undefined,
}); });
typeStats.value = await userStore.typeStats(); typeStats.value = await userStore.typeStats();
onClose();
}, },
}); });
} else { } else {
@ -279,6 +307,19 @@ async function onSubmit() {
result.id, result.id,
); );
} }
if (result && formData.value.userType === 'AGENCY') {
if (!agencyFile.value) return;
const payload: UserAttachmentCreate = {
file: agencyFile.value,
};
if (payload?.file) {
await userStore.addAttachment(result.id, payload);
}
}
selectorLabel.value = formData.value.userType; selectorLabel.value = formData.value.userType;
userStore.fetchList({ userStore.fetchList({
includeBranch: true, includeBranch: true,
@ -286,6 +327,7 @@ async function onSubmit() {
userType: selectorLabel.value ?? undefined, userType: selectorLabel.value ?? undefined,
}); });
typeStats.value = await userStore.typeStats(); typeStats.value = await userStore.typeStats();
onClose(); onClose();
}, },
}); });
@ -364,6 +406,8 @@ async function assignFormData(idEdit: string) {
userRole: foundUser.userRole, userRole: foundUser.userRole,
userType: foundUser.userType, userType: foundUser.userType,
username: foundUser.username, username: foundUser.username,
checkpoint: foundUser.checkpoint,
checkpointEN: foundUser.checkpointEN,
responsibleArea: foundUser.responsibleArea, responsibleArea: foundUser.responsibleArea,
status: foundUser.status, status: foundUser.status,
licenseExpireDate: licenseExpireDate:
@ -630,7 +674,7 @@ watch(inputSearch, async () => {
:editData="() => (infoPersonCardEdit = true)" :editData="() => (infoPersonCardEdit = true)"
> >
<template #info> <template #info>
<infoForm <InfoForm
:readonly="!infoPersonCardEdit" :readonly="!infoPersonCardEdit"
v-model:address="formData.address" v-model:address="formData.address"
v-model:addressEN="formData.addressEN" v-model:addressEN="formData.addressEN"
@ -699,9 +743,14 @@ watch(inputSearch, async () => {
v-model:sourceNationality="formData.sourceNationality" v-model:sourceNationality="formData.sourceNationality"
v-model:importNationality="formData.importNationality" v-model:importNationality="formData.importNationality"
v-model:trainingPlace="formData.trainingPlace" v-model:trainingPlace="formData.trainingPlace"
v-model:checkpoint="formData.checkpoint"
v-model:checkpointEN="formData.checkpointEN"
v-model:agencyFile="agencyFile"
v-model:agencyFileList="agencyFileList"
v-model:userId="userId"
/> />
</template> </template>
</infoForm> </InfoForm>
</template> </template>
</DrawerInfo> </DrawerInfo>
@ -845,6 +894,9 @@ watch(inputSearch, async () => {
v-model:sourceNationality="formData.sourceNationality" v-model:sourceNationality="formData.sourceNationality"
v-model:importNationality="formData.importNationality" v-model:importNationality="formData.importNationality"
v-model:trainingPlace="formData.trainingPlace" v-model:trainingPlace="formData.trainingPlace"
v-model:checkpoint="formData.checkpoint"
v-model:checkpointEN="formData.checkpointEN"
v-model:agencyFile="agencyFile"
/> />
</template> </template>
</FormDialog> </FormDialog>