From fb340d1f27a8bb53d234dbfbd467fef05c343f5e Mon Sep 17 00:00:00 2001 From: Javier Segarra Date: Wed, 16 Oct 2024 15:51:54 +0200 Subject: [PATCH] perf: refs #7793 sort when filter without fetch --- src/components/common/VnSelect.vue | 53 +++++++++++++----------------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/src/components/common/VnSelect.vue b/src/components/common/VnSelect.vue index 788bb3be3..03f94c066 100644 --- a/src/components/common/VnSelect.vue +++ b/src/components/common/VnSelect.vue @@ -104,6 +104,7 @@ const noOneOpt = ref({ [optionValue.value]: false, [optionLabel.value]: noOneText, }); +const sort = computed(() => [...($props.sortBy ?? []), `${$props.optionLabel} DESC`]); const value = computed({ get() { @@ -137,9 +138,8 @@ function findKeyInOptions() { if (!$props.options) return; return filter($props.modelValue, $props.options)?.length; } - -function setOptions(data) { - data = data.sort((a, b) => { +function sortOptions(data) { + return data.sort((a, b) => { const search = lastVal.value?.toString()?.toLowerCase(); const aValue = String(a[$props.optionLabel]).toLowerCase(); const bValue = String(b[$props.optionLabel]).toLowerCase(); @@ -156,6 +156,9 @@ function setOptions(data) { return aValue.localeCompare(bValue); }); +} +function setOptions(data) { + if (lastVal.value) data = sortOptions(data); myOptions.value = JSON.parse(JSON.stringify(data)); myOptionsOriginal.value = JSON.parse(JSON.stringify(data)); } @@ -165,26 +168,28 @@ function filter(val, options) { if (!search) return options; - return options.filter((row) => { - if ($props.filterOptions.length) { - return $props.filterOptions.some((prop) => { - const propValue = String(row[prop]).toLowerCase(); - return propValue.includes(search); - }); - } + return sortOptions( + options.filter((row) => { + if ($props.filterOptions.length) { + return $props.filterOptions.some((prop) => { + const propValue = String(row[prop]).toLowerCase(); + return propValue.includes(search); + }); + } - if (!row) return; - const id = row[$props.optionValue]; - const optionLabel = String(row[$props.optionLabel]).toLowerCase(); + if (!row) return; + const id = row[$props.optionValue]; + const optionLabel = String(row[$props.optionLabel]).toLowerCase(); - return id == search || optionLabel.includes(search); - }); + return id == search || optionLabel.includes(search); + }) + ); } async function fetchFilter(val) { if (!$props.url || !dataRef.value) return; - const { fields, include, sortBy, limit } = $props; + const { fields, include, limit } = $props; const key = optionFilterValue.value ?? (new RegExp(/\d/g).test(val) @@ -203,24 +208,10 @@ async function fetchFilter(val) { $props.exprBuilder && Object.assign(where, $props.exprBuilder(key, val)); const fetchOptions = { where, include, limit }; if (fields) fetchOptions.fields = fields; - if (sortBy) { - fetchOptions.order = [ - getOrderCaseString(key, val), - typeof sortBy === 'string' ? sortBy : [...sortBy], - ]; - } return dataRef.value.fetch(fetchOptions); } -function getOrderCaseString(prop, value) { - return `CASE - WHEN ${prop} LIKE '${value}%' THEN 1 - WHEN ${prop} LIKE '%${value}%' THEN 2 - ELSE 3 - END, ${prop} DESC`; -} - async function filterHandler(val, update) { if (!val && lastVal.value === val) { lastVal.value = val; @@ -266,7 +257,7 @@ const getVal = (val) => ($props.useLike ? { like: `%${val}%` } : val); @on-fetch="(data) => setOptions(data)" :where="where || { [optionValue]: value }" :limit="limit" - :sort-by="sortBy" + :sort-by="sort" :fields="fields" :params="params" />