From 197ebed39ddc38b9b89a63bc0c61e1aaab49fcc0 Mon Sep 17 00:00:00 2001 From: alexm Date: Tue, 15 Apr 2025 11:47:47 +0200 Subject: [PATCH 01/52] feat: refs #8224 add context menu forVnTable --- src/components/VnTable/VnContextMenu.vue | 90 ++++++++++++++++++++++++ src/components/VnTable/VnTable.vue | 12 +++- 2 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 src/components/VnTable/VnContextMenu.vue diff --git a/src/components/VnTable/VnContextMenu.vue b/src/components/VnTable/VnContextMenu.vue new file mode 100644 index 000000000..f9922538e --- /dev/null +++ b/src/components/VnTable/VnContextMenu.vue @@ -0,0 +1,90 @@ + + + +es: + Filter by selection: Filtro por selección + Exclude selection: Excluir selección + Remove filter: Quitar filtro por selección + Remove all filters: Eliminar todos los filtros + Copy value: Copiar valor + diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index 29a9200f0..7353c3726 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -33,6 +33,7 @@ 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 VnContextMenu from './VnContextMenu.vue'; const arrayData = useArrayData(useAttrs()['data-key']); const $props = defineProps({ @@ -169,8 +170,9 @@ const orders = ref(useFilterParams($attrs['data-key']).orders); const app = inject('app'); const tableHeight = useTableHeight(); -const editingRow = ref(null); -const editingField = ref(null); +const editingRow = ref(); +const editingField = ref(); +const contextMenuRef = ref({}); const isTableMode = computed(() => mode.value == TABLE_MODE); const selectRegex = /select/; const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']); @@ -195,6 +197,10 @@ onBeforeMount(() => { }); onMounted(async () => { + document.addEventListener('contextmenu', (event) => { + event.preventDefault(); + contextMenuRef.value.handler(event); + }); if ($props.isEditable) document.addEventListener('click', clickHandler); mode.value = quasar.platform.is.mobile && !$props.disableOption?.card @@ -777,6 +783,7 @@ const rowCtrlClickFunction = computed(() => { ]" :data-row-index="rowIndex" :data-col-field="col?.name" + :data-col-value="row?.[col?.name]" >
{ + en: From 4ad9a3e613143fe74d8379d705e8aedd84e16c88 Mon Sep 17 00:00:00 2001 From: alexm Date: Wed, 23 Apr 2025 13:39:33 +0200 Subject: [PATCH 02/52] feat: refs #8224 exclude filter --- src/components/VnTable/VnContextMenu.vue | 70 +++++++++++++++------ src/components/VnTable/VnFilter.vue | 3 + src/components/VnTable/VnTable.vue | 3 +- src/components/VnTable/VnTableFilter.vue | 7 ++- src/components/common/VnSelect.vue | 67 ++++++++++++++++---- src/pages/Ticket/TicketList.vue | 80 +++++++++++++++--------- 6 files changed, 167 insertions(+), 63 deletions(-) diff --git a/src/components/VnTable/VnContextMenu.vue b/src/components/VnTable/VnContextMenu.vue index f9922538e..7004469a9 100644 --- a/src/components/VnTable/VnContextMenu.vue +++ b/src/components/VnTable/VnContextMenu.vue @@ -9,18 +9,18 @@ const colField = ref(); let colValue = ''; let textValue = ''; +defineExpose({ handler }); + const arrayData = defineModel({ type: Array, }); -defineExpose({ - handler, -}); - function handler(event) { + const clickedElement = event.target.closest('td'); + if (!clickedElement) return; + target.value = event.target; qmenuRef.value.show(); - const clickedElement = event.target.closest('td'); colField.value = clickedElement.getAttribute('data-col-field'); colValue = isNaN(+clickedElement.getAttribute('data-col-value')) ? clickedElement.getAttribute('data-col-value') @@ -45,22 +45,22 @@ function getDeepestText(node) { return lastText; } -function selectionFilter() { - arrayData.value.addFilter({ params: { [colField.value]: colValue } }); +async function selectionFilter() { + await arrayData.value.addFilter({ params: { [colField.value]: colValue } }); } -function selectionExclude() { - arrayData.value.addFilter({ - params: { [colField.value]: { neq: +colValue } }, +async function selectionExclude() { + await arrayData.value.addFilter({ + params: { [colField.value]: { neq: colValue } }, }); } -function selectionRemoveFilter() { - arrayData.value.addFilter({ params: { [colField.value]: undefined } }); +async function selectionRemoveFilter() { + await arrayData.value.addFilter({ params: { [colField.value]: undefined } }); } -function removeAllFilters() { - arrayData.value.applyFilter({ params: {} }); +async function removeAllFilters() { + await arrayData.value.applyFilter({ params: {} }); } function copyValue() { @@ -72,12 +72,42 @@ function copyValue() { } diff --git a/src/components/VnTable/VnFilter.vue b/src/components/VnTable/VnFilter.vue index 82d7c772c..1ebad1abe 100644 --- a/src/components/VnTable/VnFilter.vue +++ b/src/components/VnTable/VnFilter.vue @@ -136,6 +136,9 @@ async function addFilter(value, name) { value = value === '' ? undefined : value; let field = columnFilter.value?.name ?? $props.column.name ?? name; + delete arrayData.store?.userParams?.[field]; + delete arrayData.store?.filter?.where?.[field]; + if (columnFilter.value?.inWhere) { if (columnFilter.value.alias) field = columnFilter.value.alias + '.' + field; return await arrayData.addFilterWhere({ [field]: value }); diff --git a/src/components/VnTable/VnTable.vue b/src/components/VnTable/VnTable.vue index c94089604..3eea028d8 100644 --- a/src/components/VnTable/VnTable.vue +++ b/src/components/VnTable/VnTable.vue @@ -210,11 +210,11 @@ onBeforeMount(() => { }); onMounted(async () => { + if ($props.isEditable) document.addEventListener('click', clickHandler); document.addEventListener('contextmenu', (event) => { event.preventDefault(); contextMenuRef.value.handler(event); }); - if ($props.isEditable) document.addEventListener('click', clickHandler); mode.value = quasar.platform.is.mobile && !$props.disableOption?.card ? CARD_MODE @@ -238,6 +238,7 @@ onMounted(async () => { onUnmounted(async () => { if ($props.isEditable) document.removeEventListener('click', clickHandler); + document.removeEventListener('contextmenu', {}); }); watch( diff --git a/src/components/VnTable/VnTableFilter.vue b/src/components/VnTable/VnTableFilter.vue index a7b2108ed..5d24245ac 100644 --- a/src/components/VnTable/VnTableFilter.vue +++ b/src/components/VnTable/VnTableFilter.vue @@ -77,7 +77,12 @@ function columnName(col) { + en: params: @@ -107,6 +113,8 @@ en: mine: Mine showBadDates: Show future items hasMinPrice: Has Min Price + date: Date + incompatibleFilters: Cannot select "Date" and "Show future items" at the same time es: params: buyerFk: Comprador @@ -116,4 +124,6 @@ es: mine: Para mi showBadDates: Ver items a futuro hasMinPrice: Precio mínimo + date: Fecha + incompatibleFilters: No se puede seleccionar "Fecha" y "Ver items a futuro" a la vez From b1d637f382fe1e955fe91919aecc56d5146a9bb6 Mon Sep 17 00:00:00 2001 From: alexm Date: Fri, 25 Apr 2025 14:13:45 +0200 Subject: [PATCH 08/52] test: refs #8224 fix e2e using select, use containts() --- src/components/common/VnSelect.vue | 2 +- test/cypress/integration/customer/clientList.spec.js | 8 ++++---- .../integration/entry/entryCard/entryBuys.spec.js | 2 +- .../integration/entry/entryCard/entryNotes.spec.js | 2 -- .../invoiceIn/invoiceInCorrective.spec.js | 12 +++++++++--- .../invoiceIn/invoiceInDescriptor.spec.js | 6 +++--- .../integration/invoiceIn/invoiceInList.spec.js | 2 +- .../integration/invoiceIn/invoiceInVat.spec.js | 6 ++---- test/cypress/integration/order/orderList.spec.js | 6 +++--- .../shelving/parking/parkingBasicData.spec.js | 2 +- test/cypress/integration/ticket/ticketList.spec.js | 4 ++-- 11 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue index 2078728b9..e17f71bbc 100644 --- a/src/components/common/VnSelect.vue +++ b/src/components/common/VnSelect.vue @@ -454,7 +454,7 @@ function getOptionLabel(property) { -