mirror of
https://github.com/bunkerity/bunkerweb
synced 2026-05-24 09:28:37 +00:00
refractor and increase filter performance
* refactor multiple filtering removing a lot of nested loops * add a "buffer" (wait some time before filtering that there aren't another filter input) in order to avoid calling too many time the filter and avoir freeze on template
This commit is contained in:
parent
540ecfd77b
commit
f7ced2e649
2 changed files with 75 additions and 33 deletions
|
|
@ -177,8 +177,6 @@ const props = defineProps({
|
|||
});
|
||||
|
||||
const multiples = reactive({
|
||||
// Store props.multiples on multiples.data and then use multiples.data to render increase performance
|
||||
data: props.multiples,
|
||||
invisible: [],
|
||||
toDelete: [],
|
||||
});
|
||||
|
|
@ -245,7 +243,7 @@ function delGroup(group, multName, groupName) {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<template :key="multName" v-for="(multObj, multName, id) in multiples.data">
|
||||
<template :key="multObj" v-for="(multObj, multName, id) in props.multiples">
|
||||
<Container
|
||||
data-is="multiple"
|
||||
class="layout-settings-multiple"
|
||||
|
|
@ -262,7 +260,7 @@ function delGroup(group, multName, groupName) {
|
|||
|
||||
<template
|
||||
:key="groupId"
|
||||
v-for="(group, groupName, groupId) in multiples.data[multName]"
|
||||
v-for="(group, groupName, groupId) in props.multiples[multName]"
|
||||
>
|
||||
<Container
|
||||
data-group="multiple"
|
||||
|
|
@ -279,7 +277,7 @@ function delGroup(group, multName, groupName) {
|
|||
:subtitle="`${multName.replaceAll('-', ' ')} #${+groupName + 1}`"
|
||||
/>
|
||||
<template
|
||||
:key="settingName"
|
||||
:key="setting"
|
||||
v-for="(setting, settingName, settingId) in group"
|
||||
>
|
||||
<Fields :setting="setting" />
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup>
|
||||
import { defineProps, reactive, watch } from "vue";
|
||||
import { defineProps, onUpdated, reactive, watch } from "vue";
|
||||
import Container from "@components/Widget/Container.vue";
|
||||
|
||||
import Input from "@components/Forms/Field/Input.vue";
|
||||
|
|
@ -71,18 +71,19 @@ const emits = defineEmits(["filter"]);
|
|||
|
||||
const filters = reactive({
|
||||
base: JSON.parse(JSON.stringify(props.filters)),
|
||||
bufferCount: 0,
|
||||
isFiltering: false,
|
||||
});
|
||||
|
||||
watch(props.data, () => {
|
||||
filterData();
|
||||
});
|
||||
|
||||
// Case we are changing a filter value
|
||||
// We only have to check data for this filter
|
||||
function filterData(filter = {}, value = "") {
|
||||
function startFilter(filter = {}, value) {
|
||||
filters.isFiltering = true;
|
||||
// Case we have new filter value, update it
|
||||
// Loop on filter.base and update the "value" key when matching filterName
|
||||
if (filter?.filterName && value) {
|
||||
if (filter?.filterName && value !== null) {
|
||||
filters.base.forEach((f) => {
|
||||
if (f.filterName === filter.filterName) {
|
||||
f.value = value;
|
||||
|
|
@ -133,8 +134,26 @@ function filterData(filter = {}, value = "") {
|
|||
// Remove empty row
|
||||
template = template.filter((row) => row.length > 0);
|
||||
}
|
||||
console.log("filter");
|
||||
|
||||
emits("filter", template);
|
||||
// Allow filtering again after 100ms
|
||||
setTimeout(() => {
|
||||
filters.isFiltering = false;
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// Case we are changing a filter value
|
||||
// We only have to check data for this filter
|
||||
function filterData(filter = {}, value = null) {
|
||||
// Wait for buffer input
|
||||
filters.bufferCount++;
|
||||
const currBufferCount = filters.bufferCount;
|
||||
// Wait time to check if not another input (count) to filter
|
||||
setTimeout(() => {
|
||||
// Case another input, don't filter and wait again
|
||||
if (currBufferCount < filters.bufferCount) return;
|
||||
startFilter(filter, value);
|
||||
}, 50);
|
||||
}
|
||||
|
||||
function filterRegularSettings(filterSettings, template) {
|
||||
|
|
@ -156,34 +175,57 @@ function filterRegularSettings(filterSettings, template) {
|
|||
}
|
||||
|
||||
function filterMultiplesSettings(filterSettings, template) {
|
||||
// Loop on plugins and get multiples settings like this
|
||||
template.forEach((plugin, id) => {
|
||||
// loop on plugin settings dict
|
||||
const filterMultiple = {};
|
||||
const multiples = plugin?.multiples;
|
||||
if (!multiples || Object.keys(multiples).length <= 0) return;
|
||||
for (const [multName, multGroups] of Object.entries(multiples)) {
|
||||
for (const [groupId, groupSettings] of Object.entries(multGroups)) {
|
||||
const multiples = [];
|
||||
// Format to filter
|
||||
for (let i = 0; i < template.length; i++) {
|
||||
const plugin = template[i];
|
||||
if (!plugin?.multiples || Object.keys(plugin.multiples).length <= 0)
|
||||
continue;
|
||||
for (const [multName, multGroups] of Object.entries(plugin.multiples)) {
|
||||
for (const [groupName, groupSettings] of Object.entries(multGroups)) {
|
||||
// Check if inpid is mathing a groupSettings key
|
||||
const settings = [];
|
||||
for (const [key, value] of Object.entries(groupSettings)) {
|
||||
settings.push({ ...value, setting_name: key });
|
||||
}
|
||||
const filterSettingsData = useFilter(settings, filterSettings);
|
||||
const settingsData = {};
|
||||
filterSettingsData.forEach((setting) => {
|
||||
settingsData[setting.setting_name] = setting;
|
||||
delete settingsData[setting.setting_name]?.setting_name;
|
||||
});
|
||||
// Check if at least one setting is matching
|
||||
if (Object.keys(settingsData).length > 0) {
|
||||
if (!filterMultiple[multName]) filterMultiple[multName] = {};
|
||||
filterMultiple[multName][groupId] = settingsData;
|
||||
multiples.push({
|
||||
...value,
|
||||
setting_name: key,
|
||||
plugin_id: plugin.id,
|
||||
group_name: groupName,
|
||||
mult_name: multName,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
template[id].multiples = filterMultiple;
|
||||
}
|
||||
// Remove multiples from template
|
||||
template.forEach((plugin) => {
|
||||
delete plugin.multiples;
|
||||
});
|
||||
// Add filtered multiples
|
||||
const filterSettingsData = useFilter(multiples, filterSettings);
|
||||
|
||||
for (let i = 0; i < filterSettingsData.length; i++) {
|
||||
const setting = filterSettingsData[i];
|
||||
const pluginId = setting?.plugin_id;
|
||||
const groupName = setting?.group_name;
|
||||
const multName = setting?.mult_name;
|
||||
const settingName = setting?.setting_name;
|
||||
delete setting.plugin_id;
|
||||
delete setting.group_name;
|
||||
delete setting.setting_name;
|
||||
// Find the plugin in template
|
||||
const pluginIndex = template.findIndex((plugin) => plugin.id === pluginId);
|
||||
if (pluginIndex < 0) continue;
|
||||
if (!("multiples" in template[pluginIndex]))
|
||||
template[pluginIndex]["multiples"] = {};
|
||||
|
||||
if (!(multName in template[pluginIndex]["multiples"]))
|
||||
template[pluginIndex]["multiples"][multName] = {};
|
||||
if (!(groupName in template[pluginIndex]["multiples"][multName]))
|
||||
template[pluginIndex]["multiples"][multName][groupName] = {};
|
||||
|
||||
template[pluginIndex]["multiples"][multName][groupName][settingName] =
|
||||
setting;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
@ -194,11 +236,13 @@ function filterMultiplesSettings(filterSettings, template) {
|
|||
<Input
|
||||
v-if="filter.type === 'keyword'"
|
||||
@inp="(v) => filterData(filter, v)"
|
||||
@change="(v) => filterData(filter, v)"
|
||||
v-bind="filter.field"
|
||||
/>
|
||||
<Select
|
||||
v-if="filter.type === 'select'"
|
||||
@inp="(v) => filterData(filter, v)"
|
||||
@change="(v) => filterData(filter, v)"
|
||||
v-bind="filter.field"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
|||
Loading…
Reference in a new issue