From 38639a5e71af36a423bb3a832b3e1071109fea26 Mon Sep 17 00:00:00 2001 From: Southball <6523469+southball@users.noreply.github.com> Date: Sun, 13 Nov 2022 17:55:47 +0900 Subject: [PATCH 1/3] feat: add filter types for multiselect field --- packages/nc-gui/utils/filterUtils.ts | 16 +++++++ .../db/sql-data-mapper/lib/sql/conditionV2.ts | 42 ++++++++++++++++++- .../src/lib/meta/helpers/webhookHelpers.ts | 20 +++++++++ packages/nocodb/src/lib/models/Filter.ts | 4 ++ 4 files changed, 81 insertions(+), 1 deletion(-) diff --git a/packages/nc-gui/utils/filterUtils.ts b/packages/nc-gui/utils/filterUtils.ts index a645b7d570..e14d41917d 100644 --- a/packages/nc-gui/utils/filterUtils.ts +++ b/packages/nc-gui/utils/filterUtils.ts @@ -35,6 +35,22 @@ export const comparisonOpList = [ value: 'notnull', ignoreVal: true, }, + { + text: 'contains all of', + value: 'allof', + }, + { + text: 'contains any of', + value: 'anyof', + }, + { + text: 'does not contain all of', + value: 'nallof', + }, + { + text: 'does not contain any of', + value: 'nanyof', + }, { text: '>', value: 'gt', diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts index 942b1dbb8f..fa687d1100 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts @@ -270,7 +270,7 @@ const parseConditionV2 = async ( ); const _val = customWhereClause ? customWhereClause : filter.value; - return (qb) => { + return (qb: Knex.QueryBuilder) => { let [field, val] = [_field, _val]; switch (filter.comparison_op) { case 'eq': @@ -306,6 +306,46 @@ const parseConditionV2 = async ( val ); break; + case 'allof': + case 'anyof': + case 'nallof': + case 'nanyof': + // Condition for filter, without negation + const condition = (builder: Knex.QueryBuilder) => { + const items = val.split(','); + for (let i = 0; i < items.length; i++) { + let sql; + const bindings = [field, `%,${items[i]},%`]; + if (qb?.client?.config?.client === 'pg') { + sql = "(',' || ??::text || ',') ilike ?"; + } else if (qb?.client?.config?.client === 'sqlite3') { + sql = "(',' || ?? || ',') like ?"; + } else { + sql = "CONCAT(',', ??, ',') like ?"; + } + if (i === 0) { + builder = builder.whereRaw(sql, bindings); + } else { + if ( + filter.comparison_op === 'allof' || + filter.comparison_op === 'nallof' + ) { + builder = builder.andWhereRaw(sql, bindings); + } else { + builder = builder.orWhereRaw(sql, bindings); + } + } + } + }; + if ( + filter.comparison_op === 'allof' || + filter.comparison_op === 'anyof' + ) { + qb = qb.where(condition); + } else { + qb = qb.whereNot(condition); + } + break; case 'gt': qb = qb.where(field, customWhereClause ? '<' : '>', val); break; diff --git a/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts b/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts index 697115bcec..6fb3bc4397 100644 --- a/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts +++ b/packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts @@ -72,6 +72,26 @@ export async function validateCondition(filters: Filter[], data: any) { case 'notnull': res = data[field] !== null; break; + case 'allof': + res = (filter.value?.split(',') ?? []).every((item) => + (data[field]?.split(',') ?? []).includes(item) + ); + break; + case 'anyof': + res = (filter.value?.split(',') ?? []).some((item) => + (data[field]?.split(',') ?? []).includes(item) + ); + break; + case 'nallof': + res = !(filter.value?.split(',') ?? []).every((item) => + (data[field]?.split(',') ?? []).includes(item) + ); + break; + case 'nanyof': + res = !(filter.value?.split(',') ?? []).some((item) => + (data[field]?.split(',') ?? []).includes(item) + ); + break; case 'lt': res = +data[field] < +filter.value; break; diff --git a/packages/nocodb/src/lib/models/Filter.ts b/packages/nocodb/src/lib/models/Filter.ts index 34ff8a2f50..9db23f4b35 100644 --- a/packages/nocodb/src/lib/models/Filter.ts +++ b/packages/nocodb/src/lib/models/Filter.ts @@ -30,6 +30,10 @@ export default class Filter { | 'notempty' | 'null' | 'notnull' + | 'allof' + | 'anyof' + | 'nallof' + | 'nanyof' | 'gt' | 'lt' | 'gte' From 10b669b0cff5517df437948794e2a079b511ea39 Mon Sep 17 00:00:00 2001 From: Southball <6523469+southball@users.noreply.github.com> Date: Sat, 24 Dec 2022 11:59:44 +0900 Subject: [PATCH 2/3] fix: issues with multiselect filters --- .../components/smartsheet/toolbar/ColumnFilter.vue | 14 ++++++++++++-- packages/nc-gui/utils/filterUtils.ts | 4 ++++ .../lib/db/sql-data-mapper/lib/sql/conditionV2.ts | 4 ++-- .../nocodb/src/lib/meta/helpers/webhookHelpers.ts | 8 ++++---- 4 files changed, 22 insertions(+), 8 deletions(-) diff --git a/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue b/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue index 9bb1fedc8e..8a0e41f190 100644 --- a/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue +++ b/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue @@ -1,5 +1,5 @@