Browse Source

feat: add filter types for multiselect field

pull/4379/head
Southball 2 years ago
parent
commit
38639a5e71
  1. 16
      packages/nc-gui/utils/filterUtils.ts
  2. 42
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts
  3. 20
      packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts
  4. 4
      packages/nocodb/src/lib/models/Filter.ts

16
packages/nc-gui/utils/filterUtils.ts

@ -35,6 +35,22 @@ export const comparisonOpList = [
value: 'notnull', value: 'notnull',
ignoreVal: true, 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: '>', text: '>',
value: 'gt', value: 'gt',

42
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; const _val = customWhereClause ? customWhereClause : filter.value;
return (qb) => { return (qb: Knex.QueryBuilder) => {
let [field, val] = [_field, _val]; let [field, val] = [_field, _val];
switch (filter.comparison_op) { switch (filter.comparison_op) {
case 'eq': case 'eq':
@ -306,6 +306,46 @@ const parseConditionV2 = async (
val val
); );
break; 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': case 'gt':
qb = qb.where(field, customWhereClause ? '<' : '>', val); qb = qb.where(field, customWhereClause ? '<' : '>', val);
break; break;

20
packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts

@ -72,6 +72,26 @@ export async function validateCondition(filters: Filter[], data: any) {
case 'notnull': case 'notnull':
res = data[field] !== null; res = data[field] !== null;
break; 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': case 'lt':
res = +data[field] < +filter.value; res = +data[field] < +filter.value;
break; break;

4
packages/nocodb/src/lib/models/Filter.ts

@ -30,6 +30,10 @@ export default class Filter {
| 'notempty' | 'notempty'
| 'null' | 'null'
| 'notnull' | 'notnull'
| 'allof'
| 'anyof'
| 'nallof'
| 'nanyof'
| 'gt' | 'gt'
| 'lt' | 'lt'
| 'gte' | 'gte'

Loading…
Cancel
Save