From 69f368ede1e036dada739d6e1bbb935367902cf8 Mon Sep 17 00:00:00 2001 From: Thanaphon Frappet Date: Thu, 10 Apr 2025 10:37:48 +0700 Subject: [PATCH 01/61] refactor: handle show name en --- src/pages/05_quotation/QuotationForm.vue | 2 +- src/pages/05_quotation/preview/ViewForm.vue | 2 +- src/pages/11_credit-note/document-view/MainPage.vue | 2 +- src/pages/12_debit-note/document-view/MainPage.vue | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/05_quotation/QuotationForm.vue b/src/pages/05_quotation/QuotationForm.vue index 3322cf0d..66202058 100644 --- a/src/pages/05_quotation/QuotationForm.vue +++ b/src/pages/05_quotation/QuotationForm.vue @@ -1865,7 +1865,7 @@ function covertToNode() { name: selectedWorker.map( (v, i) => `${i + 1}. ` + - `${v.namePrefix}. ${v.firstNameEN} ${v.lastNameEN}`.toUpperCase(), + ` ${v.namePrefix}. ${v.firstNameEN ? `${v.firstNameEN} ${v.lastNameEN}` : `${v.firstName} ${v.lastName}`} `.toUpperCase(), ), }, }) diff --git a/src/pages/05_quotation/preview/ViewForm.vue b/src/pages/05_quotation/preview/ViewForm.vue index 0a12408f..9977a6c7 100644 --- a/src/pages/05_quotation/preview/ViewForm.vue +++ b/src/pages/05_quotation/preview/ViewForm.vue @@ -600,7 +600,7 @@ function print() { details?.worker.map( (v, i) => `${i + 1}. ` + - `${v.namePrefix}. ${v.firstNameEN} ${v.lastNameEN}`.toUpperCase(), + `${v.namePrefix}. ${v.firstNameEN ? `${v.firstNameEN} ${v.lastNameEN}` : `${v.firstName} ${v.lastName}`} `.toUpperCase(), ) || [], }, }) || '-' diff --git a/src/pages/11_credit-note/document-view/MainPage.vue b/src/pages/11_credit-note/document-view/MainPage.vue index f87d4b3b..73024f36 100644 --- a/src/pages/11_credit-note/document-view/MainPage.vue +++ b/src/pages/11_credit-note/document-view/MainPage.vue @@ -494,7 +494,7 @@ function closeAble() { details?.worker.map( (v, i) => `${i + 1}. ` + - `${v.namePrefix}. ${v.firstNameEN} ${v.lastNameEN}`.toUpperCase(), + `${v.namePrefix}. ${v.firstNameEN ? `${v.firstNameEN} ${v.lastNameEN}` : `${v.firstName} ${v.lastName}`} `.toUpperCase(), ) || [], }, }) || '-' diff --git a/src/pages/12_debit-note/document-view/MainPage.vue b/src/pages/12_debit-note/document-view/MainPage.vue index 7233ede7..563b4d02 100644 --- a/src/pages/12_debit-note/document-view/MainPage.vue +++ b/src/pages/12_debit-note/document-view/MainPage.vue @@ -501,7 +501,7 @@ function print() { details?.worker.map( (v, i) => `${i + 1}. ` + - `${v.namePrefix}. ${v.firstNameEN} ${v.lastNameEN}`.toUpperCase(), + `${v.namePrefix}. ${v.firstNameEN ? `${v.firstNameEN} ${v.lastNameEN}` : `${v.firstName} ${v.lastName}`} `.toUpperCase(), ) || [], }, }) || '-' From a5d73ba1ffbdb5b1eaba7a0b982cd80c2e041e3d Mon Sep 17 00:00:00 2001 From: Thanaphon Frappet Date: Thu, 10 Apr 2025 17:21:29 +0700 Subject: [PATCH 02/61] refactor: show prefix on banner --- .../02_personnel-management/MainPage.vue | 28 ++++++++-- src/pages/03_customer-management/MainPage.vue | 52 ++++++++++++++++--- src/pages/05_quotation/MainPage.vue | 13 ++++- .../QuotationFormWorkerSelect.vue | 16 +++++- src/stores/utils/index.ts | 20 +++++++ 5 files changed, 117 insertions(+), 12 deletions(-) diff --git a/src/pages/02_personnel-management/MainPage.vue b/src/pages/02_personnel-management/MainPage.vue index f144fa66..b580508c 100644 --- a/src/pages/02_personnel-management/MainPage.vue +++ b/src/pages/02_personnel-management/MainPage.vue @@ -11,7 +11,7 @@ import useAddressStore from 'stores/address'; import useMyBranch from 'src/stores/my-branch'; import { calculateAge } from 'src/utils/datetime'; import { QSelect, useQuasar, type QTableProps } from 'quasar'; -import { dialog, baseUrl } from 'stores/utils'; +import { dialog, baseUrl, setPrefixName } from 'stores/utils'; import { useNavigator } from 'src/stores/navigator'; import { isRoleInclude, resetScrollBar } from 'src/stores/utils'; import { BranchUserStats } from 'stores/branch/types'; @@ -1559,7 +1559,18 @@ watch( v-model:toggle-status="formData.status" hideFade :toggle-title="$t('status.title')" - :title="`${locale === 'eng' ? `${formData.firstNameEN} ${formData.lastNameEN}` : `${formData.firstName} ${formData.lastName}`}`" + :title=" + setPrefixName( + { + namePrefix: formData.namePrefix, + firstName: formData.firstName, + lastName: formData.lastName, + firstNameEN: formData.firstNameEN, + lastNameEN: formData.lastNameEN, + }, + { locale }, + ) + " :caption="userCode" :img=" `${baseUrl}/user/${currentUser.id}/profile-image/${formData.selectedImage}`.concat( @@ -1837,7 +1848,18 @@ watch( }[formData.gender] " :toggleTitle="$t('status.title')" - :title="`${locale === 'eng' ? `${formData.firstNameEN} ${formData.lastNameEN}` : `${formData.firstName} ${formData.lastName}`}`" + :title=" + setPrefixName( + { + namePrefix: formData.namePrefix, + firstName: formData.firstName, + lastName: formData.lastName, + firstNameEN: formData.firstNameEN, + lastNameEN: formData.lastNameEN, + }, + { locale }, + ) + " :fallbackImg=" { male: '/no-img-man.png', diff --git a/src/pages/03_customer-management/MainPage.vue b/src/pages/03_customer-management/MainPage.vue index e859078e..fd2647c7 100644 --- a/src/pages/03_customer-management/MainPage.vue +++ b/src/pages/03_customer-management/MainPage.vue @@ -4,7 +4,7 @@ import { useI18n } from 'vue-i18n'; import { QSelect, useQuasar } from 'quasar'; import { useRoute, useRouter } from 'vue-router'; import { getUserId, getRole } from 'src/services/keycloak'; -import { baseUrl, waitAll } from 'src/stores/utils'; +import { baseUrl, setPrefixName, waitAll } from 'src/stores/utils'; import { dateFormat } from 'src/utils/datetime'; import { dialogCheckData } from 'stores/utils'; @@ -2004,7 +2004,16 @@ const emptyCreateDialog = ref(false); " :title=" customerFormData.customerType === 'PERS' - ? `${customerFormData.customerBranch[0]?.firstName} ${customerFormData.customerBranch[0]?.lastName}` + ? setPrefixName( + { + namePrefix: customerFormData.customerBranch[0]?.namePrefix, + firstName: customerFormData.customerBranch[0]?.firstName, + lastName: customerFormData.customerBranch[0]?.lastName, + firstNameEN: customerFormData.customerBranch[0]?.firstNameEN, + lastNameEN: customerFormData.customerBranch[0]?.lastNameEN, + }, + { locale }, + ) : customerFormData.customerBranch[0]?.registerName " :caption=" @@ -2452,6 +2461,20 @@ const emptyCreateDialog = ref(false); " :toggleTitle="$t('status.title')" hideFade + :title=" + currentFromDataEmployee + ? setPrefixName( + { + namePrefix: currentFromDataEmployee.namePrefix, + firstName: currentFromDataEmployee.firstName, + lastName: currentFromDataEmployee.lastName, + firstNameEN: currentFromDataEmployee.firstNameEN, + lastNameEN: currentFromDataEmployee.lastNameEN, + }, + { locale }, + ) + : '-' + " @view=" () => { employeeFormState.imageDialog = true; @@ -4052,7 +4075,17 @@ const emptyCreateDialog = ref(false); " :title=" customerFormData.customerType === 'PERS' - ? `${customerFormData.customerBranch[0]?.firstName} ${customerFormData.customerBranch[0]?.lastName}` + ? setPrefixName( + { + namePrefix: customerFormData.customerBranch[0]?.namePrefix, + firstName: customerFormData.customerBranch[0]?.firstName, + lastName: customerFormData.customerBranch[0]?.lastName, + firstNameEN: + customerFormData.customerBranch[0]?.firstNameEN, + lastNameEN: customerFormData.customerBranch[0]?.lastNameEN, + }, + { locale }, + ) : customerFormData.customerBranch[0]?.registerName " :caption=" @@ -4475,9 +4508,16 @@ const emptyCreateDialog = ref(false); fallback-cover="/images/employee-banner.png" :title=" employeeFormState.currentEmployee - ? $i18n.locale === 'eng' - ? `${employeeFormState.currentEmployee.firstNameEN} ${employeeFormState.currentEmployee.lastNameEN}` - : `${employeeFormState.currentEmployee.firstName} ${employeeFormState.currentEmployee.lastName}` + ? setPrefixName( + { + namePrefix: employeeFormState.currentEmployee.namePrefix, + firstName: employeeFormState.currentEmployee.firstName, + lastName: employeeFormState.currentEmployee.lastName, + firstNameEN: employeeFormState.currentEmployee.firstNameEN, + lastNameEN: employeeFormState.currentEmployee.lastNameEN, + }, + { locale }, + ) : '-' " :caption="currentFromDataEmployee.code" diff --git a/src/pages/05_quotation/MainPage.vue b/src/pages/05_quotation/MainPage.vue index c525f856..b134b2dd 100644 --- a/src/pages/05_quotation/MainPage.vue +++ b/src/pages/05_quotation/MainPage.vue @@ -7,7 +7,7 @@ import { useI18n } from 'vue-i18n'; // NOTE: Import stores import useCustomerStore from 'stores/customer'; import { useQuotationStore } from 'src/stores/quotations'; -import { dialog, isRoleInclude, notify } from 'stores/utils'; +import { dialog, isRoleInclude, notify, setPrefixName } from 'stores/utils'; import { useNavigator } from 'src/stores/navigator'; import useFlowStore from 'src/stores/flow'; import useMyBranch from 'stores/my-branch'; @@ -1008,7 +1008,16 @@ async function storeDataLocal(id: string) { " :title=" customerFormData.customerType === 'PERS' - ? `${customerFormData.customerBranch[0]?.firstName} ${customerFormData.customerBranch[0]?.lastName}` + ? setPrefixName( + { + namePrefix: customerFormData.customerBranch[0]?.namePrefix, + firstName: customerFormData.customerBranch[0]?.firstName, + lastName: customerFormData.customerBranch[0]?.lastName, + firstNameEN: customerFormData.customerBranch[0]?.firstNameEN, + lastNameEN: customerFormData.customerBranch[0]?.lastNameEN, + }, + { locale }, + ) : customerFormData.customerBranch[0]?.registerName " :caption=" diff --git a/src/pages/05_quotation/QuotationFormWorkerSelect.vue b/src/pages/05_quotation/QuotationFormWorkerSelect.vue index 155c0b30..1ac736f2 100644 --- a/src/pages/05_quotation/QuotationFormWorkerSelect.vue +++ b/src/pages/05_quotation/QuotationFormWorkerSelect.vue @@ -1,7 +1,7 @@ @@ -10,10 +13,13 @@ defineProps<{ v-if="!hideIcon" id="btn-add" padding="sm" - icon="mdi-plus" + :icon="icon ? undefined : 'mdi-plus'" direction="up" class="color-btn" > + + > + + From ed5a05709a5cabad6b698b0dbc88a522d31ee5da Mon Sep 17 00:00:00 2001 From: puriphatt Date: Thu, 10 Apr 2025 17:23:19 +0700 Subject: [PATCH 05/61] refactor: implement request list action dialog and enhance messenger functionality --- src/pages/08_request-list/MainPage.vue | 45 ++++ .../08_request-list/MessengerExpansion.vue | 4 +- .../08_request-list/RequestListAction .vue | 226 ++++++++++++++++++ src/pages/08_request-list/RequestListView.vue | 5 + .../08_request-list/TableRequestList.vue | 21 ++ 5 files changed, 300 insertions(+), 1 deletion(-) create mode 100644 src/pages/08_request-list/RequestListAction .vue diff --git a/src/pages/08_request-list/MainPage.vue b/src/pages/08_request-list/MainPage.vue index 3c5d5dee..c615b4da 100644 --- a/src/pages/08_request-list/MainPage.vue +++ b/src/pages/08_request-list/MainPage.vue @@ -24,6 +24,8 @@ import { RequestData, RequestDataStatus } from 'src/stores/request-list/types'; import { dialogWarningClose } from 'src/stores/utils'; import { CancelButton, SaveButton } from 'src/components/button'; import { getRole } from 'src/services/keycloak'; +import FloatingActionButton from 'src/components/FloatingActionButton.vue'; +import RequestListAction from './RequestListAction .vue'; const $q = useQuasar(); const navigatorStore = useNavigator(); @@ -32,6 +34,7 @@ const requestListStore = useRequestList(); const { t } = useI18n(); const { data, stats, page, pageMax, pageSize } = storeToRefs(requestListStore); +const requestListActionData = ref(); const refFilter = ref>(); // NOTE: Variable @@ -45,6 +48,7 @@ const pageState = reactive({ rejectCancelDialog: false, rejectCancelReason: '', requestId: '', + requestListActionDialog: false, }); const fieldSelectedOption = computed(() => { @@ -131,6 +135,33 @@ async function submitRejectCancel() { } } +async function openRequestListDialog() { + const ret = await requestListStore.getRequestDataList({ + page: 1, + pageSize: 999, + incomplete: true, + }); + + console.log(ret); + if (ret) { + requestListActionData.value = ret.result; + } + + pageState.requestListActionDialog = true; +} + +async function submitRequestListAction(data: { + form: { responsibleUserLocal: boolean; responsibleUserId: string }; + selected: RequestData[]; +}) { + const res = await requestListStore.updateMessenger( + data.selected.map((v) => v.id), + data.form.responsibleUserId, + ); + + if (res) pageState.requestListActionDialog = false; +} + onMounted(async () => { pageState.gridView = $q.screen.lt.md ? true : false; navigatorStore.current.title = 'requestList.title'; @@ -147,6 +178,13 @@ watch([() => pageState.inputSearch, () => pageState.statusFilter], () => { }); + + diff --git a/src/pages/08_request-list/MessengerExpansion.vue b/src/pages/08_request-list/MessengerExpansion.vue index 24434d89..4b7958cb 100644 --- a/src/pages/08_request-list/MessengerExpansion.vue +++ b/src/pages/08_request-list/MessengerExpansion.vue @@ -13,6 +13,7 @@ const props = defineProps<{ readonly?: boolean; step: Step; responsibleAreaDistrictId?: string; + defaultMessenger?: string; }>(); const emit = defineEmits<{ @@ -85,7 +86,8 @@ function assignToForm() { companyDuty: attributesForm.value.companyDuty ?? false, companyDutyCost: attributesForm.value.companyDutyCost ?? 30, responsibleUserLocal: attributesForm.value.responsibleUserLocal ?? true, - responsibleUserId: attributesForm.value.responsibleUserId ?? '', + responsibleUserId: + attributesForm.value.responsibleUserId || props.defaultMessenger, individualDuty: attributesForm.value.individualDuty ?? false, individualDutyCost: attributesForm.value.individualDutyCost ?? 10, }), diff --git a/src/pages/08_request-list/RequestListAction .vue b/src/pages/08_request-list/RequestListAction .vue new file mode 100644 index 00000000..814f4da3 --- /dev/null +++ b/src/pages/08_request-list/RequestListAction .vue @@ -0,0 +1,226 @@ + + + + diff --git a/src/pages/08_request-list/RequestListView.vue b/src/pages/08_request-list/RequestListView.vue index a908e4d5..94343725 100644 --- a/src/pages/08_request-list/RequestListView.vue +++ b/src/pages/08_request-list/RequestListView.vue @@ -873,6 +873,11 @@ async function submitRejectCancel() { :readonly=" data.requestDataStatus === RequestDataStatus.Canceled " + :default-messenger=" + value.stepStatus[pageState.currentStep - 1] + ? undefined + : data.defaultMessengerId + " :step="{ step: pageState.currentStep, requestWorkId: value.id || '', diff --git a/src/pages/08_request-list/TableRequestList.vue b/src/pages/08_request-list/TableRequestList.vue index 5872f96d..99706193 100644 --- a/src/pages/08_request-list/TableRequestList.vue +++ b/src/pages/08_request-list/TableRequestList.vue @@ -21,6 +21,8 @@ const props = withDefaults( grid?: boolean; visibleColumns?: string[]; hideAction?: boolean; + hideView?: boolean; + checkable?: boolean; }>(), { row: () => [], @@ -36,6 +38,8 @@ defineEmits<{ (e: 'rejectCancel', data: RequestData): void; }>(); +const selected = defineModel('selected'); + function responsiblePerson(quotation: QuotationFull): CreatedBy[] | undefined { const productServiceList = quotation.productServiceList; const tempPerson: CreatedBy[] = []; @@ -106,12 +110,25 @@ function getEmployeeName( card-container-class="q-col-gutter-sm" :rows-per-page-options="[0]" class="full-width" + selection="multiple" + v-model:selected="selected" + :selected-rows-label=" + (n) => + $t('general.selected', { + number: n, + msg: $t('general.list'), + }) + " + :no-data-label="$t('general.noDataTable')" >