From 4471bab7186a504a1b581c4227677bc383971ed7 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Wed, 16 Oct 2024 06:30:19 +0000 Subject: [PATCH 1/3] fix: replace computeAsync with custom watch to avoid unnecessary formula helper functions --- .../smartsheet/column/FormulaOptions.vue | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue b/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue index fd0916ffad..2d24572b3d 100644 --- a/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue +++ b/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue @@ -85,23 +85,30 @@ if ((column.value?.colOptions as any)?.formula_raw) { const source = computed(() => activeBase.value?.sources?.find((s) => s.id === meta.value?.source_id)) -const parsedTree = computedAsync(async () => { - try { - const parsed = await validateFormulaAndExtractTreeWithType({ - formula: vModel.value.formula || vModel.value.formula_raw, - columns: meta.value?.columns || [], - column: column.value ?? undefined, - clientOrSqlUi: source.value?.type as any, - getMeta: async (modelId) => await getMeta(modelId), - }) - return parsed - } catch (e) { - return { - dataType: FormulaDataTypes.UNKNOWN, - } - } +const parsedTree = ref({ + dataType: FormulaDataTypes.UNKNOWN, }) +watch( + () => vModel.value.formula || vModel.value.formula_raw, + async () => { + try { + const parsed = await validateFormulaAndExtractTreeWithType({ + formula: vModel.value.formula || vModel.value.formula_raw, + columns: (meta.value?.columns || []).slice(), + column: column.value ? { ...column.value } : undefined, + clientOrSqlUi: source.value?.type as any, + getMeta: async (modelId) => await getMeta(modelId), + }) + parsedTree.value = parsed + } catch (e) { + parsedTree.value = { + dataType: FormulaDataTypes.UNKNOWN, + } + } + }, +) + // set additional validations setAdditionalValidations({ ...validators, From 6ca6310f759bd459b66d5f4eb93cb91202022316 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Wed, 16 Oct 2024 06:30:22 +0000 Subject: [PATCH 2/3] refactor: use debounce and counter to avoid race conditions --- .../smartsheet/column/FormulaOptions.vue | 46 +++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue b/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue index 2d24572b3d..39956bb80a 100644 --- a/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue +++ b/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue @@ -85,27 +85,47 @@ if ((column.value?.colOptions as any)?.formula_raw) { const source = computed(() => activeBase.value?.sources?.find((s) => s.id === meta.value?.source_id)) -const parsedTree = ref({ +const parsedTree = ref({ dataType: FormulaDataTypes.UNKNOWN, }) -watch( - () => vModel.value.formula || vModel.value.formula_raw, - async () => { - try { - const parsed = await validateFormulaAndExtractTreeWithType({ - formula: vModel.value.formula || vModel.value.formula_raw, - columns: (meta.value?.columns || []).slice(), - column: column.value ? { ...column.value } : undefined, - clientOrSqlUi: source.value?.type as any, - getMeta: async (modelId) => await getMeta(modelId), - }) +// Initialize a counter to track watcher invocations +let watcherCounter = 0 + +// Define the debounced async validation function +const debouncedValidate = useDebounceFn(async () => { + // Increment the counter for each invocation + watcherCounter += 1 + const currentCounter = watcherCounter + + try { + const parsed = await validateFormulaAndExtractTreeWithType({ + formula: vModel.value.formula || vModel.value.formula_raw, + columns: (meta.value?.columns || []).slice(), + column: column.value ? { ...column.value } : undefined, + clientOrSqlUi: source.value?.type as any, + getMeta: async (modelId) => await getMeta(modelId), + }) + + // Update parsedTree only if this is the latest invocation + if (currentCounter === watcherCounter) { parsedTree.value = parsed - } catch (e) { + } + } catch (e) { + // Update parsedTree only if this is the latest invocation + if (currentCounter === watcherCounter) { parsedTree.value = { dataType: FormulaDataTypes.UNKNOWN, } } + } +}, 300) + +// Watch the formula inputs and call the debounced function +watch( + () => vModel.value.formula || vModel.value.formula_raw, + () => { + debouncedValidate() }, ) From fc3e4d24624b7ca90692b71dc1904c7021fcec43 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Wed, 16 Oct 2024 06:30:23 +0000 Subject: [PATCH 3/3] refactor: revert unnecessary changes --- .../nc-gui/components/smartsheet/column/FormulaOptions.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue b/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue index 39956bb80a..431b33c9a9 100644 --- a/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue +++ b/packages/nc-gui/components/smartsheet/column/FormulaOptions.vue @@ -101,8 +101,8 @@ const debouncedValidate = useDebounceFn(async () => { try { const parsed = await validateFormulaAndExtractTreeWithType({ formula: vModel.value.formula || vModel.value.formula_raw, - columns: (meta.value?.columns || []).slice(), - column: column.value ? { ...column.value } : undefined, + columns: meta.value?.columns || [], + column: column.value ?? undefined, clientOrSqlUi: source.value?.type as any, getMeta: async (modelId) => await getMeta(modelId), })