mirror of
https://github.com/bigcapitalhq/bigcapital.git
synced 2026-02-16 04:40:32 +00:00
feat: Sorting by dynamic query.
This commit is contained in:
44
server/src/lib/DynamicFilter/DynamicFilter.js
Normal file
44
server/src/lib/DynamicFilter/DynamicFilter.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import { uniqBy } from 'lodash';
|
||||
import {
|
||||
buildFilterRolesJoins,
|
||||
} from '@/lib/ViewRolesBuilder';
|
||||
|
||||
export default class DynamicFilter {
|
||||
/**
|
||||
* Constructor.
|
||||
* @param {String} tableName -
|
||||
*/
|
||||
constructor(tableName) {
|
||||
this.tableName = tableName;
|
||||
this.filters = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set filter.
|
||||
* @param {*} filterRole -
|
||||
*/
|
||||
setFilter(filterRole) {
|
||||
filterRole.setTableName(this.tableName);
|
||||
this.filters.push(filterRole);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds queries of filter roles.
|
||||
*/
|
||||
buildQuery() {
|
||||
const buildersCallbacks = [];
|
||||
const tableColumns = [];
|
||||
|
||||
this.filters.forEach((filter) => {
|
||||
const { filterRoles } = filter;
|
||||
buildersCallbacks.push(filter.buildQuery());
|
||||
tableColumns.push(...(Array.isArray(filterRoles)) ? filterRoles : [filterRoles]);
|
||||
});
|
||||
return (builder) => {
|
||||
buildersCallbacks.forEach((builderCallback) => {
|
||||
builderCallback(builder);
|
||||
});
|
||||
buildFilterRolesJoins(this.tableName, uniqBy(tableColumns, 'columnKey'))(builder);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,22 +1,25 @@
|
||||
import { difference } from 'lodash';
|
||||
import DynamicFilterRoleAbstructor from '@/lib/DynamicFilter/DynamicFilterRoleAbstructor';
|
||||
import {
|
||||
buildFilterQuery,
|
||||
} from '../ViewRolesBuilder';
|
||||
} from '@/lib/ViewRolesBuilder';
|
||||
|
||||
export default class FilterRoles {
|
||||
export default class FilterRoles extends DynamicFilterRoleAbstructor {
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {Array} filterRoles -
|
||||
* @param {Array} resourceFields -
|
||||
*/
|
||||
constructor(tableName, filterRoles, resourceFields) {
|
||||
constructor(filterRoles, resourceFields) {
|
||||
super();
|
||||
|
||||
this.filterRoles = filterRoles.map((role, index) => ({
|
||||
...role,
|
||||
index: index + 1,
|
||||
columnKey: role.field_key,
|
||||
comparator: role.comparator === 'AND' ? '&&' : '||',
|
||||
}));
|
||||
this.resourceFields = resourceFields;
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
validateFilterRoles() {
|
||||
@@ -36,10 +39,12 @@ export default class FilterRoles {
|
||||
return expression.trim();
|
||||
}
|
||||
|
||||
// @public
|
||||
/**
|
||||
* Builds database query of view roles.
|
||||
*/
|
||||
buildQuery() {
|
||||
const logicExpression = this.buildLogicExpression();
|
||||
return (builder) => {
|
||||
const logicExpression = this.buildLogicExpression();
|
||||
buildFilterQuery(this.tableName, this.filterRoles, logicExpression)(builder);
|
||||
};
|
||||
}
|
||||
18
server/src/lib/DynamicFilter/DynamicFilterRoleAbstructor.js
Normal file
18
server/src/lib/DynamicFilter/DynamicFilterRoleAbstructor.js
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
|
||||
export default class DynamicFilterAbstructor {
|
||||
constructor() {
|
||||
this.filterRoles = [];
|
||||
this.tableName = '';
|
||||
}
|
||||
|
||||
setTableName(tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
buildLogicExpression() {}
|
||||
|
||||
validateFilterRoles() {}
|
||||
|
||||
buildQuery() {}
|
||||
}
|
||||
31
server/src/lib/DynamicFilter/DynamicFilterSortBy.js
Normal file
31
server/src/lib/DynamicFilter/DynamicFilterSortBy.js
Normal file
@@ -0,0 +1,31 @@
|
||||
import DynamicFilterRoleAbstructor from '@/lib/DynamicFilter/DynamicFilterRoleAbstructor';
|
||||
import {
|
||||
getRoleFieldColumn,
|
||||
} from '@/lib/ViewRolesBuilder';
|
||||
|
||||
export default class DynamicFilterSortBy extends DynamicFilterRoleAbstructor {
|
||||
|
||||
constructor(sortByFieldKey, sortDirection) {
|
||||
super();
|
||||
|
||||
this.filterRoles = {
|
||||
columnKey: sortByFieldKey,
|
||||
value: sortDirection,
|
||||
comparator: 'sort_by',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds database query of sort by column on the given direction.
|
||||
*/
|
||||
buildQuery() {
|
||||
const { columnKey = null, value = null } = this.filterRoles;
|
||||
|
||||
return (builder) => {
|
||||
const fieldRelation = getRoleFieldColumn(this.tableName, columnKey);
|
||||
if (columnKey) {
|
||||
builder.orderBy(`${this.tableName}.${fieldRelation.column}`, value.toLowerCase());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
46
server/src/lib/DynamicFilter/DynamicFilterViews.js
Normal file
46
server/src/lib/DynamicFilter/DynamicFilterViews.js
Normal file
@@ -0,0 +1,46 @@
|
||||
import DynamicFilterRoleAbstructor from '@/lib/DynamicFilter/DynamicFilterRoleAbstructor';
|
||||
import {
|
||||
validateViewRoles,
|
||||
buildFilterQuery,
|
||||
} from '@/lib/ViewRolesBuilder';
|
||||
|
||||
export default class DynamicFilterViews extends DynamicFilterRoleAbstructor {
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {*} filterRoles -
|
||||
* @param {*} logicExpression -
|
||||
*/
|
||||
constructor(filterRoles, logicExpression) {
|
||||
super();
|
||||
|
||||
this.filterRoles = filterRoles;
|
||||
this.logicExpression = logicExpression
|
||||
.replace('AND', '&&')
|
||||
.replace('OR', '||');
|
||||
|
||||
this.tableName = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve logic expression.
|
||||
*/
|
||||
buildLogicExpression() {
|
||||
return this.logicExpression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates filter roles.
|
||||
*/
|
||||
validateFilterRoles() {
|
||||
return validateViewRoles(this.filterRoles, this.logicExpression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds database query of view roles.
|
||||
*/
|
||||
buildQuery() {
|
||||
return (builder) => {
|
||||
buildFilterQuery(this.tableName, this.filterRoles, this.logicExpression)(builder);
|
||||
};
|
||||
}
|
||||
}
|
||||
13
server/src/lib/DynamicFilter/index.js
Normal file
13
server/src/lib/DynamicFilter/index.js
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
|
||||
import DynamicFilter from './DynamicFilter';
|
||||
import DynamicFilterSortBy from './DynamicFilterSortBy';
|
||||
import DynamicFilterViews from './DynamicFilterViews';
|
||||
import DynamicFilterFilterRoles from './DynamicFilterFilterRoles';
|
||||
|
||||
export {
|
||||
DynamicFilter,
|
||||
DynamicFilterSortBy,
|
||||
DynamicFilterViews,
|
||||
DynamicFilterFilterRoles,
|
||||
};
|
||||
44
server/src/lib/ViewRolesBuilder/FilterRolesDynamicFilter.js
Normal file
44
server/src/lib/ViewRolesBuilder/FilterRolesDynamicFilter.js
Normal file
@@ -0,0 +1,44 @@
|
||||
import DynamicFilterRoleAbstructor from '@/lib/DynamicFilter/DynamicFilterRoleAbstructor';
|
||||
import {
|
||||
validateViewRoles,
|
||||
buildFilterQuery,
|
||||
} from '@/lib/ViewRolesBuilder';
|
||||
|
||||
export default class ViewRolesDynamicFilter extends DynamicFilterRoleAbstructor {
|
||||
/**
|
||||
* Constructor method.
|
||||
* @param {*} filterRoles
|
||||
* @param {*} logicExpression
|
||||
*/
|
||||
constructor(filterRoles, logicExpression) {
|
||||
super();
|
||||
|
||||
this.filterRoles = filterRoles;
|
||||
this.logicExpression = logicExpression;
|
||||
|
||||
this.tableName = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve logic expression.
|
||||
*/
|
||||
buildLogicExpression() {
|
||||
return this.logicExpression;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates filter roles.
|
||||
*/
|
||||
validateFilterRoles() {
|
||||
return validateViewRoles(this.filterRoles, this.logicExpression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds database query of view roles.
|
||||
*/
|
||||
buildQuery() {
|
||||
return (builder) => {
|
||||
buildFilterQuery(this.tableName, this.filterRoles, this.logicExpression)(builder);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -29,9 +29,8 @@ export function getRoleFieldColumn(tableName, columnKey) {
|
||||
*/
|
||||
export function buildRoleQuery(tableName, role) {
|
||||
const fieldRelation = getRoleFieldColumn(tableName, role.columnKey);
|
||||
const comparatorColumn = fieldRelation.relation || `${tableName}.${fieldRelation.column}`;
|
||||
const comparatorColumn = fieldRelation.relationColumn || `${tableName}.${fieldRelation.column}`;
|
||||
|
||||
console.log(comparatorColumn, role.value);
|
||||
switch (role.comparator) {
|
||||
case 'equals':
|
||||
default:
|
||||
@@ -44,6 +43,7 @@ export function buildRoleQuery(tableName, role) {
|
||||
builder.whereNot(comparatorColumn, role.value);
|
||||
};
|
||||
case 'contain':
|
||||
case 'contains':
|
||||
return (builder) => {
|
||||
builder.where(comparatorColumn, 'LIKE', `%${role.value}%`);
|
||||
};
|
||||
@@ -78,6 +78,17 @@ export function buildFilterRolesJoins(tableName, roles) {
|
||||
};
|
||||
}
|
||||
|
||||
export function buildSortColumnJoin(tableName, sortColumnKey) {
|
||||
return (builder) => {
|
||||
const fieldColumn = getRoleFieldColumn(tableName, sortColumnKey);
|
||||
|
||||
if (fieldColumn.relation) {
|
||||
const joinTable = getTableFromRelationColumn(fieldColumn.relation);
|
||||
builder.join(joinTable, `${tableName}.${fieldColumn.column}`, '=', fieldColumn.relation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds database query from stored view roles.
|
||||
*
|
||||
@@ -110,7 +121,6 @@ export function buildFilterRolesQuery(tableName, roles, logicExpression = '') {
|
||||
*/
|
||||
export const buildFilterQuery = (tableName, roles, logicExpression) => {
|
||||
return (builder) => {
|
||||
buildFilterRolesJoins(tableName, roles)(builder);
|
||||
buildFilterRolesQuery(tableName, roles, logicExpression)(builder);
|
||||
};
|
||||
};
|
||||
@@ -148,4 +158,28 @@ export function mapViewRolesToConditionals(viewRoles) {
|
||||
slug: viewRole.field.slug,
|
||||
index: viewRole.index,
|
||||
}));
|
||||
}
|
||||
|
||||
|
||||
export function mapFilterRolesToDynamicFilter(roles) {
|
||||
return roles.map((role) => ({
|
||||
...role,
|
||||
columnKey: role.fieldKey,
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds sort column query.
|
||||
* @param {String} tableName -
|
||||
* @param {String} columnKey -
|
||||
* @param {String} sortDirection -
|
||||
*/
|
||||
export function buildSortColumnQuery(tableName, columnKey, sortDirection) {
|
||||
const fieldRelation = getRoleFieldColumn(tableName, columnKey);
|
||||
const sortColumn = fieldRelation.relation || `${tableName}.${fieldRelation.column}`;
|
||||
|
||||
return (builder) => {
|
||||
builder.orderBy(sortColumn, sortDirection);
|
||||
buildSortColumnJoin(tableName, columnKey)(builder);
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user