diff --git a/packages/nc-gui/components/cell/MultiSelect.vue b/packages/nc-gui/components/cell/MultiSelect.vue index 7bd77a36ef..9d6ec72434 100644 --- a/packages/nc-gui/components/cell/MultiSelect.vue +++ b/packages/nc-gui/components/cell/MultiSelect.vue @@ -32,6 +32,7 @@ interface Props { modelValue?: string | string[] rowIndex?: number disableOptionCreation?: boolean + location?: 'cell' | 'filter' } const { modelValue, disableOptionCreation } = defineProps() @@ -336,7 +337,7 @@ useEventListener(document, 'click', handleClose, true) v-for="op of options" :key="op.id || op.title" :value="op.title" - :data-testid="`select-option-${column.title}-${rowIndex}`" + :data-testid="`select-option-${column.title}-${location === 'filter' ? 'filter' : rowIndex}`" :class="`nc-select-option-${column.title}-${op.title}`" @click.stop > diff --git a/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue b/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue index c0a7ec2ec2..c5e12a6b5a 100644 --- a/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue +++ b/packages/nc-gui/components/smartsheet/toolbar/ColumnFilter.vue @@ -85,17 +85,17 @@ const filterUpdateCondition = (filter: FilterType, i: number) => { ) { // anyof and nanyof can allow multiple selections, // while `eq` and `neq` only allow one selection - filter.value = '' + filter.value = null } else if (['blank', 'notblank', 'empty', 'notempty', 'null', 'notnull'].includes(filter.comparison_op!)) { // since `blank`, `empty`, `null` doesn't require value, // hence remove the previous value - filter.value = '' + filter.value = null filter.comparison_sub_op = null } else if ([UITypes.Date, UITypes.DateTime].includes(col.uidt as UITypes)) { // for date / datetime, // the input type could be decimal or datepicker / datetime picker // hence remove the previous value - filter.value = '' + filter.value = null if ( !comparisonSubOpList(filter.comparison_op!) .map((op) => op.value) @@ -181,7 +181,7 @@ const selectFilterField = (filter: Filter, index: number) => { } // reset filter value as well - filter.value = '' + filter.value = null saveOrUpdate(filter, index) } diff --git a/packages/nc-gui/components/smartsheet/toolbar/FilterInput.vue b/packages/nc-gui/components/smartsheet/toolbar/FilterInput.vue index 6a2072cba4..f664861195 100644 --- a/packages/nc-gui/components/smartsheet/toolbar/FilterInput.vue +++ b/packages/nc-gui/components/smartsheet/toolbar/FilterInput.vue @@ -193,6 +193,7 @@ const hasExtraPadding = $computed(() => { :column="column" class="flex" v-bind="componentProps" + location="filter" /> diff --git a/packages/nc-gui/lang/ar.json b/packages/nc-gui/lang/ar.json index 12bf7e1643..26c204e25b 100644 --- a/packages/nc-gui/lang/ar.json +++ b/packages/nc-gui/lang/ar.json @@ -235,6 +235,7 @@ "action": "إجراء", "actions": "إجراءات", "operation": "عملية", + "operationSub": "Sub Operation", "operationType": "نوع العملية", "operationSubType": "نوع العملية الفرعية", "description": "وصف", diff --git a/packages/nc-gui/lang/bn_IN.json b/packages/nc-gui/lang/bn_IN.json index 0076d7f265..f33c7f131c 100644 --- a/packages/nc-gui/lang/bn_IN.json +++ b/packages/nc-gui/lang/bn_IN.json @@ -235,6 +235,7 @@ "action": "কর্ম", "actions": "ক্রিয়া", "operation": "অপারেশন", + "operationSub": "Sub Operation", "operationType": "অপারেশন টাইপ", "operationSubType": "অপারেশন সাব-টাইপ", "description": "বর্ণনা", diff --git a/packages/nc-gui/lang/cs.json b/packages/nc-gui/lang/cs.json index bbddc339ee..9e37208137 100644 --- a/packages/nc-gui/lang/cs.json +++ b/packages/nc-gui/lang/cs.json @@ -235,6 +235,7 @@ "action": "Akce", "actions": "Akce", "operation": "Operace", + "operationSub": "Sub Operation", "operationType": "Typ operace", "operationSubType": "Podtyp operace", "description": "Popis", diff --git a/packages/nc-gui/lang/da.json b/packages/nc-gui/lang/da.json index 5e6e82e416..e67b4258f8 100644 --- a/packages/nc-gui/lang/da.json +++ b/packages/nc-gui/lang/da.json @@ -235,6 +235,7 @@ "action": "Handling", "actions": "Handlinger", "operation": "Operation", + "operationSub": "Sub Operation", "operationType": "Driftstype", "operationSubType": "Drift Undertype", "description": "Beskrivelse", diff --git a/packages/nc-gui/lang/de.json b/packages/nc-gui/lang/de.json index f7b7de89da..7755573d83 100644 --- a/packages/nc-gui/lang/de.json +++ b/packages/nc-gui/lang/de.json @@ -100,7 +100,7 @@ "form": "Formular", "kanban": "Kanban", "calendar": "Kalender", - "map": "Karte" + "map": "Map" }, "user": "Nutzer", "users": "Benutzer", @@ -235,6 +235,7 @@ "action": "Aktion", "actions": "Aktionen", "operation": "Vorgang", + "operationSub": "Sub Operation", "operationType": "Vorgangstyp", "operationSubType": "Vorgangsuntertyp", "description": "Beschreibung", diff --git a/packages/nc-gui/lang/es.json b/packages/nc-gui/lang/es.json index ade0869efe..8083d12c77 100644 --- a/packages/nc-gui/lang/es.json +++ b/packages/nc-gui/lang/es.json @@ -235,6 +235,7 @@ "action": "Acción", "actions": "Acciones", "operation": "Operación", + "operationSub": "Sub Operation", "operationType": "Tipo de operación", "operationSubType": "Sub-tipo de operación", "description": "Descripción", diff --git a/packages/nc-gui/lang/eu.json b/packages/nc-gui/lang/eu.json index 225443c97e..5c07152283 100644 --- a/packages/nc-gui/lang/eu.json +++ b/packages/nc-gui/lang/eu.json @@ -235,6 +235,7 @@ "action": "Ekintza", "actions": "Ekintzak", "operation": "Operation", + "operationSub": "Sub Operation", "operationType": "Operation type", "operationSubType": "Operation sub-type", "description": "Deskribapena", diff --git a/packages/nc-gui/lang/fa.json b/packages/nc-gui/lang/fa.json index 143ebc22da..9d0f71daf5 100644 --- a/packages/nc-gui/lang/fa.json +++ b/packages/nc-gui/lang/fa.json @@ -235,6 +235,7 @@ "action": "اقدام", "actions": "اقدامات", "operation": "عملیات", + "operationSub": "Sub Operation", "operationType": "نوع عملیات", "operationSubType": "زیرگونه عملیات", "description": "شرح", diff --git a/packages/nc-gui/lang/fi.json b/packages/nc-gui/lang/fi.json index d9d6af711b..df9f79d663 100644 --- a/packages/nc-gui/lang/fi.json +++ b/packages/nc-gui/lang/fi.json @@ -235,6 +235,7 @@ "action": "Toiminta", "actions": "Toiminnot", "operation": "Operaatio", + "operationSub": "Sub Operation", "operationType": "Käyttötyyppi", "operationSubType": "Käyttö Alatyyppi", "description": "Kuvaus", diff --git a/packages/nc-gui/lang/fr.json b/packages/nc-gui/lang/fr.json index 8607928f95..3fc72b3c50 100644 --- a/packages/nc-gui/lang/fr.json +++ b/packages/nc-gui/lang/fr.json @@ -235,6 +235,7 @@ "action": "Action", "actions": "Actions", "operation": "Opération", + "operationSub": "Sub Operation", "operationType": "Type d'opération", "operationSubType": "Sous-type d'opération", "description": "Description", diff --git a/packages/nc-gui/lang/he.json b/packages/nc-gui/lang/he.json index cacce26319..e94b64fda4 100644 --- a/packages/nc-gui/lang/he.json +++ b/packages/nc-gui/lang/he.json @@ -235,6 +235,7 @@ "action": "פעולה", "actions": "פעולות", "operation": "מבצע", + "operationSub": "Sub Operation", "operationType": "סוג הפעולה", "operationSubType": "מבצע תת-סוג", "description": "תיאור", diff --git a/packages/nc-gui/lang/hi.json b/packages/nc-gui/lang/hi.json index 5740c4e26a..d2ee6cf202 100644 --- a/packages/nc-gui/lang/hi.json +++ b/packages/nc-gui/lang/hi.json @@ -235,6 +235,7 @@ "action": "गतिविधि", "actions": "कार्रवाई", "operation": "संचालन", + "operationSub": "Sub Operation", "operationType": "प्रचालन प्रकार", "operationSubType": "प्रचालन उप-प्रकार", "description": "विवरण", diff --git a/packages/nc-gui/lang/hr.json b/packages/nc-gui/lang/hr.json index d24505daeb..b8d4e65de4 100644 --- a/packages/nc-gui/lang/hr.json +++ b/packages/nc-gui/lang/hr.json @@ -235,6 +235,7 @@ "action": "Akcijski", "actions": "Akcije", "operation": "Operacija", + "operationSub": "Sub Operation", "operationType": "Vrsta rada", "operationSubType": "Operacija pod-vrsti", "description": "Opis", diff --git a/packages/nc-gui/lang/id.json b/packages/nc-gui/lang/id.json index dd5ae4a49c..b010e87ffb 100644 --- a/packages/nc-gui/lang/id.json +++ b/packages/nc-gui/lang/id.json @@ -235,6 +235,7 @@ "action": "Tindakan", "actions": "Tindakan", "operation": "Operasi", + "operationSub": "Sub Operation", "operationType": "Jenis operasi", "operationSubType": "SUB-tipe operasi", "description": "Keterangan", diff --git a/packages/nc-gui/lang/it.json b/packages/nc-gui/lang/it.json index f9ad41d9b6..0c013a7a2e 100644 --- a/packages/nc-gui/lang/it.json +++ b/packages/nc-gui/lang/it.json @@ -235,6 +235,7 @@ "action": "Azione", "actions": "Azioni", "operation": "Operazione", + "operationSub": "Sub Operation", "operationType": "Tipo di operazioni", "operationSubType": "Sottotipo di operazioni", "description": "Descrizione", diff --git a/packages/nc-gui/lang/ja.json b/packages/nc-gui/lang/ja.json index 03e492f329..32660df6c9 100644 --- a/packages/nc-gui/lang/ja.json +++ b/packages/nc-gui/lang/ja.json @@ -235,6 +235,7 @@ "action": "アクション", "actions": "アクション", "operation": "操作", + "operationSub": "Sub Operation", "operationType": "操作タイプ", "operationSubType": "操作サブタイプ", "description": "説明", diff --git a/packages/nc-gui/lang/ko.json b/packages/nc-gui/lang/ko.json index 99ab014235..8750b16da6 100644 --- a/packages/nc-gui/lang/ko.json +++ b/packages/nc-gui/lang/ko.json @@ -235,6 +235,7 @@ "action": "동작", "actions": "행위", "operation": "작업", + "operationSub": "Sub Operation", "operationType": "작업 유형", "operationSubType": "작업 하위 유형", "description": "설명", diff --git a/packages/nc-gui/lang/lv.json b/packages/nc-gui/lang/lv.json index b859e014fd..e829794413 100644 --- a/packages/nc-gui/lang/lv.json +++ b/packages/nc-gui/lang/lv.json @@ -235,6 +235,7 @@ "action": "Darbība", "actions": "Darbības", "operation": "Operācija", + "operationSub": "Sub Operation", "operationType": "Operācijas tips", "operationSubType": "Operācijas apakštips", "description": "Apraksts", diff --git a/packages/nc-gui/lang/nl.json b/packages/nc-gui/lang/nl.json index 004c5205aa..87c859c727 100644 --- a/packages/nc-gui/lang/nl.json +++ b/packages/nc-gui/lang/nl.json @@ -235,6 +235,7 @@ "action": "Actie", "actions": "Acties", "operation": "Operatie", + "operationSub": "Sub Operation", "operationType": "Operatietype", "operationSubType": "Operatiesubtype", "description": "Beschrijving", diff --git a/packages/nc-gui/lang/no.json b/packages/nc-gui/lang/no.json index c4ec420be1..48578f91a4 100644 --- a/packages/nc-gui/lang/no.json +++ b/packages/nc-gui/lang/no.json @@ -235,6 +235,7 @@ "action": "Handling", "actions": "Handlinger", "operation": "Operasjon", + "operationSub": "Sub Operation", "operationType": "Operasjonstype", "operationSubType": "OPERATION SUB-TYPE", "description": "Beskrivelse", diff --git a/packages/nc-gui/lang/pl.json b/packages/nc-gui/lang/pl.json index d3c9dae2c4..6b40787b6a 100644 --- a/packages/nc-gui/lang/pl.json +++ b/packages/nc-gui/lang/pl.json @@ -235,6 +235,7 @@ "action": "Akcja", "actions": "Akcje", "operation": "Operacja", + "operationSub": "Sub Operation", "operationType": "Typ operacji", "operationSubType": "Podtypowy akcji", "description": "Opis", diff --git a/packages/nc-gui/lang/pt.json b/packages/nc-gui/lang/pt.json index 93427b42bd..4acd062047 100644 --- a/packages/nc-gui/lang/pt.json +++ b/packages/nc-gui/lang/pt.json @@ -235,6 +235,7 @@ "action": "Açao", "actions": "Ações", "operation": "Operação", + "operationSub": "Sub Operation", "operationType": "Tipo de operação", "operationSubType": "Sub-tipo de operação", "description": "Descrição", diff --git a/packages/nc-gui/lang/pt_BR.json b/packages/nc-gui/lang/pt_BR.json index 49ee9dff36..1ce3a257f7 100644 --- a/packages/nc-gui/lang/pt_BR.json +++ b/packages/nc-gui/lang/pt_BR.json @@ -235,6 +235,7 @@ "action": "Açao", "actions": "Ações", "operation": "Operação", + "operationSub": "Sub Operation", "operationType": "Tipo de operação", "operationSubType": "Sub-tipo de operação", "description": "Descrição", diff --git a/packages/nc-gui/lang/ru.json b/packages/nc-gui/lang/ru.json index b388d7eb7d..f4af5a6914 100644 --- a/packages/nc-gui/lang/ru.json +++ b/packages/nc-gui/lang/ru.json @@ -235,6 +235,7 @@ "action": "Действие", "actions": "Действия", "operation": "Операция", + "operationSub": "Sub Operation", "operationType": "Тип операции", "operationSubType": "Подтип операции", "description": "Описание", diff --git a/packages/nc-gui/lang/sk.json b/packages/nc-gui/lang/sk.json index 33846c7b85..1e44b4a008 100644 --- a/packages/nc-gui/lang/sk.json +++ b/packages/nc-gui/lang/sk.json @@ -235,6 +235,7 @@ "action": "Akcia", "actions": "Činnosti", "operation": "Operácia", + "operationSub": "Sub Operation", "operationType": "Typ operácie", "operationSubType": "Podtyp operácie", "description": "Popis", diff --git a/packages/nc-gui/lang/sl.json b/packages/nc-gui/lang/sl.json index 628409afd4..342f80a0c1 100644 --- a/packages/nc-gui/lang/sl.json +++ b/packages/nc-gui/lang/sl.json @@ -235,6 +235,7 @@ "action": "Akcija", "actions": "Akcijah", "operation": "Operacija", + "operationSub": "Sub Operation", "operationType": "Tip operacije.", "operationSubType": "Podpis delovanja", "description": "Opis", diff --git a/packages/nc-gui/lang/sv.json b/packages/nc-gui/lang/sv.json index ee63c50cfd..dfda739496 100644 --- a/packages/nc-gui/lang/sv.json +++ b/packages/nc-gui/lang/sv.json @@ -235,6 +235,7 @@ "action": "Handling", "actions": "Handlingar", "operation": "Drift", + "operationSub": "Sub Operation", "operationType": "Driftstyp", "operationSubType": "Driftstyp", "description": "Beskrivning", diff --git a/packages/nc-gui/lang/th.json b/packages/nc-gui/lang/th.json index 53197156b0..589a2b476b 100644 --- a/packages/nc-gui/lang/th.json +++ b/packages/nc-gui/lang/th.json @@ -235,6 +235,7 @@ "action": "หนังบู๊", "actions": "การกระทำ", "operation": "การดำเนินการ", + "operationSub": "Sub Operation", "operationType": "ประเภทการทำงาน", "operationSubType": "การดำเนินงานประเภทย่อย", "description": "คำอธิบาย", diff --git a/packages/nc-gui/lang/tr.json b/packages/nc-gui/lang/tr.json index 23ad9a2bf6..c3ce9382e3 100644 --- a/packages/nc-gui/lang/tr.json +++ b/packages/nc-gui/lang/tr.json @@ -235,6 +235,7 @@ "action": "Aksiyon", "actions": "Aksiyonlar", "operation": "İşlem", + "operationSub": "Sub Operation", "operationType": "İşlem türü", "operationSubType": "İşlem alt-türü", "description": "Tanım", diff --git a/packages/nc-gui/lang/uk.json b/packages/nc-gui/lang/uk.json index 2ed4552a0a..37e1d4d4d0 100644 --- a/packages/nc-gui/lang/uk.json +++ b/packages/nc-gui/lang/uk.json @@ -235,6 +235,7 @@ "action": "Дія", "actions": "Дії", "operation": "Операція", + "operationSub": "Sub Operation", "operationType": "Тип операції", "operationSubType": "Підтип операції", "description": "Опис", diff --git a/packages/nc-gui/lang/vi.json b/packages/nc-gui/lang/vi.json index 95b6ae905c..9c58464de0 100644 --- a/packages/nc-gui/lang/vi.json +++ b/packages/nc-gui/lang/vi.json @@ -235,6 +235,7 @@ "action": "Hoạt động", "actions": "Hành động", "operation": "Hoạt động", + "operationSub": "Sub Operation", "operationType": "Loại hoạt động", "operationSubType": "Loại phụ hoạt động", "description": "Sự miêu tả", diff --git a/packages/nc-gui/lang/zh-Hans.json b/packages/nc-gui/lang/zh-Hans.json index 328a296f47..85c11e5adb 100644 --- a/packages/nc-gui/lang/zh-Hans.json +++ b/packages/nc-gui/lang/zh-Hans.json @@ -235,6 +235,7 @@ "action": "操作", "actions": "操作", "operation": "操作", + "operationSub": "Sub Operation", "operationType": "操作类型", "operationSubType": "子操作类型", "description": "描述", diff --git a/packages/nc-gui/lang/zh-Hant.json b/packages/nc-gui/lang/zh-Hant.json index 18a6d91fe0..94b2e029b4 100644 --- a/packages/nc-gui/lang/zh-Hant.json +++ b/packages/nc-gui/lang/zh-Hant.json @@ -235,6 +235,7 @@ "action": "行動", "actions": "行動", "operation": "操作", + "operationSub": "Sub Operation", "operationType": "操作類型", "operationSubType": "操作子類型", "description": "描述", 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 8fe4f6b7a5..5e536d7bcd 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 @@ -90,10 +90,20 @@ const parseConditionV2 = async ( const parentModel = await parentColumn.getModel(); await parentModel.getColumns(); if (colOptions.type === RelationTypes.HAS_MANY) { - if ( - filter.comparison_op === 'empty' || - filter.comparison_op === 'notempty' - ) { + if (['blank', 'notblank'].includes(filter.comparison_op)) { + // handle self reference + if (parentModel.id === childModel.id) { + if (filter.comparison_op === 'blank') { + return (qb) => { + qb.whereNull(childColumn.column_name); + }; + } else { + return (qb) => { + qb.whereNotNull(childColumn.column_name); + }; + } + } + const selectHmCount = knex(childModel.table_name) .count(childColumn.column_name) .where( @@ -105,7 +115,7 @@ const parseConditionV2 = async ( ); return (qb) => { - if (filter.comparison_op === 'empty') { + if (filter.comparison_op === 'blank') { qb.where(knex.raw('0'), selectHmCount); } else { qb.whereNot(knex.raw('0'), selectHmCount); @@ -136,14 +146,36 @@ const parseConditionV2 = async ( else qbP.whereIn(parentColumn.column_name, selectQb); }; } else if (colOptions.type === RelationTypes.BELONGS_TO) { - if (filter.comparison_op === 'null') { - return (qb) => { - qb.whereNull(childColumn.column_name); - }; - } - if (filter.comparison_op === 'notnull') { + if (['blank', 'notblank'].includes(filter.comparison_op)) { + // handle self reference + if (parentModel.id === childModel.id) { + if (filter.comparison_op === 'blank') { + return (qb) => { + qb.whereNull(childColumn.column_name); + }; + } else { + return (qb) => { + qb.whereNotNull(childColumn.column_name); + }; + } + } + + const selectBtCount = knex(parentModel.table_name) + .count(parentColumn.column_name) + .where( + parentColumn.column_name, + knex.raw('??.??', [ + alias || childModel.table_name, + childColumn.column_name, + ]) + ); + return (qb) => { - qb.whereNotNull(childColumn.column_name); + if (filter.comparison_op === 'blank') { + qb.where(knex.raw('0'), selectBtCount); + } else { + qb.whereNot(knex.raw('0'), selectBtCount); + } }; } @@ -175,10 +207,20 @@ const parseConditionV2 = async ( const mmParentColumn = await colOptions.getMMParentColumn(); const mmChildColumn = await colOptions.getMMChildColumn(); - if ( - filter.comparison_op === 'empty' || - filter.comparison_op === 'notempty' - ) { + if (['blank', 'notblank'].includes(filter.comparison_op)) { + // handle self reference + if (mmModel.id === childModel.id) { + if (filter.comparison_op === 'blank') { + return (qb) => { + qb.whereNull(childColumn.column_name); + }; + } else { + return (qb) => { + qb.whereNotNull(childColumn.column_name); + }; + } + } + const selectMmCount = knex(mmModel.table_name) .count(mmChildColumn.column_name) .where( @@ -190,7 +232,7 @@ const parseConditionV2 = async ( ); return (qb) => { - if (filter.comparison_op === 'empty') { + if (filter.comparison_op === 'blank') { qb.where(knex.raw('0'), selectMmCount); } else { qb.whereNot(knex.raw('0'), selectMmCount); @@ -205,6 +247,7 @@ const parseConditionV2 = async ( `${mmModel.table_name}.${mmParentColumn.column_name}`, `${parentModel.table_name}.${parentColumn.column_name}` ); + ( await parseConditionV2( new Filter({ diff --git a/tests/playwright/pages/Dashboard/common/Toolbar/Filter.ts b/tests/playwright/pages/Dashboard/common/Toolbar/Filter.ts index 10d7892b76..44e3457638 100644 --- a/tests/playwright/pages/Dashboard/common/Toolbar/Filter.ts +++ b/tests/playwright/pages/Dashboard/common/Toolbar/Filter.ts @@ -123,7 +123,7 @@ export class ToolbarFilterPage extends BasePage { for (let i = 0; i < v.length; i++) { await this.rootPage .locator(`.nc-dropdown-multi-select-cell`) - .locator(`.nc-select-option-MultiSelect-${v[i]}`) + .locator(`[data-testid="select-option-MultiSelect-filter"].nc-select-option-MultiSelect-${v[i]}`) .click(); } break;