From 526a7dd6285adba5800ad128df2fd546679d147b Mon Sep 17 00:00:00 2001 From: joan Date: Mon, 20 Mar 2023 14:57:09 +0100 Subject: [PATCH 1/5] feature(POS): added responsive table --- CHANGELOG.md | 6 +- src/components/ui/VnFilterPanel.vue | 9 +- src/components/ui/VnSearchbar.vue | 27 +- src/i18n/en/index.js | 1 + src/i18n/es/index.js | 3 +- src/pages/Customer/CustomerPayments.vue | 245 ++++++++++++++++++ src/pages/Customer/CustomerPaymentsFilter.vue | 78 ++++++ src/router/modules/customer.js | 11 +- 8 files changed, 365 insertions(+), 15 deletions(-) create mode 100644 src/pages/Customer/CustomerPayments.vue create mode 100644 src/pages/Customer/CustomerPaymentsFilter.vue diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fffb1b53..436ef4eb8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- Added... +- (Clientes) => Añadida nueva sección "Pagos Web" para gestionar los pagos de todos los clientes +- (Tickets) => Añadida opción en el menú desplegable del ticket para enviar SMS al cliente +- (Reclamaciones) => Añadida nueva sección "Registros de auditoría" +- (Trabajadores) => Añádido módulo de trabajadores +- (General) => Añadida barra de búsqueda general en los listados principales ### Changed diff --git a/src/components/ui/VnFilterPanel.vue b/src/components/ui/VnFilterPanel.vue index e61b4b6c4..d361838e1 100644 --- a/src/components/ui/VnFilterPanel.vue +++ b/src/components/ui/VnFilterPanel.vue @@ -141,8 +141,11 @@ function formatValue(value) { -
- {{ t(`You didn't enter any filter`) }} +
+ {{ t(`No filters applied`) }}
es: - You didn't enter any filter: No has introducido ningún filtro + No filters applied: No se han aplicado filtros Applied filters: Filtros aplicados Remove filters: Eliminar filtros Refresh: Refrescar diff --git a/src/components/ui/VnSearchbar.vue b/src/components/ui/VnSearchbar.vue index 7585f09b3..115530713 100644 --- a/src/components/ui/VnSearchbar.vue +++ b/src/components/ui/VnSearchbar.vue @@ -51,18 +51,27 @@ const props = defineProps({ const router = useRouter(); const route = useRoute(); -const arrayData = useArrayData(props.dataKey, { - url: props.url, - filter: props.filter, - where: props.where, - limit: props.limit, - order: props.order, - userParams: props.userParams, -}); -const store = arrayData.store; +let arrayData = null; +let store = null; const searchText = ref(''); onMounted(() => { + const options = {}; + if (props.url) { + options.url = props.url; + } + if (props.filter) { + options.filter = props.filter; + } + + // url: props.url, + // filter: props.filter, + // where: props.where, + // limit: props.limit, + // order: props.order, + // userParams: props.userParams, + arrayData = useArrayData(props.dataKey, options); + store = arrayData.store; const params = store.userParams; if (params && params.search) { searchText.value = params.search; diff --git a/src/i18n/en/index.js b/src/i18n/en/index.js index be4603ea8..87c427c74 100644 --- a/src/i18n/en/index.js +++ b/src/i18n/en/index.js @@ -61,6 +61,7 @@ export default { customers: 'Customers', list: 'List', createCustomer: 'Create customer', + webPayments: 'Web Payments', summary: 'Summary', basicData: 'Basic Data', }, diff --git a/src/i18n/es/index.js b/src/i18n/es/index.js index b3336ca7a..44dc595c2 100644 --- a/src/i18n/es/index.js +++ b/src/i18n/es/index.js @@ -61,8 +61,9 @@ export default { customers: 'Clientes', list: 'Listado', createCustomer: 'Crear cliente', - summary: 'Resumen', basicData: 'Datos básicos', + summary: 'Resumen', + webPayments: 'Web Payments' }, list: { phone: 'Teléfono', diff --git a/src/pages/Customer/CustomerPayments.vue b/src/pages/Customer/CustomerPayments.vue new file mode 100644 index 000000000..73398288c --- /dev/null +++ b/src/pages/Customer/CustomerPayments.vue @@ -0,0 +1,245 @@ + + + + + + + +es: + Confirm transaction: Confirmar transacción + Transaction ID: ID transacción + Customer ID: ID cliente + Customer Name: Nombre cliente + State: Estado + Dated: Fecha + Amount: Importe + Actions: Acciones + Confirmed: Confirmada + Unconfirmed: Sin confirmar + diff --git a/src/pages/Customer/CustomerPaymentsFilter.vue b/src/pages/Customer/CustomerPaymentsFilter.vue new file mode 100644 index 000000000..1d26b2d6a --- /dev/null +++ b/src/pages/Customer/CustomerPaymentsFilter.vue @@ -0,0 +1,78 @@ + + + + + +en: + params: + orderFk: Order + clientFk: Customer + amount: Amount +es: + params: + orderFk: Pedido + clientFk: Cliente + amount: Importe + Order ID: ID pedido + Customer ID: ID cliente + Amount: Importe + diff --git a/src/router/modules/customer.js b/src/router/modules/customer.js index 7b48413f2..c7e978eec 100644 --- a/src/router/modules/customer.js +++ b/src/router/modules/customer.js @@ -10,7 +10,7 @@ export default { component: RouterView, redirect: { name: 'CustomerMain' }, menus: { - main: ['CustomerList', 'CustomerCreate'], + main: ['CustomerList', 'CustomerPayments', 'CustomerCreate'], card: ['CustomerBasicData'], }, children: [ @@ -29,6 +29,15 @@ export default { }, component: () => import('src/pages/Customer/CustomerList.vue') }, + { + path: 'payments', + name: 'CustomerPayments', + meta: { + title: 'webPayments', + icon: 'vn:onlinepayment', + }, + component: () => import('src/pages/Customer/CustomerPayments.vue') + }, { path: 'create', name: 'CustomerCreate', From f1df8e83f544e5adb7bbde3369c85d7e096f2bb9 Mon Sep 17 00:00:00 2001 From: joan Date: Tue, 21 Mar 2023 09:49:47 +0100 Subject: [PATCH 2/5] Polishing --- jsconfig.json | 1 + src/components/ui/VnSearchbar.vue | 20 +---- src/composables/useArrayData.js | 20 ++++- src/pages/Customer/CustomerPayments.vue | 103 +++++++++++++++++------- src/stores/useArrayDataStore.js | 1 + 5 files changed, 98 insertions(+), 47 deletions(-) diff --git a/jsconfig.json b/jsconfig.json index f4abfc709..9c6a8010d 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -11,6 +11,7 @@ "assets/*": ["src/assets/*"], "boot/*": ["src/boot/*"], "stores/*": ["src/stores/*"], + "filters/*": ["src/filters/*"], "vue$": ["node_modules/vue/dist/vue.runtime.esm-bundler.js"] } }, diff --git a/src/components/ui/VnSearchbar.vue b/src/components/ui/VnSearchbar.vue index 115530713..47a7fc24c 100644 --- a/src/components/ui/VnSearchbar.vue +++ b/src/components/ui/VnSearchbar.vue @@ -51,27 +51,11 @@ const props = defineProps({ const router = useRouter(); const route = useRoute(); -let arrayData = null; -let store = null; +const arrayData = useArrayData(props.dataKey, { ...props }); +const store = arrayData.store; const searchText = ref(''); onMounted(() => { - const options = {}; - if (props.url) { - options.url = props.url; - } - if (props.filter) { - options.filter = props.filter; - } - - // url: props.url, - // filter: props.filter, - // where: props.where, - // limit: props.limit, - // order: props.order, - // userParams: props.userParams, - arrayData = useArrayData(props.dataKey, options); - store = arrayData.store; const params = store.userParams; if (params && params.search) { searchText.value = params.search; diff --git a/src/composables/useArrayData.js b/src/composables/useArrayData.js index 01f8ca294..c7808f9a8 100644 --- a/src/composables/useArrayData.js +++ b/src/composables/useArrayData.js @@ -30,9 +30,20 @@ export function useArrayData(key, userOptions) { }); function setOptions() { + const allowedOptions = [ + 'url', + 'filter', + 'where', + 'order', + 'limit', + 'skip', + 'userParams', + 'userFilter' + ]; if (typeof userOptions === 'object') { for (const option in userOptions) { - if (userOptions[option] == null) continue; + const isEmpty = userOptions[option] == null || userOptions[option] == '' + if (isEmpty || !allowedOptions.includes(option)) continue; if (Object.prototype.hasOwnProperty.call(store, option)) { store[option] = userOptions[option]; @@ -62,6 +73,7 @@ export function useArrayData(key, userOptions) { Object.assign(params, store.userParams); + store.isLoading = true const response = await axios.get(store.url, { signal: canceller.signal, params, @@ -82,6 +94,8 @@ export function useArrayData(key, userOptions) { updateStateParams(); } + store.isLoading = false + canceller = null; } @@ -139,7 +153,8 @@ export function useArrayData(key, userOptions) { }); } - const totalRows = computed(() => store.data && store.data.length | 0); + const totalRows = computed(() => store.data && store.data.length || 0); + const isLoading = computed(() => store.isLoading || false) return { fetch, @@ -152,5 +167,6 @@ export function useArrayData(key, userOptions) { hasMoreData, totalRows, updateStateParams, + isLoading }; } diff --git a/src/pages/Customer/CustomerPayments.vue b/src/pages/Customer/CustomerPayments.vue index 73398288c..c1853ac20 100644 --- a/src/pages/Customer/CustomerPayments.vue +++ b/src/pages/Customer/CustomerPayments.vue @@ -4,15 +4,17 @@ import { ref, computed } from 'vue'; import { useI18n } from 'vue-i18n'; import { useQuasar } from 'quasar'; import { useStateStore } from 'stores/useStateStore'; +import { useArrayData } from 'composables/useArrayData'; import Paginate from 'components/PaginateData.vue'; import VnConfirm from 'components/ui/VnConfirm.vue'; import CustomerDescriptorProxy from './Card/CustomerDescriptorProxy.vue'; -import { toDate, toCurrency } from 'filters'; +import { toDate, toCurrency } from 'filters/index'; import CustomerPaymentsFilter from './CustomerPaymentsFilter.vue'; const stateStore = useStateStore(); const quasar = useQuasar(); const { t } = useI18n(); +const arrayData = useArrayData('CustomerTransactions'); async function confirm(transaction) { quasar @@ -27,11 +29,10 @@ async function confirm(transaction) { .onOk((row) => (row.isConfirmed = true)); } -async function confirmTransaction(transaction) { - const body = { id: transaction.id }; - await axios.post('Clients/confirmTransaction', body); +async function confirmTransaction({ id }) { + await axios.post('Clients/confirmTransaction', { id }); quasar.notify({ - message: 'Transaction confirmed', + message: t('Payment confirmed'), type: 'positive', }); } @@ -49,6 +50,7 @@ const columns = computed(() => [ label: t('Customer ID'), field: (row) => row.clientFk, align: 'right', + sortable: true, }, { name: 'customer', @@ -60,6 +62,7 @@ const columns = computed(() => [ label: t('State'), field: (row) => row.isConfirmed, format: (value) => (value ? t('Confirmed') : t('Unconfirmed')), + align: 'left', sortable: true, }, { @@ -81,6 +84,12 @@ const columns = computed(() => [ grid: false, }, ]); +const isLoading = computed(() => arrayData.isLoading.value); + +function stateColor(row) { + if (row.isConfirmed) return 'positive'; + return 'primary'; +}