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, type: Object,
default: () => ({}), default: () => ({}),
}, },
multiCheck: {
type: Object,
default: () => ({}),
},
crudModel: { crudModel: {
type: Object, type: Object,
default: () => ({}), default: () => ({}),
@ -197,10 +201,10 @@ const onVirtualScroll = ({ to }) => {
handleScroll(); handleScroll();
const virtualScrollContainer = tableRef.value?.$el?.querySelector('.q-table__middle'); const virtualScrollContainer = tableRef.value?.$el?.querySelector('.q-table__middle');
if (virtualScrollContainer) { if (virtualScrollContainer) {
virtualScrollContainer.dispatchEvent(new CustomEvent('scroll')); virtualScrollContainer.dispatchEvent(new CustomEvent('scroll'));
if (vnScrollRef.value) { if (vnScrollRef.value) {
vnScrollRef.value.updateScrollContainer(virtualScrollContainer); vnScrollRef.value.updateScrollContainer(virtualScrollContainer);
} }
} }
}; };
@ -680,7 +684,7 @@ const handleSelectedAll = (data) => {
<CrudModel <CrudModel
v-bind="$attrs" v-bind="$attrs"
:class="$attrs['class'] ?? 'q-px-md'" :class="$attrs['class'] ?? 'q-px-md'"
:limit="$attrs['limit'] ?? 100" :limit="$attrs['limit'] ?? 10"
ref="CrudModelRef" ref="CrudModelRef"
@on-fetch="(...args) => emit('onFetch', ...args)" @on-fetch="(...args) => emit('onFetch', ...args)"
:search-url="searchUrl" :search-url="searchUrl"
@ -698,9 +702,9 @@ const handleSelectedAll = (data) => {
ref="tableRef" ref="tableRef"
v-bind="table" v-bind="table"
:class="[ :class="[
'vnTable', 'vnTable',
table ? 'selection-cell' : '', table ? 'selection-cell' : '',
$props.footer ? 'last-row-sticky' : '', $props.footer ? 'last-row-sticky' : '',
]" ]"
wrap-cells wrap-cells
:columns="splittedColumns.columns" :columns="splittedColumns.columns"
@ -720,7 +724,10 @@ const handleSelectedAll = (data) => {
:data-cy :data-cy
> >
<template #header-selection> <template #header-selection>
{{ $attrs['url'] }}
<VnMultiCheck <VnMultiCheck
:searchUrl="searchUrl"
:expand="$props.multiCheck.expand"
v-model="selectAll" v-model="selectAll"
:url="$attrs['url']" :url="$attrs['url']"
@update:selected="handleMultiCheck" @update:selected="handleMultiCheck"
@ -1127,9 +1134,9 @@ const handleSelectedAll = (data) => {
</FormModelPopup> </FormModelPopup>
</QDialog> </QDialog>
<VnScroll <VnScroll
ref="vnScrollRef" ref="vnScrollRef"
v-if="isTableMode" v-if="isTableMode"
:scroll-target="tableRef?.$el?.querySelector('.q-table__middle')" :scroll-target="tableRef?.$el?.querySelector('.q-table__middle')"
/> />
</template> </template>
<i18n> <i18n>

View File

@ -4,47 +4,60 @@ import VnCheckbox from './VnCheckbox.vue';
import axios from 'axios'; import axios from 'axios';
import { toRaw } from 'vue'; import { toRaw } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
import { useRoute } from 'vue-router';
const route = useRoute();
const { t } = useI18n(); const { t } = useI18n();
const model = defineModel({ type: [Boolean] }); const model = defineModel({ type: [Boolean] });
const props = defineProps({ const props = defineProps({
expand: {
type: Boolean,
default: false,
},
url: { url: {
type: String, type: String,
default: null, default: null,
required: true, required: true,
}, },
searchUrl: {
type: [String, Boolean],
default: 'table',
},
}); });
const value = ref(false); const value = ref(false);
const rows = ref(0); const rows = ref(0);
defineEmits(['update:selected', 'select:all']); const onClick = () => {
const onClick = async () => {
if (value.value) { if (value.value) {
const { filter } = JSON.parse(route.query[props.searchUrl]);
filter.limit = 0;
const params = {
params: { filter: JSON.stringify(filter) },
};
axios axios
.get(props.url, { .get(props.url, params)
params: { .then(({ data }) => {
filter: null, rows.value = data;
},
}) })
.then((response) => { .catch(console.error);
rows.value = response.data;
console.log(response.data);
})
.catch((error) => {
console.error(error);
});
} }
}; };
defineEmits(['update:selected', 'select:all']);
</script> </script>
<template> <template>
<div style="display: flex"> <div style="display: flex">
<VnCheckbox v-model="value" @click="$emit('update:selected', value)" /> <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"> <QMenu anchor="bottom right" self="top right">
<QList> <QList>
<QItem v-ripple clickable @click="$emit('select:all', toRaw(rows))"> <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> <slot name="more-options"></slot>
</QList> </QList>
</QMenu> </QMenu>
@ -57,11 +70,11 @@ en:
fr: fr:
Select all: 'Sélectionner tout ({rows})' Select all: 'Sélectionner tout ({rows})'
es: es:
Select all: Seleccionar todo ({rows}) Select all: 'Seleccionar todo ({rows})'
de: de:
Select all: 'Alle auswählen ({rows})' Select all: 'Alle auswählen ({rows})'
it: it:
Select all: 'Seleziona tutto ({rows})' Select all: 'Seleziona tutto ({rows})'
pt: pt:
Select all: Selecionar tudo ({rows}) Select all: 'Selecionar tudo ({rows})'
</i18n> </i18n>

View File

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