From e0c1725001a65673b3f224a8e247b4d415759a3b Mon Sep 17 00:00:00 2001 From: Methapon Metanipat <162551568+Methapon-Frappet@users.noreply.github.com> Date: Mon, 27 Jan 2025 10:39:53 +0700 Subject: [PATCH] refactor: responsive (#180) * refactor: can open one dropdown whe lt.md * style: update MainLayout background color and fix avatar border class name * feat: add touch position binding for dropdown in ProfileMenu * refactor: enhance icon styling in DrawerComponent * fix: update screen size conditions * feat: add responsive search and filter functionality in MainPage * feat: update styling and functionality in BasicInformation and MainPage components * feat: package view mode improve layout and responsiveness * feat: improve layout and responsiveness of ProfileBanner component * feat: enhance TreeView component with improved icon layout and cursor pointer styling * feat: update DialogForm component to prevent text wrapping in the center column * feat: enhance FormDocument, PriceDataComponent, and BasicInfoProduct components with layout and styling improvements * feat: enhance ProfileBanner dark tab * feat: 02 => responsive & responsibleArea type * fix: layout header bg condition & 02 filter col * feat: 04 flow => add AddButton component and enhance layout in FormFlow and FlowDialog * feat: 07 => enhance layout and responsiveness * refactor: simplify header structure and improve layout consistency * fix: improve text color in ItemCard and adjust responsive breakpoints in product service group * refactor: 05 => enhance layout responsiveness and improve class bindings in quotation components * refactor: enhance styling and improve props flexibility in dialog and select components * refactor: 05 => enhance layout responsiveness in quotation components * refactor: 05 => enhance layout responsiveness * refactor: 05 => formWorkerAdd * refactor: 05 => formWorkerAdd Product table * refactor: 05 => improve layout responsiveness and enhance component structure * refactor: enhance grid view handling and improve component imports * refactor: improve column classes for better layout consistency * refactor: 09 => enhance layout structure and improve responsiveness in task order views * refactor: 10 => enhance invoice main page layout and improve component interactions * refactor: 13 => enhance receipt main page layout and improve component interactions * refactor: 11 => enhance layout and improve responsiveness in credit note pages * refactor: 01 => screen.sm search & filter * refactor: 01 => improve layout responsiveness and fix variable naming in branch management forms --------- Co-authored-by: puriphatt --- .../01_branch-management/FormBank.vue | 16 +- .../FormBranchContact.vue | 6 +- .../FormBranchInformation.vue | 6 +- .../04_flow-management/FormFlow.vue | 14 +- .../04_product-service/BasicInfoProduct.vue | 6 +- .../04_product-service/BasicInformation.vue | 21 +- .../04_product-service/FormDocument.vue | 1 + .../04_product-service/PriceDataComponent.vue | 2 +- src/components/05_quotation/FormAbout.vue | 2 +- src/components/05_quotation/QuotationCard.vue | 8 +- .../FormBasicInfoAgencies.vue | 5 +- src/components/DialogForm.vue | 2 +- src/components/ItemCard.vue | 4 +- src/components/ProfileBanner.vue | 33 +- src/components/dialog/DialogViewFile.vue | 6 +- src/components/shared/SelectInput.vue | 4 +- src/components/shared/SelectZone.vue | 6 +- src/components/shared/TreeView.vue | 27 +- src/layouts/DrawerComponent.vue | 33 +- src/layouts/MainLayout.vue | 5 +- src/layouts/ProfileMenu.vue | 1 + src/pages/01_branch-management/MainPage.vue | 63 ++- .../02_personnel-management/MainPage.vue | 40 +- src/pages/04_flow-managment/FlowDialog.vue | 10 +- src/pages/04_flow-managment/MainPage.vue | 28 +- src/pages/04_product-service/MainPage.vue | 521 +++++++++++------- src/pages/05_quotation/MainPage.vue | 48 +- src/pages/05_quotation/PaymentForm.vue | 74 +-- src/pages/05_quotation/QuotationForm.vue | 84 ++- .../QuotationFormProductSelect.vue | 16 +- .../05_quotation/QuotationFormReceipt.vue | 7 +- .../QuotationFormWorkerAddDialog.vue | 16 +- .../QuotationFormWorkerSelect.vue | 2 +- src/pages/05_quotation/TableRequest.vue | 10 +- .../07_agencies-management/AgenciesDialog.vue | 12 +- src/pages/07_agencies-management/MainPage.vue | 13 +- src/pages/08_request-list/MainPage.vue | 31 +- src/pages/09_task-order/MainPage.vue | 15 +- .../09_task-order/order_view/MainPage.vue | 100 ++-- .../09_task-order/receive_view/MainPage.vue | 186 ++++--- src/pages/10_invoice/MainPage.vue | 33 +- src/pages/11_credit-note/MainPage.vue | 13 +- .../11_credit-note/RefundInformation.vue | 33 +- src/pages/13_receipt/MainPage.vue | 35 +- src/stores/user/types.ts | 4 +- 45 files changed, 993 insertions(+), 609 deletions(-) diff --git a/src/components/01_branch-management/FormBank.vue b/src/components/01_branch-management/FormBank.vue index eef5f3a1..e9cc4483 100644 --- a/src/components/01_branch-management/FormBank.vue +++ b/src/components/01_branch-management/FormBank.vue @@ -44,7 +44,7 @@ defineEmits<{ }>(); const bankBookOptions = ref[]>([]); -let bankBoookFilter: ( +let bankBookFilter: ( value: string, update: (callbackFn: () => void, afterFn?: (ref: QSelect) => void) => void, ) => void; @@ -77,7 +77,7 @@ function change(e: Event) { onMounted(() => { if (optionStore.globalOption) { - bankBoookFilter = selectFilterOptionRefMod( + bankBookFilter = selectFilterOptionRefMod( ref(optionStore.globalOption.bankBook), bankBookOptions, 'label', @@ -94,7 +94,7 @@ onMounted(() => { watch( () => optionStore.globalOption, () => { - bankBoookFilter = selectFilterOptionRefMod( + bankBookFilter = selectFilterOptionRefMod( ref(optionStore.globalOption.bankBook), bankBookOptions, 'label', @@ -131,8 +131,8 @@ watch(
- + diff --git a/src/components/04_product-service/FormDocument.vue b/src/components/04_product-service/FormDocument.vue index f7aa3ab1..f875122c 100644 --- a/src/components/04_product-service/FormDocument.vue +++ b/src/components/04_product-service/FormDocument.vue @@ -106,6 +106,7 @@ function optionSearch(val: string | null) {
-
+
{{ $t(`general.about`) }} -
+
-import { Icon } from '@iconify/vue/dist/iconify.js'; import { formatNumberDecimal } from 'src/stores/utils'; import BadgeComponent from 'components/BadgeComponent.vue'; import KebabAction from '../shared/KebabAction.vue'; -import MainButton from '../button/MainButton.vue'; defineProps<{ title?: string; @@ -48,7 +46,7 @@ const rand = Math.random();
@@ -378,6 +385,7 @@ const smallBanner = ref(false);
@@ -425,7 +433,7 @@ const smallBanner = ref(false); inline-label mobile-arrows v-model="currentTab" - active-class="active-tab text-weight-bold" + :active-class="`active-tab text-weight-bold ${$q.dark.isActive && 'dark'}`" class="app-text-muted full-width" align="left" v-if="typeof tabsList === 'object'" @@ -435,6 +443,7 @@ const smallBanner = ref(false); :id="`${prefix}-tab-${tab.label}`" v-bind:key="tab.name" class="content-tab text-capitalize" + :class="{ 'tab-label': currentTab !== tab.name }" :name="tab.name" :label="tab.label" /> @@ -526,5 +535,13 @@ const smallBanner = ref(false); .active-tab { color: var(--brand-1); + &.dark { + filter: brightness(1.3); + } +} + +.tab-label { + color: var(--foreground); + opacity: 75%; } diff --git a/src/components/dialog/DialogViewFile.vue b/src/components/dialog/DialogViewFile.vue index db574376..871842bf 100644 --- a/src/components/dialog/DialogViewFile.vue +++ b/src/components/dialog/DialogViewFile.vue @@ -57,13 +57,13 @@ async function downloadImage(url: string | null) {
-
+
-
+
- +
+ +
diff --git a/src/layouts/DrawerComponent.vue b/src/layouts/DrawerComponent.vue index a5012b7d..92a4b67d 100644 --- a/src/layouts/DrawerComponent.vue +++ b/src/layouts/DrawerComponent.vue @@ -5,6 +5,7 @@ import { storeToRefs } from 'pinia'; import { Icon } from '@iconify/vue'; import useMyBranch from 'stores/my-branch'; import { getUserId, getRole } from 'src/services/keycloak'; +import { useQuasar } from 'quasar'; type Menu = { label: string; @@ -17,6 +18,8 @@ type Menu = { }; const router = useRouter(); +const $q = useQuasar(); + const userBranch = useMyBranch(); const { currentMyBranch } = storeToRefs(userBranch); @@ -35,17 +38,6 @@ const currentPath = computed(() => { return router.currentRoute.value.path; }); -// const labelMenu = ref< -// { -// label: string; -// icon: string; -// route: string; -// hidden?: boolean; -// disabled?: boolean; -// isax?: boolean; -// }[] -// >([]); - function navigateTo(label: string, destination?: string) { if (!destination) return; router.push(`${destination}`); @@ -57,6 +49,8 @@ function reActiveMenu() { ); const currMenuIndex = menuData.value.findIndex((m) => m === currMenu); + + if ($q.screen.lt.sm) menuActive.value.fill(false); menuActive.value[currMenuIndex] = true; } @@ -204,7 +198,6 @@ onMounted(async () => { :width="mini ? 80 : 256" show-if-above > -
{ :disable="menu.disabled" :header-class="{ row: true, - 'justify-between': !mini, 'no-padding justify-center': mini, 'active-menu text-weight-bold': menuActive[i], 'text-weight-medium': !menu.disabled, @@ -254,7 +246,12 @@ onMounted(async () => { :class="`isax ${menu.icon}`" style="font-size: 24px" /> - + { border-bottom-right-radius: var(--radius-2); } } + +.fix-icon { + color: var(--text-mute-2) !important; +} + +:deep(.q-item.q-item-type.row.no-wrap.q-item--dense.disabled) { + opacity: 30% !important; +} diff --git a/src/layouts/MainLayout.vue b/src/layouts/MainLayout.vue index 02e0cabe..168b895d 100644 --- a/src/layouts/MainLayout.vue +++ b/src/layouts/MainLayout.vue @@ -208,6 +208,9 @@ onMounted(async () => {
{ } } -.avartar-border { +.avatar-border { margin-top: 24px; border: 5px solid var(--surface-1); border-radius: 50%; diff --git a/src/layouts/ProfileMenu.vue b/src/layouts/ProfileMenu.vue index 1c7451ea..82980933 100644 --- a/src/layouts/ProfileMenu.vue +++ b/src/layouts/ProfileMenu.vue @@ -317,6 +317,7 @@ onMounted(async () => { max-width="200" :offset="[10, 0]" style="width: 160px" + :touch-position="$q.screen.lt.sm" >
diff --git a/src/pages/01_branch-management/MainPage.vue b/src/pages/01_branch-management/MainPage.vue index abaeb972..e00bc118 100644 --- a/src/pages/01_branch-management/MainPage.vue +++ b/src/pages/01_branch-management/MainPage.vue @@ -6,7 +6,7 @@ import { Icon } from '@iconify/vue'; import { BranchContact } from 'stores/branch-contact/types'; import { useQuasar } from 'quasar'; import { useI18n } from 'vue-i18n'; -import type { QTableProps, QTableSlots } from 'quasar'; +import type { QSelect, QTableProps, QTableSlots } from 'quasar'; import { resetScrollBar } from 'src/stores/utils'; import useBranchStore from 'stores/branch'; import useFlowStore from 'stores/flow'; @@ -72,6 +72,7 @@ const typeBranchItem = [ color: 'var(--blue-6-hsl)', }, ]; +const refFilter = ref>(); const holdDialog = ref(false); const isSubCreate = ref(false); const columns = [ @@ -302,7 +303,10 @@ const stats = ref< }[] >([]); -const splitterModel = ref(25); +// const splitterModel = ref(25); +const splitterModel = computed(() => + $q.screen.lt.md ? (currentHq.value.id ? 0 : 100) : 25, +); const defaultFormData = { headOfficeId: null, @@ -1020,12 +1024,13 @@ watch(currentHq, () => { class="col" before-class="overflow-hidden" after-class="overflow-hidden" + :disable="$q.screen.lt.sm" > -
+
state.search, getWorkerList); ...data, _selectedIndex: selectedIndex(data), }))" - class="col-2" + class="col-md-2 col-sm-6 col-12" >
-
+
state.search, getWorkerList); expand-icon="mdi-chevron-down-circle" header-class="q-py-sm text-medium text-body items-center surface-1" v-for="{ id, amount, worker, product } in productServiceList" + :key="id" >