From 6489a4e3cfafad9b0b9a5c7af8fa9fd63d408c9b Mon Sep 17 00:00:00 2001 From: Pranav C Date: Fri, 14 Jun 2024 14:38:41 +0000 Subject: [PATCH 1/3] fix: add option to sort cache data --- packages/nocodb/src/cache/CacheMgr.ts | 33 +++++++++++++++ packages/nocodb/src/cache/NocoCache.ts | 7 +++- packages/nocodb/src/models/Filter.ts | 53 +++++++++++++++++------- packages/nocodb/src/models/HookFilter.ts | 20 ++++++--- 4 files changed, 92 insertions(+), 21 deletions(-) diff --git a/packages/nocodb/src/cache/CacheMgr.ts b/packages/nocodb/src/cache/CacheMgr.ts index d6df1bb83f..f615cc93c7 100644 --- a/packages/nocodb/src/cache/CacheMgr.ts +++ b/packages/nocodb/src/cache/CacheMgr.ts @@ -251,6 +251,11 @@ export default abstract class CacheMgr { async getList( scope: string, subKeys: string[], + orderBy?: { + key: string; + dir?: 'asc' | 'desc'; + isString?: boolean; + }, ): Promise<{ list: any[]; isNoneList: boolean; @@ -328,6 +333,34 @@ export default abstract class CacheMgr { } } + // Check if orderBy parameter is provided and valid + if (orderBy?.key) { + // Destructure the properties from orderBy object + const { key, dir, isString } = orderBy; + + // Determine the multiplier for sorting order: -1 for descending, 1 for ascending + const orderMultiplier = dir === 'desc' ? -1 : 1; + + // Sort the values array based on the specified property + values.sort((a, b) => { + // Get the property values from a and b + const aValue = a?.[key]; + const bValue = b?.[key]; + + // If aValue is null or undefined, move it to the end + if (aValue === null || aValue === undefined) return 1; + // If bValue is null or undefined, move it to the end + if (bValue === null || bValue === undefined) return -1; + + if (isString) { + // If the property is a string, use localeCompare for comparison + return orderMultiplier * String(aValue).localeCompare(String(bValue)); + } + // If the property is a number, subtract the values directly + return orderMultiplier * (aValue - bValue); + }); + } + return { list: values.map((res) => { try { diff --git a/packages/nocodb/src/cache/NocoCache.ts b/packages/nocodb/src/cache/NocoCache.ts index b2383e80a3..c0402c17d1 100644 --- a/packages/nocodb/src/cache/NocoCache.ts +++ b/packages/nocodb/src/cache/NocoCache.ts @@ -62,6 +62,11 @@ export default class NocoCache { public static async getList( scope: string, subKeys: string[], + orderBy?: { + key: string; + dir?: 'asc' | 'desc'; + isString?: boolean; + }, ): Promise<{ list: any[]; isNoneList: boolean; @@ -71,7 +76,7 @@ export default class NocoCache { list: [], isNoneList: false, }); - return this.client.getList(scope, subKeys); + return this.client.getList(scope, subKeys, orderBy); } public static async setList( diff --git a/packages/nocodb/src/models/Filter.ts b/packages/nocodb/src/models/Filter.ts index 216b70c787..1835cc5b24 100644 --- a/packages/nocodb/src/models/Filter.ts +++ b/packages/nocodb/src/models/Filter.ts @@ -385,9 +385,13 @@ export default class Filter implements FilterType { ): Promise { if (this.children) return this.children; if (!this.is_group) return null; - const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [ - this.id, - ]); + const cachedList = await NocoCache.getList( + CacheScope.FILTER_EXP, + [this.id], + { + key: 'order', + }, + ); let { list: childFilters } = cachedList; const { isNoneList } = cachedList; if (!isNoneList && !childFilters.length) { @@ -438,9 +442,13 @@ export default class Filter implements FilterType { }, ncMeta = Noco.ncMeta, ): Promise { - const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [ - viewId || hookId || linkColId, - ]); + const cachedList = await NocoCache.getList( + CacheScope.FILTER_EXP, + [viewId || hookId || linkColId], + { + key: 'order', + }, + ); let { list: filters } = cachedList; const { isNoneList } = cachedList; if (!isNoneList && !filters.length) { @@ -596,7 +604,13 @@ export default class Filter implements FilterType { { viewId }: { viewId: any }, ncMeta = Noco.ncMeta, ) { - const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [viewId]); + const cachedList = await NocoCache.getList( + CacheScope.FILTER_EXP, + [viewId], + { + key: 'order', + }, + ); let { list: filterObjs } = cachedList; const { isNoneList } = cachedList; if (!isNoneList && !filterObjs.length) { @@ -623,7 +637,11 @@ export default class Filter implements FilterType { { hookId }: { hookId: any }, ncMeta = Noco.ncMeta, ) { - const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [hookId]); + const cachedList = await NocoCache.getList( + CacheScope.FILTER_EXP, + [hookId], + { key: 'order' }, + ); let { list: filterObjs } = cachedList; const { isNoneList } = cachedList; if (!isNoneList && !filterObjs.length) { @@ -654,9 +672,11 @@ export default class Filter implements FilterType { }, ncMeta = Noco.ncMeta, ) { - const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [ - parentId, - ]); + const cachedList = await NocoCache.getList( + CacheScope.FILTER_EXP, + [parentId], + { key: 'order' }, + ); let { list: filterObjs } = cachedList; const { isNoneList } = cachedList; if (!isNoneList && !filterObjs.length) { @@ -690,10 +710,13 @@ export default class Filter implements FilterType { }, ncMeta = Noco.ncMeta, ) { - const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [ - hookId, - parentId, - ]); + const cachedList = await NocoCache.getList( + CacheScope.FILTER_EXP, + [hookId, parentId], + { + key: 'order', + }, + ); let { list: filterObjs } = cachedList; const { isNoneList } = cachedList; if (!isNoneList && !filterObjs.length) { diff --git a/packages/nocodb/src/models/HookFilter.ts b/packages/nocodb/src/models/HookFilter.ts index d50a60a2cb..43873a5d5b 100644 --- a/packages/nocodb/src/models/HookFilter.ts +++ b/packages/nocodb/src/models/HookFilter.ts @@ -247,9 +247,11 @@ export default class Filter { ): Promise { if (this.children) return this.children; if (!this.is_group) return null; - const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [ - this.id, - ]); + const cachedList = await NocoCache.getList( + CacheScope.FILTER_EXP, + [this.id], + { key: 'order' }, + ); let { list: childFilters } = cachedList; const { isNoneList } = cachedList; if (!isNoneList && !childFilters.length) { @@ -293,7 +295,11 @@ export default class Filter { }, ncMeta = Noco.ncMeta, ): Promise { - const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [viewId]); + const cachedList = await NocoCache.getList( + CacheScope.FILTER_EXP, + [viewId], + { key: 'order' }, + ); let { list: filters } = cachedList; const { isNoneList } = cachedList; if (!isNoneList && !filters.length) { @@ -393,7 +399,11 @@ export default class Filter { { viewId }: { viewId: any }, ncMeta = Noco.ncMeta, ) { - const cachedList = await NocoCache.getList(CacheScope.FILTER_EXP, [viewId]); + const cachedList = await NocoCache.getList( + CacheScope.FILTER_EXP, + [viewId], + { key: 'order' }, + ); let { list: filterObjs } = cachedList; const { isNoneList } = cachedList; if (!isNoneList && !filterObjs.length) { From c2e31c38360700f327a5cf75262300d35a1ffdd4 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Fri, 14 Jun 2024 22:00:48 +0530 Subject: [PATCH 2/3] fix: apply sort after parsing list data Signed-off-by: Pranav C --- packages/nocodb/src/cache/CacheMgr.ts | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/nocodb/src/cache/CacheMgr.ts b/packages/nocodb/src/cache/CacheMgr.ts index f615cc93c7..de727f4183 100644 --- a/packages/nocodb/src/cache/CacheMgr.ts +++ b/packages/nocodb/src/cache/CacheMgr.ts @@ -332,6 +332,17 @@ export default abstract class CacheMgr { ); } } + const list = values.map((res) => { + try { + const o = JSON.parse(res); + if (typeof o === 'object') { + return o.value; + } + } catch (e) { + return res; + } + return res; + }); // Check if orderBy parameter is provided and valid if (orderBy?.key) { @@ -342,7 +353,7 @@ export default abstract class CacheMgr { const orderMultiplier = dir === 'desc' ? -1 : 1; // Sort the values array based on the specified property - values.sort((a, b) => { + list.sort((a, b) => { // Get the property values from a and b const aValue = a?.[key]; const bValue = b?.[key]; @@ -362,17 +373,7 @@ export default abstract class CacheMgr { } return { - list: values.map((res) => { - try { - const o = JSON.parse(res); - if (typeof o === 'object') { - return o.value; - } - } catch (e) { - return res; - } - return res; - }), + list, isNoneList, }; } From 646ff49e82c4477c2da3c48fb1342fa3ef1f9463 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Fri, 14 Jun 2024 22:25:49 +0530 Subject: [PATCH 3/3] fix: on delete find index using id since index could change while deleting Signed-off-by: Pranav C --- packages/nc-gui/composables/useViewFilters.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/nc-gui/composables/useViewFilters.ts b/packages/nc-gui/composables/useViewFilters.ts index 0326f8bb85..ad61e79872 100644 --- a/packages/nc-gui/composables/useViewFilters.ts +++ b/packages/nc-gui/composables/useViewFilters.ts @@ -502,9 +502,11 @@ export function useViewFilters( } else { try { await $api.dbTableFilter.delete(filter.id) - if (!isWebhook && !isLink) reloadData?.() - filters.value.splice(i, 1) + + // find item index by using id and remove it from array since item index may change + const itemIndex = filters.value.findIndex((f) => f.id === filter.id) + if (itemIndex > -1) filters.value.splice(itemIndex) } catch (e: any) { console.log(e) message.error(await extractSdkResponseErrorMsg(e))