#345 - Filter items by tag
This commit is contained in:
parent
96d755cd21
commit
542d9dca86
|
@ -27,8 +27,7 @@ export default class CrudModel extends ModelProxy {
|
|||
where: mergeWhere(this.link, this.where),
|
||||
include: this.include,
|
||||
order: this.order,
|
||||
limit: this.limit,
|
||||
userData: this.userData
|
||||
limit: this.limit
|
||||
};
|
||||
|
||||
let filter = this.filter;
|
||||
|
@ -153,7 +152,7 @@ ngModule.component('vnCrudModel', {
|
|||
order: '@?',
|
||||
limit: '<?',
|
||||
filter: '<?',
|
||||
userData: '<?',
|
||||
userParams: '<?',
|
||||
primaryKey: '@?',
|
||||
autoLoad: '<?'
|
||||
}
|
||||
|
@ -232,8 +231,6 @@ function mergeFilters(src, dst) {
|
|||
res.order = src.order;
|
||||
if (src.limit)
|
||||
res.limit = src.limit;
|
||||
if (src.userData)
|
||||
res.userData = src.userData;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="/item/api/Items/filter"
|
||||
filter="::$ctrl.filter"
|
||||
limit="8"
|
||||
order="name ASC"
|
||||
data="items"
|
||||
auto-load="false">
|
||||
</vn-crud-model>
|
||||
|
|
|
@ -8,22 +8,6 @@ class Controller {
|
|||
this.$state = $state;
|
||||
this.$ = $scope;
|
||||
this.itemSelected = null;
|
||||
|
||||
this.filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'itemType',
|
||||
scope: {
|
||||
fields: ['name', 'workerFk'],
|
||||
include: {
|
||||
relation: 'worker',
|
||||
fields: ['firstName', 'name']
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
order: 'name ASC'
|
||||
};
|
||||
}
|
||||
|
||||
exprBuilder(param, value) {
|
||||
|
@ -31,10 +15,10 @@ class Controller {
|
|||
case 'search':
|
||||
return /^\d+$/.test(value)
|
||||
? {id: value}
|
||||
: {name: {regexp: value}};
|
||||
: {name: {like: `%${value}%`}};
|
||||
case 'name':
|
||||
case 'description':
|
||||
return {[param]: {regexp: value}};
|
||||
return {[param]: {like: `%${value}%`}};
|
||||
case 'id':
|
||||
case 'typeFk':
|
||||
return {[param]: value};
|
||||
|
|
|
@ -21,10 +21,10 @@
|
|||
value="{{::$ctrl.item.size}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Type"
|
||||
value="{{::$ctrl.item.itemType.name}}">
|
||||
value="{{::$ctrl.item.type}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Buyer"
|
||||
value="{{::$ctrl.item.itemType.worker.firstName}} {{::$ctrl.item.itemType.worker.name}}">
|
||||
value="{{::$ctrl.item.firstName}} {{::$ctrl.item.worker}}">
|
||||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-horizontal class="buttons">
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
|
||||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('filter', {
|
||||
description: 'Find all instances of the model matched by filter from the data source.',
|
||||
|
@ -6,7 +9,7 @@ module.exports = Self => {
|
|||
{
|
||||
arg: 'filter',
|
||||
type: 'Object',
|
||||
description: 'Filter defining fields, where, include, order, offset, and limit - must be a JSON-encoded string ({"something":"value"})',
|
||||
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'tags',
|
||||
|
@ -26,7 +29,29 @@ module.exports = Self => {
|
|||
});
|
||||
|
||||
Self.filter = async(filter, tags) => {
|
||||
console.log(tags);
|
||||
return await Self.find(filter);
|
||||
let stmt = new ParameterizedSQL(
|
||||
`SELECT i.id, i.image, i.name, i.description, i.size,
|
||||
t.name type, w.firstName, w.name worker
|
||||
FROM item i
|
||||
JOIN itemType t ON t.id = i.typeFk
|
||||
JOIN worker w ON w.id = t.workerFk`
|
||||
);
|
||||
|
||||
if (tags) {
|
||||
let i = 1;
|
||||
for (let tag of tags) {
|
||||
if (tag.value == null) continue;
|
||||
let tAlias = `it${i++}`;
|
||||
stmt.merge({
|
||||
sql: `JOIN itemTag ${tAlias} ON ${tAlias}.itemFk = i.id
|
||||
AND ${tAlias}.tagFk = ?
|
||||
AND ${tAlias}.value = ?`,
|
||||
params: [tag.tagFk, tag.value]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
stmt.merge(Self.buildSuffix(filter, 'i'));
|
||||
return Self.rawStmt(stmt);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
module.exports = function(Self) {
|
||||
Self.rawSql = function(query, params, cb) {
|
||||
var connector = this.dataSource.connector;
|
||||
return new Promise(function(resolve, reject) {
|
||||
connector.execute(query, params, function(error, response) {
|
||||
if (cb)
|
||||
cb(error, response);
|
||||
if (error)
|
||||
reject(error);
|
||||
else
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
|
@ -1,3 +1,6 @@
|
|||
|
||||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||
|
||||
module.exports = function(Self) {
|
||||
Self.setup = function() {
|
||||
Self.super_.setup.call(this);
|
||||
|
@ -162,7 +165,89 @@ module.exports = function(Self) {
|
|||
};
|
||||
};
|
||||
|
||||
require('../methods/vn-model/rawSql')(Self);
|
||||
Self.rawSql = function(query, params, cb) {
|
||||
var connector = this.dataSource.connector;
|
||||
return new Promise(function(resolve, reject) {
|
||||
connector.execute(query, params, function(error, response) {
|
||||
if (cb)
|
||||
cb(error, response);
|
||||
if (error)
|
||||
reject(error);
|
||||
else
|
||||
resolve(response);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
Self.rawStmt = function(stmt) {
|
||||
return this.rawSql(stmt.sql, stmt.params);
|
||||
};
|
||||
|
||||
Self.escapeName = function(name) {
|
||||
return this.dataSource.connector.escapeName(name);
|
||||
};
|
||||
|
||||
Self.buildWhere = function(filter, tableAlias) {
|
||||
let connector = this.dataSource.connector;
|
||||
let wrappedConnector = Object.create(connector);
|
||||
wrappedConnector.columnEscaped = function(model, property) {
|
||||
let sql = tableAlias
|
||||
? connector.escapeName(tableAlias) + '.'
|
||||
: '';
|
||||
return sql + connector.columnEscaped(model, property);
|
||||
};
|
||||
|
||||
return wrappedConnector.buildWhere(this.modelName, filter.where);
|
||||
};
|
||||
|
||||
Self.buildLimit = function(filter) {
|
||||
let sql = new ParameterizedSQL('');
|
||||
this.dataSource.connector.applyPagination(this.modelName, sql, filter);
|
||||
return sql;
|
||||
};
|
||||
|
||||
Self.buildOrderBy = function(filter) {
|
||||
let order = filter.order;
|
||||
|
||||
if (!order)
|
||||
return '';
|
||||
if (typeof order === 'string')
|
||||
order = [order];
|
||||
|
||||
let clauses = [];
|
||||
|
||||
for (let clause of order) {
|
||||
let sqlOrder = '';
|
||||
let t = clause.split(/[\s,]+/);
|
||||
let names = t[0].split('.');
|
||||
|
||||
if (names.length > 1)
|
||||
sqlOrder += this.escapeName(names[0]) + '.';
|
||||
sqlOrder += this.escapeName(names[names.length - 1]);
|
||||
|
||||
if (t.length > 1)
|
||||
sqlOrder += ' ' + (t[1].toUpperCase() == 'ASC' ? 'ASC' : 'DESC');
|
||||
|
||||
clauses.push(sqlOrder);
|
||||
}
|
||||
|
||||
return `ORDER BY ${clauses.join(', ')}`;
|
||||
};
|
||||
|
||||
Self.buildPagination = function(filter) {
|
||||
return ParameterizedSQL.join([
|
||||
this.buildOrderBy(filter),
|
||||
this.buildLimit(filter)
|
||||
]);
|
||||
};
|
||||
|
||||
Self.buildSuffix = function(filter, tableAlias) {
|
||||
return ParameterizedSQL.join([
|
||||
this.buildWhere(filter, tableAlias),
|
||||
this.buildPagination(filter)
|
||||
]);
|
||||
};
|
||||
|
||||
require('../methods/vn-model/installMethod')(Self);
|
||||
require('../methods/vn-model/validateBinded')(Self);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue