Browse Source

Merge pull request #8732 from nocodb/nc-fix/filter-bugs

Nc fix/filter bugs
pull/8742/head
Pranav C 7 months ago committed by GitHub
parent
commit
3869752d43
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 45
      packages/nc-gui/composables/useDebounceFnCached.ts
  2. 31
      packages/nc-gui/composables/useViewFilters.ts

45
packages/nc-gui/composables/useDebounceFnCached.ts

@ -0,0 +1,45 @@
import type { DebounceFilterOptions, MaybeRefOrGetter } from '@vueuse/core'
type FunctionArgs = (...args: any[]) => any
// Default function to generate a cache key
function defaultGetCacheKey(): string {
return 'default'
}
/**
* Creates a cached debounced version of the given function.
*
* @param fn - The function to debounce.
* @param ms - The debounce delay in milliseconds. Default is 500ms.
* @param getCacheKey - Function to generate a unique cache key based on the arguments.
* @param options - Additional options for debouncing.
*
* @returns A debounced version of the input function with caching.
*/
export function useCachedDebouncedFunction<T extends FunctionArgs>(
fn: T,
ms: MaybeRefOrGetter<number> = 500,
getCacheKey: (...args: Parameters<T>) => string | number = defaultGetCacheKey,
options: DebounceFilterOptions = {},
): (...args: Parameters<T>) => ReturnType<T> {
// Cache to store debounced functions based on a unique key
const debounceCache = new Map<string | number, any>()
return (...args: Parameters<T>): ReturnType<T> => {
// Generate a unique key for the given arguments
const key = getCacheKey(...args)
// If the debounced function for the given key is not in the cache, create and cache it
if (!debounceCache.has(key)) {
const debouncedFn = useDebounceFn(fn, ms, options)
debounceCache.set(key, debouncedFn)
}
// Retrieve the cached debounced function
const debouncedFn = debounceCache.get(key)
// Call and return the result of the debounced function
return debouncedFn!(...args)
}
}

31
packages/nc-gui/composables/useViewFilters.ts

@ -338,7 +338,9 @@ export function useViewFilters(
} }
} }
const saveOrUpdate = async (filter: Filter, i: number, force = false, undo = false, skipDataReload = false) => { const saveOrUpdateDebounced = useCachedDebouncedFunction(saveOrUpdate, 500, (_filter: Filter, i: number) => i)
async function saveOrUpdate(filter: Filter, i: number, force = false, undo = false, skipDataReload = false) {
// if already in progress the debounced function which will call this function again with 500ms delay until it's not saving // if already in progress the debounced function which will call this function again with 500ms delay until it's not saving
if (savingStatus[i]) { if (savingStatus[i]) {
return saveOrUpdateDebounced(filter, i, force, undo, skipDataReload) return saveOrUpdateDebounced(filter, i, force, undo, skipDataReload)
@ -379,14 +381,13 @@ export function useViewFilters(
} }
} }
} }
try { try {
if (nestedMode.value) { if (nestedMode.value) {
filters.value[i] = { ...filter } filters.value[i] = { ...filter }
filters.value = [...filters.value] filters.value = [...filters.value]
} else if (!autoApply?.value && !force) { } else if (!autoApply?.value && !force) {
filter.status = filter.id ? 'update' : 'create' filter.status = filter.id ? 'update' : 'create'
} else if (filters.value[i]?.id && filter.status !== 'create') { } else if (filters.value[i]?.id && filters.value[i]?.status !== 'create') {
await $api.dbTableFilter.update(filters.value[i].id!, { await $api.dbTableFilter.update(filters.value[i].id!, {
...filter, ...filter,
fk_parent_id: parentId.value, fk_parent_id: parentId.value,
@ -399,15 +400,32 @@ export function useViewFilters(
}) })
} else { } else {
if (linkColId?.value) { if (linkColId?.value) {
filters.value[i] = await $api.dbTableLinkFilter.create(linkColId.value, { const savedFilter = await $api.dbTableLinkFilter.create(linkColId.value, {
...filter, ...filter,
fk_parent_id: parentId, fk_parent_id: parentId,
}) })
// extract id from saved filter and update the filter object
// avoiding whole object update to prevent overwriting of current filter object changes
filters.value[i] = {
...filters.value[i],
fk_parent_id: parentId,
id: savedFilter.id,
status: undefined,
}
} else { } else {
filters.value[i] = await $api.dbTableFilter.create(view.value.id!, { console.log(parentId.value)
const savedFilter = await $api.dbTableFilter.create(view.value.id!, {
...filter, ...filter,
fk_parent_id: parentId.value, fk_parent_id: parentId.value,
}) })
// extract id from saved filter and update the filter object
// avoiding whole object update to prevent overwriting of current filter object changes
filters.value[i] = {
...filters.value[i],
fk_parent_id: parentId,
id: savedFilter.id,
status: undefined,
}
} }
if (!isLink && !isWebhook) allFilters.value.push(filters.value[+i]) if (!isLink && !isWebhook) allFilters.value.push(filters.value[+i])
} }
@ -496,9 +514,6 @@ export function useViewFilters(
if (!isLink && !isWebhook) allFilters.value = allFilters.value.filter((f) => f.id !== filter.id) if (!isLink && !isWebhook) allFilters.value = allFilters.value.filter((f) => f.id !== filter.id)
} }
} }
const saveOrUpdateDebounced = useDebounceFn(saveOrUpdate, 500)
const addFilter = async (undo = false, draftFilter: Partial<FilterType> = {}) => { const addFilter = async (undo = false, draftFilter: Partial<FilterType> = {}) => {
filters.value.push(draftFilter?.fk_column_id ? { ...placeholderFilter(), ...draftFilter } : placeholderFilter()) filters.value.push(draftFilter?.fk_column_id ? { ...placeholderFilter(), ...draftFilter } : placeholderFilter())
if (!undo) { if (!undo) {

Loading…
Cancel
Save