121 lines
3.1 KiB
Vue
121 lines
3.1 KiB
Vue
<script setup>
|
|
import { ref } from 'vue';
|
|
import { useClipboard } from 'src/composables/useClipboard';
|
|
|
|
const { copyText } = useClipboard();
|
|
const target = ref();
|
|
const qmenuRef = ref();
|
|
const colField = ref();
|
|
let colValue = '';
|
|
let textValue = '';
|
|
|
|
defineExpose({ handler });
|
|
|
|
const arrayData = defineModel({
|
|
type: Array,
|
|
});
|
|
|
|
function handler(event) {
|
|
const clickedElement = event.target.closest('td');
|
|
if (!clickedElement) return;
|
|
|
|
target.value = event.target;
|
|
qmenuRef.value.show();
|
|
colField.value = clickedElement.getAttribute('data-col-field');
|
|
colValue = isNaN(+clickedElement.getAttribute('data-col-value'))
|
|
? clickedElement.getAttribute('data-col-value')
|
|
: +clickedElement.getAttribute('data-col-value');
|
|
textValue = getDeepestText(clickedElement);
|
|
}
|
|
|
|
function getDeepestText(node) {
|
|
const walker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT, {
|
|
acceptNode: (textNode) => {
|
|
return textNode.nodeValue.trim()
|
|
? NodeFilter.FILTER_ACCEPT
|
|
: NodeFilter.FILTER_REJECT;
|
|
},
|
|
});
|
|
|
|
let lastText = '';
|
|
while (walker.nextNode()) {
|
|
lastText = walker.currentNode.nodeValue.trim();
|
|
}
|
|
|
|
return lastText;
|
|
}
|
|
|
|
async function selectionFilter() {
|
|
await arrayData.value.addFilter({ params: { [colField.value]: colValue } });
|
|
}
|
|
|
|
async function selectionExclude() {
|
|
await arrayData.value.addFilter({
|
|
params: { [colField.value]: { neq: colValue } },
|
|
});
|
|
}
|
|
|
|
async function selectionRemoveFilter() {
|
|
await arrayData.value.addFilter({ params: { [colField.value]: undefined } });
|
|
}
|
|
|
|
async function removeAllFilters() {
|
|
await arrayData.value.applyFilter({ params: {} });
|
|
}
|
|
|
|
function copyValue() {
|
|
copyText(textValue, {
|
|
component: {
|
|
copyValue: textValue,
|
|
},
|
|
});
|
|
}
|
|
</script>
|
|
<template>
|
|
<QMenu ref="qmenuRef" :target class="column q-pa-sm" auto-close no-parent-event>
|
|
<QBtn
|
|
flat
|
|
icon="filter_list"
|
|
@click="selectionFilter()"
|
|
align="left"
|
|
:label="$t('Filter by selection')"
|
|
/>
|
|
<QBtn
|
|
flat
|
|
icon="dangerous"
|
|
@click="selectionExclude()"
|
|
align="left"
|
|
:label="$t('Exclude selection')"
|
|
/>
|
|
<QBtn
|
|
flat
|
|
icon="filter_list_off"
|
|
@click="selectionRemoveFilter()"
|
|
align="left"
|
|
:label="$t('Remove filter')"
|
|
/>
|
|
<QBtn
|
|
flat
|
|
icon="filter_list_off"
|
|
@click="removeAllFilters()"
|
|
align="left"
|
|
:label="$t('Remove all filters')"
|
|
/>
|
|
<QBtn
|
|
flat
|
|
icon="file_copy"
|
|
@click="copyValue()"
|
|
align="left"
|
|
:label="$t('Copy value')"
|
|
/>
|
|
</QMenu>
|
|
</template>
|
|
<i18n>
|
|
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
|
|
</i18n>
|