diff --git a/CHANGELOG.md b/CHANGELOG.md index 7edd6caa..b108827d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +### 1.X - 2026-01-X +- Add Array filter types + - ARRAY_CONTAINS_ALL, ARRAY_CONTAINS_ANY, ARRAY_CONTAINS_EXACT, ARRAY_ISEMPTY, ARRAY_ISNOTEMPTY + ### 1.44.1 - 2026-01-07 - Lineage: add "restricted" property diff --git a/package-lock.json b/package-lock.json index 45b738ad..1f03519f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@labkey/api", - "version": "1.44.1", + "version": "1.45.0-fb-mvtc.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@labkey/api", - "version": "1.44.1", + "version": "1.45.0-fb-mvtc.4", "license": "Apache-2.0", "devDependencies": { "@babel/core": "7.28.5", diff --git a/package.json b/package.json index 17a36fca..07055c26 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@labkey/api", - "version": "1.44.1", + "version": "1.45.0-fb-mvtc.4", "description": "JavaScript client API for LabKey Server", "scripts": { "build": "npm run build:dist && npm run build:docs", diff --git a/src/labkey/filter/Types.ts b/src/labkey/filter/Types.ts index 60f14e12..a992ea64 100644 --- a/src/labkey/filter/Types.ts +++ b/src/labkey/filter/Types.ts @@ -128,6 +128,47 @@ export const Types: Record = { // These operators require a data value // + ARRAY_CONTAINS_ALL: registerFilterType( + 'Contains All', + null, + 'arraycontainsall', + true, + ',', + 'Contains All Of' + ), + ARRAY_CONTAINS_ANY: registerFilterType( + 'Contains Any', + null, + 'arraycontainsany', + true, + ',', + 'Contains At Least One Of' + ), + ARRAY_CONTAINS_EXACT: registerFilterType( + 'Contains Exactly', + null, + 'arraymatches', + true, + ',', + 'Contains Exactly the Selected Values' + ), + ARRAY_CONTAINS_NOT_EXACT: registerFilterType( + 'Does Not Contain Exactly', + null, + 'arraynotmatches', + true, + ',', + 'Does Not Contains Exactly the Selected Values' + ), + ARRAY_CONTAINS_NONE: registerFilterType( + 'Contains None', + null, + 'arraycontainsnone', + true, + ',', + 'Contains None Of' + ), + EQUAL, DATE_EQUAL: registerFilterType( EQUAL.getDisplayText(), @@ -271,6 +312,29 @@ export const Types: Record = { // These are the 'no data value' operators // + ARRAY_ISEMPTY: registerFilterType( + 'Is Empty', + null, + 'arrayisempty', + false, + undefined, + undefined, + undefined, + undefined, + false, + ), + ARRAY_ISNOTEMPTY: registerFilterType( + 'Is Not Empty', + null, + 'arrayisnotempty', + false, + undefined, + undefined, + undefined, + undefined, + false, + ), + // NOTE: This type, for better or worse, uses empty string as it's urlSuffix. // The result is a filter that is encoded as ".~=". HAS_ANY_VALUE: registerFilterType('Has Any Value', null, ''), @@ -359,9 +423,10 @@ export const Types: Record = { EXP_LINEAGE_OF: registerFilterType('In The Lineage Of', null, 'exp:lineageof', true, ',', ' in the lineage of'), }; -export type JsonType = 'boolean' | 'date' | 'float' | 'int' | 'string' | 'time'; +export type JsonType = 'array' | 'boolean' | 'date' | 'float' | 'int' | 'string' | 'time'; export const TYPES_BY_JSON_TYPE: Record = { + array: [Types.ARRAY_ISEMPTY, Types.ARRAY_ISNOTEMPTY, Types.ARRAY_CONTAINS_ALL, Types.ARRAY_CONTAINS_NONE, Types.ARRAY_CONTAINS_ANY, Types.ARRAY_CONTAINS_EXACT, Types.ARRAY_CONTAINS_NOT_EXACT], boolean: [Types.HAS_ANY_VALUE, Types.EQUAL, Types.NEQ_OR_NULL, Types.ISBLANK, Types.NONBLANK], date: [ Types.DATE_EQUAL, @@ -440,6 +505,7 @@ export const TYPES_BY_JSON_TYPE: Record = { // TODO: Update to Record export const TYPES_BY_JSON_TYPE_DEFAULT: Record = { + array: Types.ARRAY_CONTAINS_ALL, boolean: Types.EQUAL, date: Types.DATE_EQUAL, float: Types.EQUAL, diff --git a/src/test/data/filter_types_snapshot.json b/src/test/data/filter_types_snapshot.json index cd3e6334..103b7a3d 100644 --- a/src/test/data/filter_types_snapshot.json +++ b/src/test/data/filter_types_snapshot.json @@ -1,4 +1,123 @@ { + "ARRAY_CONTAINS_ALL": { + "getDisplaySymbol": null, + "getDisplayText": "Contains All", + "getLabKeySqlOperator": "undefined", + "getLongDisplayText": "Contains All Of", + "getMultiValueFilter": null, + "getMultiValueMaxOccurs": "undefined", + "getMultiValueMinOccurs": "undefined", + "getMultiValueSeparator": ",", + "getOpposite": null, + "getSingleValueFilter": "undefined", + "getURLParameterValue": "undefined", + "getURLSuffix": "arraycontainsall", + "isDataValueRequired": true, + "isMultiValued": true, + "isTableWise": false + }, + "ARRAY_CONTAINS_ANY": { + "getDisplaySymbol": null, + "getDisplayText": "Contains Any", + "getLabKeySqlOperator": "undefined", + "getLongDisplayText": "Contains At Least One Of", + "getMultiValueFilter": null, + "getMultiValueMaxOccurs": "undefined", + "getMultiValueMinOccurs": "undefined", + "getMultiValueSeparator": ",", + "getOpposite": null, + "getSingleValueFilter": "undefined", + "getURLParameterValue": "undefined", + "getURLSuffix": "arraycontainsany", + "isDataValueRequired": true, + "isMultiValued": true, + "isTableWise": false + }, + "ARRAY_CONTAINS_EXACT": { + "getDisplaySymbol": null, + "getDisplayText": "Contains Exactly", + "getLabKeySqlOperator": "undefined", + "getLongDisplayText": "Contains Exactly the Selected Values", + "getMultiValueFilter": null, + "getMultiValueMaxOccurs": "undefined", + "getMultiValueMinOccurs": "undefined", + "getMultiValueSeparator": ",", + "getOpposite": null, + "getSingleValueFilter": "undefined", + "getURLParameterValue": "undefined", + "getURLSuffix": "arraymatches", + "isDataValueRequired": true, + "isMultiValued": true, + "isTableWise": false + }, + "ARRAY_CONTAINS_NONE": { + "getDisplaySymbol": null, + "getDisplayText": "Contains None", + "getLabKeySqlOperator": "undefined", + "getLongDisplayText": "Contains None Of", + "getMultiValueFilter": null, + "getMultiValueMaxOccurs": "undefined", + "getMultiValueMinOccurs": "undefined", + "getMultiValueSeparator": ",", + "getOpposite": null, + "getSingleValueFilter": "undefined", + "getURLParameterValue": "undefined", + "getURLSuffix": "arraycontainsnone", + "isDataValueRequired": true, + "isMultiValued": true, + "isTableWise": false + }, + "ARRAY_CONTAINS_NOT_EXACT": { + "getDisplaySymbol": null, + "getDisplayText": "Does Not Contain Exactly", + "getLabKeySqlOperator": "undefined", + "getLongDisplayText": "Does Not Contains Exactly the Selected Values", + "getMultiValueFilter": null, + "getMultiValueMaxOccurs": "undefined", + "getMultiValueMinOccurs": "undefined", + "getMultiValueSeparator": ",", + "getOpposite": null, + "getSingleValueFilter": "undefined", + "getURLParameterValue": "undefined", + "getURLSuffix": "arraynotmatches", + "isDataValueRequired": true, + "isMultiValued": true, + "isTableWise": false + }, + "ARRAY_ISEMPTY": { + "getDisplaySymbol": null, + "getDisplayText": "Is Empty", + "getLabKeySqlOperator": "undefined", + "getLongDisplayText": "Is Empty", + "getMultiValueFilter": "undefined", + "getMultiValueMaxOccurs": "undefined", + "getMultiValueMinOccurs": "undefined", + "getMultiValueSeparator": null, + "getOpposite": null, + "getSingleValueFilter": "arrayisempty", + "getURLParameterValue": "", + "getURLSuffix": "arrayisempty", + "isDataValueRequired": false, + "isMultiValued": false, + "isTableWise": false + }, + "ARRAY_ISNOTEMPTY": { + "getDisplaySymbol": null, + "getDisplayText": "Is Not Empty", + "getLabKeySqlOperator": "undefined", + "getLongDisplayText": "Is Not Empty", + "getMultiValueFilter": "undefined", + "getMultiValueMaxOccurs": "undefined", + "getMultiValueMinOccurs": "undefined", + "getMultiValueSeparator": null, + "getOpposite": null, + "getSingleValueFilter": "arrayisnotempty", + "getURLParameterValue": "", + "getURLSuffix": "arrayisnotempty", + "isDataValueRequired": false, + "isMultiValued": false, + "isTableWise": false + }, "BETWEEN": { "getDisplaySymbol": null, "getDisplayText": "Between",