From 77e6093bd1de7be15b0e0e8eb8d436ccdeb0a4e7 Mon Sep 17 00:00:00 2001 From: Taha Yassine Kraiem Date: Thu, 27 Oct 2022 15:13:51 +0200 Subject: [PATCH] feat(chalice): fixed assist search feat(assist): fixed search --- api/chalicelib/core/assist.py | 5 +-- api/schemas.py | 4 ++- utilities/utils/helper.js | 65 +++++++++++++++++++++++++++-------- 3 files changed, 56 insertions(+), 18 deletions(-) diff --git a/api/chalicelib/core/assist.py b/api/chalicelib/core/assist.py index d87cb90bd..b1bae90b3 100644 --- a/api/chalicelib/core/assist.py +++ b/api/chalicelib/core/assist.py @@ -39,9 +39,10 @@ def get_live_sessions_ws(project_id, body: schemas.LiveSessionsSearchPayloadSche } for f in body.filters: if f.type == schemas.LiveFilterType.metadata: - data["filter"][f.source] = f.value + data["filter"][f.source] = {"values": f.value, "operator": f.operator} + else: - data["filter"][f.type.value] = f.value + data["filter"][f.type.value] = {"values": f.value, "operator": f.operator} return __get_live_sessions_ws(project_id=project_id, data=data) diff --git a/api/schemas.py b/api/schemas.py index bacceea78..6207c8ff3 100644 --- a/api/schemas.py +++ b/api/schemas.py @@ -1025,13 +1025,15 @@ class LiveFilterType(str, Enum): user_UUID = "USERUUID" tracker_version = "TRACKERVERSION" user_browser_version = "USERBROWSERVERSION" - user_device_type = "USERDEVICETYPE", + user_device_type = "USERDEVICETYPE" class LiveSessionSearchFilterSchema(BaseModel): value: Union[List[str], str] = Field(...) type: LiveFilterType = Field(...) source: Optional[str] = Field(None) + operator: Literal[SearchEventOperator._is.value, + SearchEventOperator._contains.value] = Field(SearchEventOperator._contains.value) @root_validator def validator(cls, values): diff --git a/utilities/utils/helper.js b/utilities/utils/helper.js index b9c20a6f3..22fcd0fd5 100644 --- a/utilities/utils/helper.js +++ b/utilities/utils/helper.js @@ -40,19 +40,20 @@ const extractSessionIdFromRequest = function (req) { } const isValidSession = function (sessionInfo, filters) { let foundAll = true; - for (const [key, values] of Object.entries(filters)) { + for (const [key, body] of Object.entries(filters)) { let found = false; - if (values !== undefined && values !== null) { + if (body.values !== undefined && body.values !== null) { for (const [skey, svalue] of Object.entries(sessionInfo)) { if (svalue !== undefined && svalue !== null) { if (typeof (svalue) === "object") { - if (isValidSession(svalue, {[key]: values})) { + if (isValidSession(svalue, {[key]: body})) { found = true; break; } } else if (skey.toLowerCase() === key.toLowerCase()) { - for (let v of values) { - if (String(svalue).toLowerCase().indexOf(v.toLowerCase()) >= 0) { + for (let v of body["values"]) { + if (body.operator === "is" && String(svalue).toLowerCase() === v.toLowerCase() + || body.operator !== "is" && String(svalue).toLowerCase().indexOf(v.toLowerCase()) >= 0) { found = true; break; } @@ -97,21 +98,37 @@ const objectToObjectOfArrays = function (obj) { for (let k of Object.keys(obj)) { if (obj[k] !== undefined && obj[k] !== null) { _obj[k] = obj[k]; - if (!Array.isArray(_obj[k])) { + if (!Array.isArray(_obj[k].values)) { _obj[k] = [_obj[k]]; } - for (let i = 0; i < _obj[k].length; i++) { - _obj[k][i] = String(_obj[k][i]); + for (let i = 0; i < _obj[k].values.length; i++) { + _obj[k].values[i] = String(_obj[k].values[i]); } } } } return _obj; } +const transformFilters = function (filter) { + for (let key of Object.keys(filter)) { + //To support old v1.7.0 payload + if (Array.isArray(filter[key]) || filter[key] === undefined || filter[key] === null) { + debug && console.log(`[WS]old format for key=${key}`); + filter[key] = {"values": filter[key]}; + } + if (filter[key].operator) { + debug && console.log(`[WS]where operator=${filter[key].operator}`); + } else { + debug && console.log(`[WS]where operator=DEFAULT-contains`); + filter[key].operator = "contains"; + } + } + return filter; +} const extractPayloadFromRequest = function (req) { let filters = { - "query": {}, - "filter": {}, + "query": {}, // for autocomplete + "filter": {}, // for sessions search "sort": { "key": req.body.sort && req.body.sort.key ? req.body.sort.key : undefined, "order": req.body.sort && req.body.sort.order === "DESC" @@ -135,6 +152,7 @@ const extractPayloadFromRequest = function (req) { } filters.filter = objectToObjectOfArrays(filters.filter); filters.filter = {...filters.filter, ...(req.body.filter || {})}; + filters.filter = transformFilters(filters.filter); debug && console.log("payload/filters:" + JSON.stringify(filters)) return filters; } @@ -149,20 +167,36 @@ const getValue = function (obj, key) { } if (val !== undefined) { - return val; + return isNaN(val) ? val : Number(val); } } } return undefined; } const sortPaginate = function (list, filters) { + if (typeof (list) === "object" && !Array.isArray(list)) { + for (const [key, value] of Object.entries(list)) { + list[key] = sortPaginate(value, filters); + } + return list + } + const total = list.length; list.sort((a, b) => { - const vA = getValue(a, filters.sort.key || "timestamp"); - const vB = getValue(b, filters.sort.key || "timestamp"); - return vA > vB ? 1 : vA < vB ? -1 : 0; + const tA = getValue(a, "timestamp"); + const tB = getValue(b, "timestamp"); + return tA < tB ? 1 : tA > tB ? -1 : 0; }); - + if (filters.sort.order) { + list.reverse(); + } + if ((filters.sort.key || "timestamp") !== "timestamp") { + list.sort((a, b) => { + const vA = getValue(a, filters.sort.key); + const vB = getValue(b, filters.sort.key); + return vA > vB ? 1 : vA < vB ? -1 : 0; + }); + } if (filters.sort.order) { list.reverse(); } @@ -185,6 +219,7 @@ const uniqueAutocomplete = function (list) { return _list; } module.exports = { + transformFilters, extractPeerId, request_logger, getValidAttributes,