Skip to content

Commit

Permalink
fix: parse filter object
Browse files Browse the repository at this point in the history
  • Loading branch information
CaduGomes committed Nov 17, 2023
1 parent 5d55db8 commit f95abb3
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 16 deletions.
131 changes: 131 additions & 0 deletions __test__/data/filterUtils/parseFilterObject.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { expect } from 'chai';
import { parseFilterObject } from '../../../src/imports/data/filterUtils';

describe('FilterUtils > parseFilterObject', () => {
it('should successfully parse filter object with conditions object', () => {
const metaObject = {
_id: 'example',
fields: {
status: {
maxSelected: 1,
minSelected: 1,
name: 'status',
type: 'picklist',
isSortable: true,
label: {
en: 'Status',
pt_BR: 'Situação',
},
optionsSorter: 'asc',
options: {
draft: {
en: 'Draft',
pt_BR: 'Rascunho',
},
active: {
pt_BR: 'Ativo',
en: 'Active',
},
inactive: {
en: 'Inactive',
pt_BR: 'Inativo',
},
},
defaultValue: 'draft',
renderAs: 'without_scroll',
},
},
};

const condition = {
match: 'and',
filters: [
{
match: 'and',
conditions: {
'status:in': {
term: 'status',
operator: 'in',
value: ['Ativo'],
editable: true,
disabled: false,
sort: 0,
},
},
},
],
};

const req = {
user: {
_id: 'user123',
},
};

const result = parseFilterObject(condition, metaObject, req);

expect(result).to.be.deep.equal({ status: { $in: ['Ativo'] } });
});

it('should successfully parse filter object with conditions array', () => {
const metaObject = {
_id: 'example',
fields: {
status: {
maxSelected: 1,
minSelected: 1,
name: 'status',
type: 'picklist',
isSortable: true,
label: {
en: 'Status',
pt_BR: 'Situação',
},
optionsSorter: 'asc',
options: {
draft: {
en: 'Draft',
pt_BR: 'Rascunho',
},
active: {
pt_BR: 'Ativo',
en: 'Active',
},
inactive: {
en: 'Inactive',
pt_BR: 'Inativo',
},
},
defaultValue: 'draft',
renderAs: 'without_scroll',
},
},
};

const condition = {
match: 'and',
filters: [
{
match: 'and',
conditions: [
{
term: 'status',
operator: 'equals',
value: 'Em Andamento',
},
],
},
],
};

const req = {
user: {
_id: 'user123',
},
};

const result = parseFilterObject(condition, metaObject, req);

expect(result).to.be.deep.equal({ status: 'Em Andamento' });
});
});
1 change: 1 addition & 0 deletions __test__/globalSetup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export default async function globalSetup() {

console.info(`\n✅ Started app`);
} catch (error) {
console.error(`\n❌ Failed to start app, verify port 3000`);
console.error(error);
}
}
Expand Down
47 changes: 32 additions & 15 deletions src/imports/data/filterUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,23 +248,31 @@ export function parseFilterCondition(condition, metaObject, req, invert) {
const getValue = function (value) {
if (operator === 'between') {
const result = {};
if (isObject(value)) {
if (isObject(value.greater_or_equals) && isString(value.greater_or_equals.$date)) {
result.greater_or_equals = processValueByType(value.greater_or_equals);
if (isObject(value) && value != null) {
if (value.greater_or_equals != null) {
if (value.greater_or_equals.$date != null && isString(value.greater_or_equals.$date)) {
result.greater_or_equals = processValueByType(value.greater_or_equals);
} else {
result.greater_or_equals = value.greater_or_equals;
}
}

if (isObject(value.less_or_equals) && isString(value.less_or_equals.$date)) {
value.less_or_equals = processValueByType(value.less_or_equals);
if (value.less_or_equals != null) {
if (value.less_or_equals.$date != null && isString(value.less_or_equals.$date)) {
value.less_or_equals = processValueByType(value.less_or_equals);
} else {
result.less_or_equals = value.less_or_equals;
}
}
}
return result;
} else {
return processValueByType(value);
}
};

const conditionValue = getValue(conditionValueResult.data);
const queryCondition = {};

switch (operator) {
case 'equals':
queryCondition[condition.term] = conditionValue;
Expand Down Expand Up @@ -308,10 +316,10 @@ export function parseFilterCondition(condition, metaObject, req, invert) {
break;
case 'between':
queryCondition[condition.term] = {};
if (conditionValue.greater_or_equals != null) {
if (conditionValue != null && conditionValue.greater_or_equals != null) {
queryCondition[condition.term].$gte = conditionValue.greater_or_equals;
}
if (conditionValue.less_or_equals != null) {
if (conditionValue != null && conditionValue.less_or_equals != null) {
queryCondition[condition.term].$lte = conditionValue.less_or_equals;
}
break;
Expand Down Expand Up @@ -349,7 +357,7 @@ export function parseFilterObject(filter, metaObject, data) {
} else if (isObject(filter.conditions) && Object.keys(filter.conditions).length > 0) {
const objectConditions = Object.entries(filter.conditions)
.filter(([, { disabled = false }]) => disabled !== true)
.map(([key, condition]) => parseFilterCondition({ ...condition, term: key }, metaObject, data));
.map(([, condition]) => parseFilterCondition(condition, metaObject, data));

if (objectConditions.some(({ success }) => success === false)) {
return objectConditions.find(({ success }) => success === false);
Expand Down Expand Up @@ -512,19 +520,28 @@ export function filterConditionToFn(condition, metaObject, req) {
};

const operator = type === ('money.currency' && ['not_equals', 'exists'].includes(condition.operator) === false) ? 'equals' : condition.operator;

const getValue = function (value) {
if (operator === 'between') {
const result = {};
if (isObject(value)) {
if (isObject(value.greater_or_equals) && isString(value.greater_or_equals.$date)) {
result.greater_or_equals = processValueByType(value.greater_or_equals);
if (isObject(value) && value != null) {
if (value.greater_or_equals != null) {
if (value.greater_or_equals.$date != null && isString(value.greater_or_equals.$date)) {
result.greater_or_equals = processValueByType(value.greater_or_equals);
} else {
result.greater_or_equals = value.greater_or_equals;
}
}

if (isObject(value.less_or_equals) && isString(value.less_or_equals.$date)) {
value.less_or_equals = processValueByType(value.less_or_equals);
if (value.less_or_equals != null) {
if (value.less_or_equals.$date != null && isString(value.less_or_equals.$date)) {
value.less_or_equals = processValueByType(value.less_or_equals);
} else {
result.less_or_equals = value.less_or_equals;
}
}
}

return result;
} else {
return processValueByType(value);
}
Expand Down
2 changes: 1 addition & 1 deletion src/server/routes/rest/data/dataApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const dataApi: FastifyPluginCallback = (fastify, _, done) => {
Querystring: { displayName: string; displayType: string; fields: string; filter: string; sort: string; limit: string; start: string; withDetailFields: string };
}>('/rest/data/:document/find', async (req, reply) => {
if (req.query.filter != null && isString(req.query.filter)) {
req.query.filter = JSON.parse(req.query.filter);
req.query.filter = JSON.parse(req.query.filter.replace(/\+/g, ' '));
}

const result = await find({
Expand Down

0 comments on commit f95abb3

Please sign in to comment.