diff --git a/src/components/02_personnel-management/FormAddress.vue b/src/components/02_personnel-management/FormAddress.vue index 464e419a..fc86f14a 100644 --- a/src/components/02_personnel-management/FormAddress.vue +++ b/src/components/02_personnel-management/FormAddress.vue @@ -212,6 +212,12 @@ watch(districtId, fetchSubDistrict); :label="$t('province')" class="col-3" :options="addrOptions.provinceOps" + lazy-rules + :rules="[ + (val) => + (val && val.length > 0) || $t('formDialogInputProvinceValidate'), + ]" + @update:model-value="districtId = subDistrictId = zipCode = null" /> ( 'importNationality', ); const trainingPlace = defineModel('trainingPlace'); -const checkpoint = defineModel('checkPoint'); -const checkpointEN = defineModel('checkPointEN'); +const checkpoint = defineModel('checkPoint'); +const checkpointEN = defineModel('checkPointEN'); const agencyFile = defineModel('agencyFile'); const agencyFileList = defineModel<{ name: string; url: string }[]>('agencyFileList'); diff --git a/src/components/02_personnel-management/FormInformation.vue b/src/components/02_personnel-management/FormInformation.vue index da020667..be5764cc 100644 --- a/src/components/02_personnel-management/FormInformation.vue +++ b/src/components/02_personnel-management/FormInformation.vue @@ -44,7 +44,7 @@ async function selectHq(id: string) { map-options options-dense hide-bottom-space - class="col-6" + class="col-4" v-model="hqId" option-label="label" option-value="value" @@ -65,13 +65,31 @@ async function selectHq(id: string) { options-dense clearable hide-bottom-space - class="col-6" + class="col-4" v-model="brId" :label="$t('formDialogInputBrId')" option-label="label" option-value="value" :options="userStore.userOption.brOpts" /> + - - + /> --> import { ref } from 'vue'; +import AppBox from './app/AppBox.vue'; defineProps<{ title: string; isEdit?: boolean; bgOn?: boolean; statusBranch?: string; + badgeLabel?: string; + badgeClass?: string; editData?: (...args: unknown[]) => void; deleteData?: (...args: unknown[]) => void; submit?: (...args: unknown[]) => void; @@ -103,6 +106,13 @@ function reset() { : $t('statusACTIVE') }} + + {{ badgeLabel }} +
@@ -214,4 +224,11 @@ function reset() { background-color: hsla(var(--_branch-badge-bg) / 0.1); } } + +.badge-label { + display: inline-block; + border-radius: var(--radius-6); + background-color: var(--surface-2); + text-wrap: nowrap; +} diff --git a/src/components/FormDialog.vue b/src/components/FormDialog.vue index 0dc12681..f194940d 100644 --- a/src/components/FormDialog.vue +++ b/src/components/FormDialog.vue @@ -9,6 +9,8 @@ defineProps<{ addressTitleEN?: string; addressSeparator?: boolean; branchStatus?: string; + badgeLabel?: string; + badgeClass?: string; submit?: (...args: unknown[]) => void; close?: (...args: unknown[]) => void; }>(); @@ -27,7 +29,7 @@ const zipCode = defineModel('zipCode', { default: '' }); style=" padding: 0; border-radius: var(--radius-2); - max-width: 80%; + max-width: 85%; max-height: 100%; " > @@ -39,7 +41,14 @@ const zipCode = defineModel('zipCode', { default: '' });
{{ title }} -
{{ branchStatus ? `(${branchStatus})` : '' }}
+ {{ branchStatus ? `(${branchStatus})` : '' }} + + {{ badgeLabel }} +
('zipCode', { default: '' }); .form-footer { border-top: 1px solid var(--border-color); } + +.badge-label { + display: inline-block; + border-radius: var(--radius-6); + background-color: var(--surface-2); + text-wrap: nowrap; +} diff --git a/src/css/app.scss b/src/css/app.scss index e8f38c54..1488da86 100644 --- a/src/css/app.scss +++ b/src/css/app.scss @@ -147,3 +147,21 @@ html { color: hsl(var(--positive-fg)); background-color: hsl(var(--positive-bg)); } + +.app-text-male { + color: hsl(var(--gender-male)); +} + +.app-bg-male { + color: hsl(var(--positive-fg)); + background-color: hsl(var(--gender-male)) !important; +} + +.app-text-female { + color: hsl(var(--gender-female)); +} + +.app-bg-female { + color: hsl(var(--positive-fg)); + background-color: hsl(var(--gender-female)) !important; +} diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue index 7bac0065..ed99eaa9 100644 --- a/src/layouts/MainLayout.vue +++ b/src/layouts/MainLayout.vue @@ -13,8 +13,9 @@ import { useI18n } from 'vue-i18n'; import useLoader from 'stores/loader'; import DrawerComponent from 'components/DrawerComponent.vue'; -import GlobalDialog from 'components/GlobalDialog.vue'; import useUserStore from 'src/stores/user'; +import { Option } from 'src/stores/user/types'; +import { dialog } from 'src/stores/utils'; interface NotificationButton { item: string; @@ -34,11 +35,12 @@ const loaderStore = useLoader(); const { visible } = storeToRefs(loaderStore); const { locale } = useI18n({ useScope: 'global' }); +const userStore = useUserStore(); -const logoutModal = ref(false); const leftDrawerOpen = ref(false); const filterUnread = ref(false); const unread = ref(1); +const filterRole = ref(); const currentLanguage = ref('ไทย'); const language: { @@ -100,21 +102,46 @@ function setActive(button: NotificationButton) { } } -function doLogout(confirm: boolean = false) { - logoutModal.value = true; - if (confirm) { - logoutModal.value = false; - logout(); - } +function doLogout() { + dialog({ + icon: 'mdi-logout-variant', + title: 'ยืนยันการออกจากระบบ', + persistent: true, + message: 'คุณต้องการออกจากระบบ ใช่หรือไม่', + action: async () => { + logout(); + }, + }); +} + +function getRoleName(userRoleValue?: string[], roleOptions: Option[]) { + if (!userRoleValue || !roleOptions) return; + + const matchingRole: string | undefined = roleOptions.find( + (role) => role.value === userRoleValue[0], + )?.label; + + return matchingRole ? matchingRole : ''; } onMounted(async () => { const user = getUsername(); const uid = getUserId(); + const userRoles = getRole(); + if (userRoles) { + console.log(userRoles); + filterRole.value = userRoles.filter( + (role) => + role !== 'default-roles-dev' && + role !== 'offline_access' && + role !== 'uma_authorization', + ); + } + if (user === 'admin') return; if (uid) { - const res = await useUserStore().fetchById(uid); + const res = await userStore.fetchById(uid); if (res && res.profileImageUrl) userImage.value = res.profileImageUrl; } @@ -260,7 +287,9 @@ onMounted(async () => { {{ getName() }}
- {{ getRole()?.includes('admin') ? 'Admin' : 'User' }} + {{ + getRoleName(filterRole, userStore.userOption.roleOpts) + }}
@@ -347,14 +376,6 @@ onMounted(async () => { - diff --git a/src/pages/02_personnel-management/MainPage.vue b/src/pages/02_personnel-management/MainPage.vue index 30830668..f8e86cd1 100644 --- a/src/pages/02_personnel-management/MainPage.vue +++ b/src/pages/02_personnel-management/MainPage.vue @@ -70,6 +70,7 @@ const defaultFormData = { checkpointEN: null, }; +const userCode = ref(); const currentUser = ref(); const infoPersonCardEdit = ref(false); const infoPersonId = ref(''); @@ -86,7 +87,6 @@ const userId = ref(); const selectorLabel = ref(''); const hqId = ref(); const brId = ref(); -const code = ref(); const formDialogRef = ref(); const userStats = ref(); const typeStats = ref(); @@ -156,12 +156,33 @@ const selectorList = computed(() => [ ]); async function openDialog(action?: 'FORM' | 'INFO', idEdit?: string) { + if (userStore.userOption.hqOpts.length === 0) { + await userStore.fetchHqOption(); + } + + if (userStore.userOption.roleOpts.length === 0) { + await userStore.fetchRoleOption(); + } + + if (idEdit && userData.value) { + assignFormData(idEdit); + isEdit.value = true; + + if (formData.value.userType === 'AGENCY') { + const result = await userStore.fetchAttachment(idEdit); + + if (result) { + agencyFileList.value = result; + } + } + } + if (action === 'FORM') { modal.value = true; } else if (action === 'INFO') { + if (!userData.value) return; infoDrawer.value = true; infoPersonCardEdit.value = false; - if (!userData.value) return; const user = userData.value.result.find((x) => x.id === idEdit); infoPersonCard.value = user ? [ @@ -182,33 +203,8 @@ async function openDialog(action?: 'FORM' | 'INFO', idEdit?: string) { } statusToggle.value = true; - profileSubmit.value = false; userStore.userOption.brOpts = []; - - if (userStore.userOption.hqOpts.length === 0) { - await userStore.fetchHqOption(); - } - - if (userStore.userOption.hqOpts.length === 1) { - hqId.value = userStore.userOption.hqOpts[0].value; - } - - if (userStore.userOption.roleOpts.length === 0) { - await userStore.fetchRoleOption(); - } - - if (idEdit && userData.value) { - isEdit.value = true; - assignFormData(idEdit); - - if (formData.value.userType === 'AGENCY') { - const result = await userStore.fetchAttachment(idEdit); - - if (result) { - agencyFileList.value = result; - } - } - } + hqId.value = userStore.userOption.hqOpts[0].value; } function undo() { @@ -218,16 +214,16 @@ function undo() { } function onClose() { - code.value = ''; hqId.value = ''; brId.value = ''; userId.value = ''; + userCode.value = ''; urlProfile.value = ''; agencyFile.value = []; - profileSubmit.value = false; modal.value = false; - infoDrawer.value = false; isEdit.value = false; + infoDrawer.value = false; + profileSubmit.value = false; statusToggle.value = true; Object.assign(formData.value, defaultFormData); mapUserType(selectorLabel.value); @@ -300,7 +296,10 @@ async function onSubmit() { userType: selectorLabel.value ?? undefined, }); typeStats.value = await userStore.typeStats(); - + const res = await branchStore.userStats(formData.value.userType); + if (res) { + userStats.value = res; + } onClose(); }, }); @@ -346,7 +345,10 @@ async function onSubmit() { userType: selectorLabel.value ?? undefined, }); typeStats.value = await userStore.typeStats(); - + const res = await branchStore.userStats(formData.value.userType); + if (res) { + userStats.value = res; + } onClose(); }, }); @@ -380,7 +382,6 @@ function mapUserType(label: string) { DELEGATE: 'DELEGATE', AGENCY: 'AGENCY', }; - formData.value.userType = userTypeMap[label]; } @@ -398,6 +399,7 @@ async function toggleStatus(id: string) { async function assignFormData(idEdit: string) { if (!userData.value) return; const foundUser = userData.value.result.find((user) => user.id === idEdit); + if (foundUser) { currentUser.value = foundUser; infoPersonId.value = currentUser.value.id; @@ -456,7 +458,7 @@ async function assignFormData(idEdit: string) { } } - code.value = foundUser.code; + userCode.value = foundUser.code; urlProfile.value = foundUser.profileImageUrl; isEdit.value = true; profileSubmit.value = true; @@ -701,6 +703,8 @@ watch(