feat: add multi-check support to VnTable and VnMultiCheck components

This commit is contained in:
Javier Segarra 2025-04-23 19:24:07 +02:00
parent f683d78e0e
commit 0c0d21e53e
3 changed files with 59 additions and 36 deletions

View File

@ -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) => {
<CrudModel
v-bind="$attrs"
:class="$attrs['class'] ?? 'q-px-md'"
:limit="$attrs['limit'] ?? 100"
:limit="$attrs['limit'] ?? 10"
ref="CrudModelRef"
@on-fetch="(...args) => emit('onFetch', ...args)"
:search-url="searchUrl"
@ -698,9 +702,9 @@ 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
>
<template #header-selection>
{{ $attrs['url'] }}
<VnMultiCheck
:searchUrl="searchUrl"
:expand="$props.multiCheck.expand"
v-model="selectAll"
:url="$attrs['url']"
@update:selected="handleMultiCheck"
@ -1126,10 +1133,10 @@ const handleSelectedAll = (data) => {
</template>
</FormModelPopup>
</QDialog>
<VnScroll
ref="vnScrollRef"
v-if="isTableMode"
:scroll-target="tableRef?.$el?.querySelector('.q-table__middle')"
<VnScroll
ref="vnScrollRef"
v-if="isTableMode"
:scroll-target="tableRef?.$el?.querySelector('.q-table__middle')"
/>
</template>
<i18n>

View File

@ -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']);
</script>
<template>
<div style="display: flex">
<VnCheckbox v-model="value" @click="$emit('update:selected', value)" />
<QBtn v-if="value" flat dense icon="expand_more" @click="onClick">
<QBtn
v-if="value && $props.expand"
flat
dense
icon="expand_more"
@click="onClick"
>
<QMenu anchor="bottom right" self="top right">
<QList>
<QItem v-ripple clickable @click="$emit('select:all', toRaw(rows))">
{{ t('Select all', { rows: rows.length }) }}</QItem
>
{{ t('Select all', { rows: rows.length }) }}
</QItem>
<slot name="more-options"></slot>
</QList>
</QMenu>
@ -57,11 +70,11 @@ en:
fr:
Select all: 'Sélectionner tout ({rows})'
es:
Select all: Seleccionar todo ({rows})
Select all: 'Seleccionar todo ({rows})'
de:
Select all: 'Alle auswählen ({rows})'
it:
Select all: 'Seleziona tutto ({rows})'
pt:
Select all: Selecionar tudo ({rows})
Select all: 'Selecionar tudo ({rows})'
</i18n>

View File

@ -100,6 +100,9 @@ const columns = computed(() => [
'row-key': 'id',
selection: 'multiple',
}"
:multi-check="{
expand: true,
}"
v-model:selected="selected"
:right-search="true"
:columns="columns"