From 3c37971fc10d00a08e1e72b1a6fd3475c3ca4499 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Wed, 15 May 2024 11:18:17 +0000 Subject: [PATCH 1/6] fix: updating logicalOp --- packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue b/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue index 364ba74d20..d4c3a49a39 100644 --- a/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue +++ b/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue @@ -369,7 +369,7 @@ const onLogicalOpUpdate = async (filter: Filter, index: number) => { }), ) } - await filterUpdateCondition(filter, index) + await saveOrUpdate(filter, index) } From 8bcc87e059f569cbf2ef3a654f45446f2de0c787 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Wed, 15 May 2024 11:18:17 +0000 Subject: [PATCH 2/6] fix: extract locked state among visible filters(exclude deleted filters which is not synced) --- .../components/smartsheet/toolbar/ColumnFilter.vue | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue b/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue index d4c3a49a39..155782497e 100644 --- a/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue +++ b/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue @@ -355,15 +355,17 @@ watch( }, ) +const visibleFilters = computed(() => filters.value.filter((filter) => filter.status !== 'delete')) + const isLogicalOpChangeAllowed = computed(() => { - return new Set(filters.value.slice(1).map((filter) => filter.logical_op)).size > 1 + return new Set(visibleFilters.value.slice(1).map((filter) => filter.logical_op)).size > 1 }) // when logical operation is updated, update all the siblings with the same logical operation only if it's in locked state const onLogicalOpUpdate = async (filter: Filter, index: number) => { - if (index === 1 && filters.value.slice(2).every((siblingFilter) => siblingFilter.logical_op !== filter.logical_op)) { + if (index === 1 && visibleFilters.value.slice(2).every((siblingFilter) => siblingFilter.logical_op !== filter.logical_op)) { await Promise.all( - filters.value.slice(2).map(async (siblingFilter, i) => { + visibleFilters.value.slice(2).map(async (siblingFilter, i) => { siblingFilter.logical_op = filter.logical_op await saveOrUpdate(siblingFilter, i + 2, false, false, true) }), @@ -403,9 +405,9 @@ const onLogicalOpUpdate = async (filter: Filter, index: number) => { class="min-w-20 capitalize" placeholder="Group op" dropdown-class-name="nc-dropdown-filter-logical-op-group" - :disabled="i > 1 && !isLogicalOpChangeAllowed" + :disabled="visibleFilters.indexOf(filter) > 1 && !isLogicalOpChangeAllowed" @click.stop - @change="saveOrUpdate(filter, i)" + @change="onLogicalOpUpdate(filter, i)" >
@@ -456,7 +458,7 @@ const onLogicalOpUpdate = async (filter: Filter, index: number) => { :dropdown-match-select-width="false" class="h-full !min-w-20 !max-w-20 capitalize" hide-details - :disabled="filter.readOnly || (i > 1 && !isLogicalOpChangeAllowed)" + :disabled="filter.readOnly || (visibleFilters.indexOf(filter) > 1 && !isLogicalOpChangeAllowed)" dropdown-class-name="nc-dropdown-filter-logical-op" @change="onLogicalOpUpdate(filter, i)" @click.stop From e1547af31ba2f88fd64173bd7d48743559f121ef Mon Sep 17 00:00:00 2001 From: Pranav C Date: Wed, 15 May 2024 11:18:17 +0000 Subject: [PATCH 3/6] fix: external source adding issue --- packages/nc-gui/store/bases.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/nc-gui/store/bases.ts b/packages/nc-gui/store/bases.ts index 1764934728..4335ba834a 100644 --- a/packages/nc-gui/store/bases.ts +++ b/packages/nc-gui/store/bases.ts @@ -43,6 +43,8 @@ export const useBases = defineStore('basesStore', () => { return basesMap }) + const isDataSourceLimitReached = computed(() => Number(openedProject.value?.sources?.length) > 9) + const workspaceStore = useWorkspace() const tableStore = useTablesStore() @@ -389,6 +391,7 @@ export const useBases = defineStore('basesStore', () => { toggleStarred, basesUser, clearBasesUser, + isDataSourceLimitReached, } }) From f8851c7b5248fd8bcd6e0ebeeec6cde45f681e17 Mon Sep 17 00:00:00 2001 From: Pranav C Date: Wed, 15 May 2024 11:18:18 +0000 Subject: [PATCH 4/6] fix: lock logical op for filter group as well --- packages/nc-gui/composables/useViewFilters.ts | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/packages/nc-gui/composables/useViewFilters.ts b/packages/nc-gui/composables/useViewFilters.ts index 2f73de8d36..8b8a1d6064 100644 --- a/packages/nc-gui/composables/useViewFilters.ts +++ b/packages/nc-gui/composables/useViewFilters.ts @@ -192,6 +192,16 @@ export function useViewFilters( } } + const placeholderGroupFilter = (): Filter => { + const logicalOps = new Set(filters.value.slice(1).map((filter) => filter.logical_op)) + + return { + is_group: true, + status: 'create', + logical_op: logicalOps.size === 1 ? logicalOps.values().next().value : 'and', + } + } + const loadAllChildFilters = async (filters: Filter[]) => { // Array to store promises of child filter loading const promises = [] @@ -464,11 +474,7 @@ export function useViewFilters( const addFilterGroup = async () => { const child = placeholderFilter() - const placeHolderGroupFilter: Filter = { - is_group: true, - status: 'create', - logical_op: 'and', - } + const placeHolderGroupFilter: Filter = placeholderGroupFilter() if (nestedMode.value) placeHolderGroupFilter.children = [child] From a55a5466dd5e4ba5489523d7be3f121d84e7ae5a Mon Sep 17 00:00:00 2001 From: Pranav C Date: Wed, 15 May 2024 11:18:18 +0000 Subject: [PATCH 5/6] fix: nested webhook filter related issues --- .../smartsheet/toolbar/ColumnFilter.vue | 27 +- packages/nc-gui/composables/useViewFilters.ts | 26 +- packages/nocodb/src/helpers/webhookHelpers.ts | 438 +++++++++--------- packages/nocodb/src/models/Filter.ts | 4 +- 4 files changed, 259 insertions(+), 236 deletions(-) diff --git a/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue b/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue index 155782497e..05d9fc3e62 100644 --- a/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue +++ b/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue @@ -12,6 +12,7 @@ interface Props { webHook?: boolean draftFilter?: Partial } + const props = withDefaults(defineProps(), { nestedLevel: 0, autoSave: true, @@ -21,13 +22,14 @@ const props = withDefaults(defineProps(), { webHook: false, }) -const emit = defineEmits(['update:filtersLength', 'update:draftFilter']) +const emit = defineEmits(['update:filtersLength', 'update:draftFilter', 'update:modelValue']) const excludedFilterColUidt = [UITypes.QrCode, UITypes.Barcode] const draftFilter = useVModel(props, 'draftFilter', emit) +const modelValue = useVModel(props, 'modelValue', emit) -const { nestedLevel, parentId, autoSave, hookId, modelValue, showLoading, webHook } = toRefs(props) +const { nestedLevel, parentId, autoSave, hookId, showLoading, webHook } = toRefs(props) const nested = computed(() => nestedLevel.value > 0) @@ -66,7 +68,7 @@ const { types, } = useViewFilters( activeView, - parentId?.value, + parentId, computed(() => autoSave.value), () => reloadDataHook.trigger({ shouldShowLoading: showLoading.value, offset: 0 }), modelValue.value || nestedFilters.value, @@ -204,8 +206,10 @@ const applyChanges = async (hookId?: string, nested = false, isConditionSupporte if (!localNestedFilters.value?.length) return + await nextTick() + for (const nestedFilter of localNestedFilters.value) { - if (nestedFilter.parentId) { + if (nestedFilter.parentId?.value) { await nestedFilter.applyChanges(hookId, true) } } @@ -250,7 +254,7 @@ const updateFilterValue = (value: string, filter: Filter, index: number) => { defineExpose({ applyChanges, - parentId: parentId?.value, + parentId, }) const scrollToBottom = () => { @@ -373,6 +377,17 @@ const onLogicalOpUpdate = async (filter: Filter, index: number) => { } await saveOrUpdate(filter, index) } + +// watch for changes in filters and update the modelValue +watch( + filters, + () => { + if (modelValue.value !== filters.value) modelValue.value = filters.value + }, + { + immediate: true, + }, +)