Browse Source

fix: issues with multiselect filters

pull/4379/head
Southball 2 years ago
parent
commit
10b669b0cf
  1. 14
      packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue
  2. 4
      packages/nc-gui/utils/filterUtils.ts
  3. 4
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts
  4. 8
      packages/nocodb/src/lib/meta/helpers/webhookHelpers.ts

14
packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue

@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import type { FilterType } from 'nocodb-sdk' import type { ColumnType, FilterType } from 'nocodb-sdk'
import { UITypes } from 'nocodb-sdk' import { UITypes } from 'nocodb-sdk'
import { import {
ActiveViewInj, ActiveViewInj,
@ -100,6 +100,11 @@ watch(
}, },
) )
const getApplicableFilters = (id?: string) => {
const colType = (meta.value?.columnsById as Record<string, ColumnType>)?.[id ?? '']?.uidt
return comparisonOpList.filter((op) => !op.types || op.types.includes(colType))
}
const applyChanges = async (hookId?: string, _nested = false) => { const applyChanges = async (hookId?: string, _nested = false) => {
await sync(hookId, _nested) await sync(hookId, _nested)
@ -213,7 +218,12 @@ defineExpose({
dropdown-class-name="nc-dropdown-filter-comp-op" dropdown-class-name="nc-dropdown-filter-comp-op"
@change="filterUpdateCondition(filter, i)" @change="filterUpdateCondition(filter, i)"
> >
<a-select-option v-for="compOp in comparisonOpList" :key="compOp.value" :value="compOp.value" class=""> <a-select-option
v-for="compOp in getApplicableFilters(filter.fk_column_id)"
:key="compOp.value"
:value="compOp.value"
class=""
>
{{ compOp.text }} {{ compOp.text }}
</a-select-option> </a-select-option>
</a-select> </a-select>

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

@ -38,18 +38,22 @@ export const comparisonOpList = [
{ {
text: 'contains all of', text: 'contains all of',
value: 'allof', value: 'allof',
types: ['MultiSelect'],
}, },
{ {
text: 'contains any of', text: 'contains any of',
value: 'anyof', value: 'anyof',
types: ['MultiSelect'],
}, },
{ {
text: 'does not contain all of', text: 'does not contain all of',
value: 'nallof', value: 'nallof',
types: ['MultiSelect'],
}, },
{ {
text: 'does not contain any of', text: 'does not contain any of',
value: 'nanyof', value: 'nanyof',
types: ['MultiSelect'],
}, },
{ {
text: '>', text: '>',

4
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/conditionV2.ts

@ -312,7 +312,7 @@ const parseConditionV2 = async (
case 'nanyof': case 'nanyof':
// Condition for filter, without negation // Condition for filter, without negation
const condition = (builder: Knex.QueryBuilder) => { const condition = (builder: Knex.QueryBuilder) => {
const items = val.split(','); const items = val.split(',').map((item) => item.trim());
for (let i = 0; i < items.length; i++) { for (let i = 0; i < items.length; i++) {
let sql; let sql;
const bindings = [field, `%,${items[i]},%`]; const bindings = [field, `%,${items[i]},%`];
@ -343,7 +343,7 @@ const parseConditionV2 = async (
) { ) {
qb = qb.where(condition); qb = qb.where(condition);
} else { } else {
qb = qb.whereNot(condition); qb = qb.whereNot(condition).orWhereNull(field);
} }
break; break;
case 'gt': case 'gt':

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

@ -73,22 +73,22 @@ export async function validateCondition(filters: Filter[], data: any) {
res = data[field] !== null; res = data[field] !== null;
break; break;
case 'allof': case 'allof':
res = (filter.value?.split(',') ?? []).every((item) => res = (filter.value?.split(',').map((item) => item.trim()) ?? []).every((item) =>
(data[field]?.split(',') ?? []).includes(item) (data[field]?.split(',') ?? []).includes(item)
); );
break; break;
case 'anyof': case 'anyof':
res = (filter.value?.split(',') ?? []).some((item) => res = (filter.value?.split(',').map((item) => item.trim()) ?? []).some((item) =>
(data[field]?.split(',') ?? []).includes(item) (data[field]?.split(',') ?? []).includes(item)
); );
break; break;
case 'nallof': case 'nallof':
res = !(filter.value?.split(',') ?? []).every((item) => res = !(filter.value?.split(',').map((item) => item.trim()) ?? []).every((item) =>
(data[field]?.split(',') ?? []).includes(item) (data[field]?.split(',') ?? []).includes(item)
); );
break; break;
case 'nanyof': case 'nanyof':
res = !(filter.value?.split(',') ?? []).some((item) => res = !(filter.value?.split(',').map((item) => item.trim()) ?? []).some((item) =>
(data[field]?.split(',') ?? []).includes(item) (data[field]?.split(',') ?? []).includes(item)
); );
break; break;

Loading…
Cancel
Save