From b13bcea3319f260f5f9eed75fc490f3a620c64d5 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Tue, 22 Apr 2025 17:43:29 +0200 Subject: [PATCH 1/5] feat: add VnMultiCheck component for multi-selection functionality --- src/components/VnTable/VnTable.vue | 30 ++++++++++++++- src/components/common/VnMultiCheck.vue | 51 ++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/components/common/VnMultiCheck.vue diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index 7e9ab85cb..6af2ccf7e 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -33,7 +33,8 @@ import VnTableOrder from 'src/components/VnTable/VnOrder.vue'; import VnTableFilter from './VnTableFilter.vue'; import { getColAlign } from 'src/composables/getColAlign'; import RightMenu from '../common/RightMenu.vue'; -import VnScroll from '../common/VnScroll.vue' +import VnScroll from '../common/VnScroll.vue'; +import VnMultiCheck from '../common/VnMultiCheck.vue'; const arrayData = useArrayData(useAttrs()['data-key']); const $props = defineProps({ @@ -157,6 +158,7 @@ const CARD_MODE = 'card'; const TABLE_MODE = 'table'; const mode = ref(CARD_MODE); const selected = ref([]); +const selectAll = ref(false); const hasParams = ref(false); const CrudModelRef = ref({}); const showForm = ref(false); @@ -638,6 +640,23 @@ const rowCtrlClickFunction = computed(() => { }; return () => {}; }); +const handleMultiCheck = (value) => { + if (value) { + selected.value = tableRef.value.rows; + } else { + selected.value = []; + } + emit('update:selected', selected.value); +}; + +const handleSelectedAll = (data) => { + if (data) { + selected.value = data; + } else { + selected.value = []; + } + emit('update:selected', selected.value); +}; + +en: + Select all: 'Select all ({rows})' +fr: + Select all: 'Sélectionner tout ({rows})' +es: + Select all: Seleccionar todo ({rows}) +de: + Select all: 'Alle auswählen ({rows})' +it: + Select all: 'Seleziona tutto ({rows})' +pt: + Select all: Selecionar tudo ({rows}) + diff --git a/src/pages/Customer/Notifications/CustomerNotificationsCampaignConsumption.vue b/src/pages/Customer/Notifications/CustomerNotificationsCampaignConsumption.vue index f637c7e0a..141a02bfc 100644 --- a/src/pages/Customer/Notifications/CustomerNotificationsCampaignConsumption.vue +++ b/src/pages/Customer/Notifications/CustomerNotificationsCampaignConsumption.vue @@ -98,7 +98,9 @@ onMounted(async () => { - {{ t('Campaign consumption') }} + {{ + t('Campaign consumption', { rows: $props.clients.length }) + }} { valentinesDay: Valentine's Day mothersDay: Mother's Day allSaints: All Saints' Day + Campaign consumption: Campaign consumption ({rows}) es: params: valentinesDay: Día de San Valentín mothersDay: Día de la Madre allSaints: Día de Todos los Santos - Campaign consumption: Consumo campaña + Campaign consumption: Consumo campaña ({rows}) Campaign: Campaña From: Desde To: Hasta From 0c0d21e53e92737ccc39bb2eb8f04b4521b33529 Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 23 Apr 2025 19:24:07 +0200 Subject: [PATCH 3/5] feat: add multi-check support to VnTable and VnMultiCheck components --- src/components/VnTable/VnTable.vue | 41 ++++++++------- src/components/common/VnMultiCheck.vue | 51 ++++++++++++------- .../Notifications/CustomerNotifications.vue | 3 ++ 3 files changed, 59 insertions(+), 36 deletions(-) diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index 6af2ccf7e..1a4d5e552 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -114,6 +114,10 @@ const $props = defineProps({ type: Object, default: () => ({}), }, + multiCheck: { + type: Object, + default: () => ({}), + }, crudModel: { type: Object, default: () => ({}), @@ -197,10 +201,10 @@ const onVirtualScroll = ({ to }) => { handleScroll(); const virtualScrollContainer = tableRef.value?.$el?.querySelector('.q-table__middle'); if (virtualScrollContainer) { - virtualScrollContainer.dispatchEvent(new CustomEvent('scroll')); - if (vnScrollRef.value) { - vnScrollRef.value.updateScrollContainer(virtualScrollContainer); - } + virtualScrollContainer.dispatchEvent(new CustomEvent('scroll')); + if (vnScrollRef.value) { + vnScrollRef.value.updateScrollContainer(virtualScrollContainer); + } } }; @@ -343,11 +347,11 @@ function handleOnDataSaved(_) { else $props.create.onDataSaved(_); } function handleScroll() { - if ($props.crudModel.disableInfiniteScroll) return; - const tMiddle = tableRef.value.$el.querySelector('.q-table__middle'); - const { scrollHeight, scrollTop, clientHeight } = tMiddle; - const isAtBottom = Math.abs(scrollHeight - scrollTop - clientHeight) <= 40; - if (isAtBottom) CrudModelRef.value.vnPaginateRef.paginate(); + if ($props.crudModel.disableInfiniteScroll) return; + const tMiddle = tableRef.value.$el.querySelector('.q-table__middle'); + const { scrollHeight, scrollTop, clientHeight } = tMiddle; + const isAtBottom = Math.abs(scrollHeight - scrollTop - clientHeight) <= 40; + if (isAtBottom) CrudModelRef.value.vnPaginateRef.paginate(); } function handleSelection({ evt, added, rows: selectedRows }, rows) { if (evt?.shiftKey && added) { @@ -680,7 +684,7 @@ const handleSelectedAll = (data) => { { ref="tableRef" v-bind="table" :class="[ - 'vnTable', - table ? 'selection-cell' : '', - $props.footer ? 'last-row-sticky' : '', + 'vnTable', + table ? 'selection-cell' : '', + $props.footer ? 'last-row-sticky' : '', ]" wrap-cells :columns="splittedColumns.columns" @@ -720,7 +724,10 @@ const handleSelectedAll = (data) => { :data-cy > - diff --git a/src/components/common/VnMultiCheck.vue b/src/components/common/VnMultiCheck.vue index 1d4898503..19b93ffa9 100644 --- a/src/components/common/VnMultiCheck.vue +++ b/src/components/common/VnMultiCheck.vue @@ -4,47 +4,60 @@ import VnCheckbox from './VnCheckbox.vue'; import axios from 'axios'; import { toRaw } from 'vue'; import { useI18n } from 'vue-i18n'; - +import { useRoute } from 'vue-router'; +const route = useRoute(); const { t } = useI18n(); const model = defineModel({ type: [Boolean] }); const props = defineProps({ + expand: { + type: Boolean, + default: false, + }, url: { type: String, default: null, required: true, }, + searchUrl: { + type: [String, Boolean], + default: 'table', + }, }); const value = ref(false); const rows = ref(0); -defineEmits(['update:selected', 'select:all']); -const onClick = async () => { +const onClick = () => { if (value.value) { + const { filter } = JSON.parse(route.query[props.searchUrl]); + filter.limit = 0; + const params = { + params: { filter: JSON.stringify(filter) }, + }; axios - .get(props.url, { - params: { - filter: null, - }, + .get(props.url, params) + .then(({ data }) => { + rows.value = data; }) - .then((response) => { - rows.value = response.data; - console.log(response.data); - }) - .catch((error) => { - console.error(error); - }); + .catch(console.error); } }; +defineEmits(['update:selected', 'select:all']);