catalog filters #598
This commit is contained in:
parent
8d1aa30287
commit
fa31010069
|
@ -4,8 +4,7 @@
|
||||||
type="button"
|
type="button"
|
||||||
class="mdl-textfield__input"
|
class="mdl-textfield__input"
|
||||||
ng-click="$ctrl.onMouseDown($event)"
|
ng-click="$ctrl.onMouseDown($event)"
|
||||||
ng-keydown="$ctrl.onKeyDown($event)">
|
ng-keydown="$ctrl.onKeyDown($event)"/>
|
||||||
</input>
|
|
||||||
<div class="icons">
|
<div class="icons">
|
||||||
<vn-icon
|
<vn-icon
|
||||||
ng-show="!$ctrl.disabled"
|
ng-show="!$ctrl.disabled"
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
<div>
|
<vn-one>
|
||||||
<span ng-class="{'mdl-chip--deletable': !$ctrl.disabled}" class="mdl-chip">
|
<span ng-class="{'mdl-chip--deletable': !$ctrl.disabled}" class="mdl-chip">
|
||||||
<span class="mdl-chip__text" ng-transclude></span>
|
<span class="mdl-chip__text ellipsize" ng-transclude></span>
|
||||||
<button ng-click="$ctrl.remove()" ng-show="!$ctrl.disabled" type="button" class="mdl-chip__action">
|
<button ng-click="$ctrl.remove()" ng-show="!$ctrl.disabled" type="button" class="mdl-chip__action">
|
||||||
<i class="material-icons">cancel</i>
|
<i class="material-icons">cancel</i>
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</vn-one>
|
|
@ -2,11 +2,6 @@ import ngModule from '../../module';
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
export default class Chip {
|
export default class Chip {
|
||||||
constructor($element, $scope, $transclude) {
|
|
||||||
$transclude($scope.$parent, clone => {
|
|
||||||
angular.element($element[0].querySelector('div')).append(clone);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove chip event
|
* Remove chip event
|
||||||
|
|
|
@ -1,11 +1,18 @@
|
||||||
@import 'colors';
|
@import 'colors';
|
||||||
|
|
||||||
vn-chip {
|
vn-chip {
|
||||||
|
margin: 0 0.5em 0.5em 0;
|
||||||
|
|
||||||
.mdl-chip {
|
.mdl-chip {
|
||||||
background-color: rgba($main-01, 0.9);
|
background-color: rgba($main-01, 0.9);
|
||||||
|
color: #FFF
|
||||||
}
|
}
|
||||||
|
|
||||||
.mdl-chip:active {
|
.mdl-chip:active {
|
||||||
background-color: $main-01
|
background-color: $main-01
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& > vn-one > span > span {
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="container"
|
<div class="container"
|
||||||
ng-class="{selected: $ctrl.hasFocus}">
|
ng-class="{selected: $ctrl.hasFocus}">
|
||||||
<div class="textField">
|
<div class="textField">
|
||||||
<div class="leftIcons"></div>
|
<div class="leftIcons" ng-transclude="leftIcons"></div>
|
||||||
<div class="infix">
|
<div class="infix">
|
||||||
<input
|
<input
|
||||||
class="mdl-textfield__input"
|
class="mdl-textfield__input"
|
||||||
|
@ -33,6 +33,6 @@
|
||||||
info_outline
|
info_outline
|
||||||
</i>
|
</i>
|
||||||
</div>
|
</div>
|
||||||
<div class="rightIcons"></div>
|
<div class="rightIcons" ng-transclude="rightIcons"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -3,7 +3,7 @@ import Input from '../../lib/input';
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
export default class Textfield extends Input {
|
export default class Textfield extends Input {
|
||||||
constructor($element, $scope, $attrs, vnTemplate, $transclude) {
|
constructor($element, $scope, $attrs, vnTemplate) {
|
||||||
super($element, $scope);
|
super($element, $scope);
|
||||||
vnTemplate.normalizeInputAttrs($attrs);
|
vnTemplate.normalizeInputAttrs($attrs);
|
||||||
this._value = null;
|
this._value = null;
|
||||||
|
@ -14,20 +14,12 @@ export default class Textfield extends Input {
|
||||||
this.hasFocus = false;
|
this.hasFocus = false;
|
||||||
this.hasMouseIn = false;
|
this.hasMouseIn = false;
|
||||||
|
|
||||||
if ($transclude) {
|
|
||||||
$transclude($scope.$parent, tClone => {
|
|
||||||
this.leftIcons = tClone[0];
|
|
||||||
}, null, 'leftIcons');
|
|
||||||
$transclude($scope.$parent, tClone => {
|
|
||||||
this.rightIcons = tClone[0];
|
|
||||||
}, null, 'rightIcons');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.input.addEventListener('keydown', () => {
|
this.input.addEventListener('keydown', () => {
|
||||||
if (!this.oldValue) {
|
if (!this.oldValue) {
|
||||||
this.saveOldValue();
|
this.saveOldValue();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.input.addEventListener('keyup', e => {
|
this.input.addEventListener('keyup', e => {
|
||||||
if (e.key == "Escape") {
|
if (e.key == "Escape") {
|
||||||
this.value = this.oldValue;
|
this.value = this.oldValue;
|
||||||
|
@ -37,6 +29,7 @@ export default class Textfield extends Input {
|
||||||
if (e.key == "Escape" || e.key == "Enter")
|
if (e.key == "Escape" || e.key == "Enter")
|
||||||
this.input.blur();
|
this.input.blur();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.input.addEventListener('blur', () => {
|
this.input.addEventListener('blur', () => {
|
||||||
if (this.onChange && !this.cancelled &&
|
if (this.onChange && !this.cancelled &&
|
||||||
(this.oldValue && this.oldValue != this.value))
|
(this.oldValue && this.oldValue != this.value))
|
||||||
|
@ -45,19 +38,11 @@ export default class Textfield extends Input {
|
||||||
this.cancelled = false;
|
this.cancelled = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
saveOldValue() {
|
saveOldValue() {
|
||||||
this.oldValue = this.value;
|
this.oldValue = this.value;
|
||||||
}
|
}
|
||||||
set leftIcons(value) {
|
|
||||||
for (let i = 0; i < value.children.length; i++) {
|
|
||||||
this.element.querySelector('.leftIcons').appendChild(value.children[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set rightIcons(value) {
|
|
||||||
for (let i = 0; i < value.children.length; i++) {
|
|
||||||
this.element.querySelector('.rightIcons').appendChild(value.children[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
set value(value) {
|
set value(value) {
|
||||||
this._value = (value === undefined || value === '') ? null : value;
|
this._value = (value === undefined || value === '') ? null : value;
|
||||||
this.input.value = this._value;
|
this.input.value = this._value;
|
||||||
|
@ -66,18 +51,23 @@ export default class Textfield extends Input {
|
||||||
if (this.hasValue) this.element.classList.add('not-empty');
|
if (this.hasValue) this.element.classList.add('not-empty');
|
||||||
else this.element.classList.remove('not-empty');
|
else this.element.classList.remove('not-empty');
|
||||||
}
|
}
|
||||||
|
|
||||||
get value() {
|
get value() {
|
||||||
return this._value;
|
return this._value;
|
||||||
}
|
}
|
||||||
|
|
||||||
set type(value) {
|
set type(value) {
|
||||||
this._type = value || 'text';
|
this._type = value || 'text';
|
||||||
}
|
}
|
||||||
|
|
||||||
get type() {
|
get type() {
|
||||||
return this._type;
|
return this._type;
|
||||||
}
|
}
|
||||||
|
|
||||||
set vnTabIndex(value) {
|
set vnTabIndex(value) {
|
||||||
this.input.tabindex = value;
|
this.input.tabindex = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
this.saveOldValue();
|
this.saveOldValue();
|
||||||
this.value = null;
|
this.value = null;
|
||||||
|
@ -85,7 +75,7 @@ export default class Textfield extends Input {
|
||||||
this.input.focus();
|
this.input.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Textfield.$inject = ['$element', '$scope', '$attrs', 'vnTemplate', '$transclude'];
|
Textfield.$inject = ['$element', '$scope', '$attrs', 'vnTemplate'];
|
||||||
|
|
||||||
ngModule.component('vnTextfield', {
|
ngModule.component('vnTextfield', {
|
||||||
template: require('./textfield.html'),
|
template: require('./textfield.html'),
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
.icon-volume:before { content: '\e801'; } /* '' */
|
.icon-volume:before { content: '\e801'; } /* '' */
|
||||||
.icon-barcode:before { content: '\e802'; } /* '' */
|
.icon-barcode:before { content: '\e802'; } /* '' */
|
||||||
.icon-bucket:before { content: '\e803'; } /* '' */
|
.icon-bucket:before { content: '\e803'; } /* '' */
|
||||||
.icon-accesory:before { content: '\e804'; } /* '' */
|
.icon-accessory:before { content: '\e804'; } /* '' */
|
||||||
.icon-dfiscales:before { content: '\e805'; } /* '' */
|
.icon-dfiscales:before { content: '\e805'; } /* '' */
|
||||||
.icon-doc:before { content: '\e806'; } /* '' */
|
.icon-doc:before { content: '\e806'; } /* '' */
|
||||||
.icon-eye:before { content: '\e807'; } /* '' */
|
.icon-eye:before { content: '\e807'; } /* '' */
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
.icon-entry:before { content: '\e829'; } /* '' */
|
.icon-entry:before { content: '\e829'; } /* '' */
|
||||||
.icon-traceability:before { content: '\e82a'; } /* '' */
|
.icon-traceability:before { content: '\e82a'; } /* '' */
|
||||||
.icon-transaction:before { content: '\e82b'; } /* '' */
|
.icon-transaction:before { content: '\e82b'; } /* '' */
|
||||||
.icon-verde:before { content: '\e82c'; } /* '' */
|
.icon-greenery:before { content: '\e82c'; } /* '' */
|
||||||
.icon-regentry:before { content: '\e82d'; } /* '' */
|
.icon-regentry:before { content: '\e82d'; } /* '' */
|
||||||
.icon-plant:before { content: '\e82e'; } /* '' */
|
.icon-plant:before { content: '\e82e'; } /* '' */
|
||||||
.icon-artificial:before { content: '\e82f'; } /* '' */
|
.icon-artificial:before { content: '\e82f'; } /* '' */
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"url": "/catalog?q",
|
"url": "/catalog?category&type",
|
||||||
"state": "order.card.catalog",
|
"state": "order.card.catalog",
|
||||||
"component": "vn-order-catalog",
|
"component": "vn-order-catalog",
|
||||||
"description": "Catalog",
|
"description": "Catalog",
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
<vn-crud-model
|
<vn-crud-model
|
||||||
vn-id="model"
|
vn-id="model"
|
||||||
url="/order/api/Orders/CatalogFilter"
|
url="/order/api/Orders/CatalogFilter"
|
||||||
filter="::$ctrl.filter"
|
filter="$ctrl.filter"
|
||||||
|
limit="50"
|
||||||
data="items" auto-load="false">
|
data="items" auto-load="false">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
|
|
||||||
|
@ -9,9 +10,19 @@
|
||||||
<vn-vertical vn-one>
|
<vn-vertical vn-one>
|
||||||
<vn-card>
|
<vn-card>
|
||||||
<vn-vertical>
|
<vn-vertical>
|
||||||
<vn-horizontal class="catalog-header" pad-medium>
|
<vn-horizontal class="catalog-header" pad-medium-h>
|
||||||
<vn-one>{{model.data.length}} <span translate>results</span></vn-one>
|
<vn-one>{{model.data.length}} <span translate>results</span></vn-one>
|
||||||
<vn-one>-</vn-one>
|
<vn-one>
|
||||||
|
<vn-autocomplete vn-none
|
||||||
|
data="$ctrl.orderList"
|
||||||
|
initial-data="$ctrl.orderBy"
|
||||||
|
field="$ctrl.orderBy"
|
||||||
|
on-change="$ctrl.setOrder(value)"
|
||||||
|
show-field="name"
|
||||||
|
value-field="order"
|
||||||
|
label="Order by">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-one>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal class="catalog-list" pad-small>
|
<vn-horizontal class="catalog-list" pad-small>
|
||||||
<section class="product" ng-repeat="item in items">
|
<section class="product" ng-repeat="item in items">
|
||||||
|
@ -74,6 +85,10 @@
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
|
<vn-pagination
|
||||||
|
model="model"
|
||||||
|
scroll-selector="ui-view">
|
||||||
|
</vn-pagination>
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
|
|
||||||
<vn-auto class="right-block">
|
<vn-auto class="right-block">
|
||||||
|
|
|
@ -1,29 +1,48 @@
|
||||||
import ngModule from '../module';
|
import ngModule from '../module';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
class Controller {
|
class Controller {
|
||||||
constructor($scope, $stateParams) {
|
constructor($scope, $stateParams, $translate) {
|
||||||
this.$scope = $scope;
|
this.$scope = $scope;
|
||||||
this.$stateParams = $stateParams;
|
this.$stateParams = $stateParams;
|
||||||
}
|
this.orderList = [
|
||||||
|
{
|
||||||
applyFilter() {
|
order: 'relevancy DESC, name',
|
||||||
this.$scope.model.filter = this.filter;
|
name: $translate.instant('Default order')
|
||||||
this.$scope.model.refresh();
|
},
|
||||||
}
|
{
|
||||||
|
order: 'name',
|
||||||
set order(value) {
|
name: $translate.instant('Ascendant name')
|
||||||
this._order = value;
|
},
|
||||||
|
{
|
||||||
if (!value) return;
|
order: 'name DESC',
|
||||||
|
name: $translate.instant('Descendant name')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
order: 'price',
|
||||||
|
name: $translate.instant('Ascendant price')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
order: 'price DESC',
|
||||||
|
name: $translate.instant('Descendant price')
|
||||||
|
}
|
||||||
|
];
|
||||||
this.filter = {
|
this.filter = {
|
||||||
orderFk: value.id,
|
order: this.orderList[0].order
|
||||||
where: {}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
get order() {
|
get orderBy() {
|
||||||
return this._order;
|
return this._orderBy;
|
||||||
|
}
|
||||||
|
|
||||||
|
set orderBy(value) {
|
||||||
|
this._orderBy = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
setOrder(order) {
|
||||||
|
this.$scope.model.filter.order = order;
|
||||||
|
this.$scope.model.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
preview(event, item) {
|
preview(event, item) {
|
||||||
|
@ -36,7 +55,7 @@ class Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.$inject = ['$scope', '$stateParams'];
|
Controller.$inject = ['$scope', '$stateParams', '$translate'];
|
||||||
|
|
||||||
ngModule.component('vnOrderCatalog', {
|
ngModule.component('vnOrderCatalog', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
@import "colors";
|
||||||
|
|
||||||
|
.catalog-header {
|
||||||
|
border-color: $lines;
|
||||||
|
border-bottom: 1px solid rgba($lines, 0.5);
|
||||||
|
|
||||||
|
vn-one:first-child {
|
||||||
|
padding-top: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
vn-one:nth-child(2) {
|
||||||
|
padding-top: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: $secondary-font-color
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,8 +3,6 @@
|
||||||
url="/order/api/ItemCategories"
|
url="/order/api/ItemCategories"
|
||||||
data="categories">
|
data="categories">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
|
|
||||||
|
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-vertical vn-one>
|
<vn-vertical vn-one>
|
||||||
<vn-card >
|
<vn-card >
|
||||||
|
@ -12,37 +10,91 @@
|
||||||
<vn-horizontal pad-medium class="item-category">
|
<vn-horizontal pad-medium class="item-category">
|
||||||
<vn-one margin-small-v ng-repeat="category in categories">
|
<vn-one margin-small-v ng-repeat="category in categories">
|
||||||
<vn-icon
|
<vn-icon
|
||||||
ng-class="{'active': $ctrl.categoryFk == category.id}"
|
ng-class="{'active': $ctrl.category.id == category.id}"
|
||||||
pad-small
|
pad-small
|
||||||
icon="{{::category.icon}}"
|
icon="{{::category.icon}}"
|
||||||
vn-tooltip="{{::category.name}}"
|
vn-tooltip="{{::category.name}}"
|
||||||
ng-click="$ctrl.categoryFk = category.id">
|
ng-click="$ctrl.category = {
|
||||||
|
id: category.id,
|
||||||
|
value: category.name
|
||||||
|
}">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
</vn-one>
|
</vn-one>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
|
||||||
<vn-horizontal pad-medium class="catalog-header">
|
<vn-horizontal pad-medium class="catalog-header">
|
||||||
<vn-icon icon="search"></vn-icon>
|
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
initial-data="$ctrl.typeFk"
|
vn-id="type"
|
||||||
field="$ctrl.typeFk"
|
|
||||||
data="$ctrl.itemTypes"
|
data="$ctrl.itemTypes"
|
||||||
|
on-change="$ctrl.type = {
|
||||||
|
id: value,
|
||||||
|
value: type.selection.name
|
||||||
|
}"
|
||||||
|
field="$ctrl.type.id"
|
||||||
show-field="name"
|
show-field="name"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
label="Type">
|
label="Type">
|
||||||
|
<t-left-icons>
|
||||||
|
<i class="material-icons">search</i>
|
||||||
|
</t-left-icons>
|
||||||
|
<t-right-icons>
|
||||||
|
<i class="material-icons"
|
||||||
|
ng-click="$ctrl.openPanel($event)"
|
||||||
|
style="cursor: pointer; color: #aaa">
|
||||||
|
keyboard_arrow_down
|
||||||
|
</i>
|
||||||
|
</t-right-icons>
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
|
||||||
<vn-horizontal pad-medium class="catalog-header">
|
<vn-horizontal pad-medium class="catalog-header">
|
||||||
<vn-searchbar
|
<vn-one>
|
||||||
panel="vn-order-search-panel"
|
<vn-textfield
|
||||||
on-search="$ctrl.onSearch(filter)"
|
vn-id="search"
|
||||||
expr-builder="$ctrl.exprBuilder(param, value)">
|
ng-keyUp="$ctrl.onSearch($event)"
|
||||||
</vn-searchbar>
|
label="Search tag"
|
||||||
|
model="$ctrl.value">
|
||||||
|
<t-left-icons>
|
||||||
|
<i class="material-icons">search</i>
|
||||||
|
</t-left-icons>
|
||||||
|
<t-right-icons>
|
||||||
|
<i class="material-icons"
|
||||||
|
ng-click="$ctrl.openPanel($event)"
|
||||||
|
style="cursor: pointer; color: #aaa">
|
||||||
|
keyboard_arrow_down
|
||||||
|
</i>
|
||||||
|
</t-right-icons>
|
||||||
|
</vn-textfield>
|
||||||
|
|
||||||
|
<vn-popover
|
||||||
|
vn-id="popover"
|
||||||
|
on-close="$ctrl.onPopoverClose()">
|
||||||
|
<vn-order-search-panel/>
|
||||||
|
</vn-popover>
|
||||||
|
</vn-one>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
|
||||||
<vn-horizontal pad-medium>
|
<vn-horizontal pad-medium style="flex-wrap: wrap">
|
||||||
<vn-chip onRemove="$ctrl.onRemove($index)">Tag1</vn-chip>
|
<vn-chip
|
||||||
|
ng-if="$ctrl.category"
|
||||||
|
vn-tooltip="Category"
|
||||||
|
on-remove="$ctrl.category = null" ellipsize>
|
||||||
|
<span translate>{{$ctrl.category.value}}</span>
|
||||||
|
</vn-chip>
|
||||||
|
|
||||||
|
<vn-chip
|
||||||
|
ng-if="$ctrl.type"
|
||||||
|
vn-tooltip="Type"
|
||||||
|
on-remove="$ctrl.type = null" ellipsize>
|
||||||
|
<span translate>{{$ctrl.type.value}}</span>
|
||||||
|
</vn-chip>
|
||||||
|
|
||||||
|
<vn-chip
|
||||||
|
ng-repeat="tag in $ctrl.tags"
|
||||||
|
vn-tooltip="Value"
|
||||||
|
on-remove="$ctrl.remove($index)" ellipsize>
|
||||||
|
<span translate>{{::tag.value}}</span>
|
||||||
|
</vn-chip>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
|
|
|
@ -2,74 +2,175 @@ import ngModule from '../module';
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
class Controller {
|
class Controller {
|
||||||
constructor($http) {
|
constructor($http, $scope, $state, $compile, $transitions, $window) {
|
||||||
this.$http = $http;
|
this.$http = $http;
|
||||||
|
this.$scope = $scope;
|
||||||
|
this.$state = $state;
|
||||||
|
this.$stateParams = $state.params;
|
||||||
|
this.$compile = $compile;
|
||||||
|
this.$transitions = $transitions;
|
||||||
this.itemTypes = [];
|
this.itemTypes = [];
|
||||||
|
this.tags = [];
|
||||||
|
|
||||||
|
/* $transitions.onSuccess({}, transition => {
|
||||||
|
let params = {};
|
||||||
|
if (this.category)
|
||||||
|
params.category = this.category;
|
||||||
|
|
||||||
|
if (this.type)
|
||||||
|
params.type = this.type;
|
||||||
|
|
||||||
|
$window.history.replaceState(params);
|
||||||
|
|
||||||
|
this.applyFilters();
|
||||||
|
}); */
|
||||||
}
|
}
|
||||||
|
|
||||||
get where() {
|
get order() {
|
||||||
return this.catalog.filter.where;
|
return this._order;
|
||||||
}
|
}
|
||||||
|
|
||||||
set categoryFk(value) {
|
set order(value) {
|
||||||
if (this.where['it.categoryFk'] == value) {
|
this._order = value;
|
||||||
this.where['it.categoryFk'] = null;
|
|
||||||
this.where['i.typeFk'] = null;
|
if (!value.id) return;
|
||||||
this.itemTypes = [];
|
|
||||||
|
this.$scope.$$postDigest(() => {
|
||||||
|
let category;
|
||||||
|
let type;
|
||||||
|
|
||||||
|
if (this.$stateParams.category)
|
||||||
|
category = JSON.parse(this.$stateParams.category);
|
||||||
|
|
||||||
|
if (this.$stateParams.type)
|
||||||
|
type = JSON.parse(this.$stateParams.type);
|
||||||
|
|
||||||
|
if (category && category.id)
|
||||||
|
this.category = category;
|
||||||
|
|
||||||
|
if (type && type.id)
|
||||||
|
this.type = type;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get category() {
|
||||||
|
return this._category;
|
||||||
|
}
|
||||||
|
|
||||||
|
set category(value) {
|
||||||
|
this.itemTypes = [];
|
||||||
|
this.type = null;
|
||||||
|
|
||||||
|
if (!value || (this.category && this.category.id == value.id)) {
|
||||||
|
this._category = null;
|
||||||
|
this.updateStateParams();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.where['it.categoryFk'] = value;
|
this._category = value;
|
||||||
this.where['i.typeFk'] = null;
|
this.updateStateParams();
|
||||||
|
|
||||||
let query = `/item/api/ItemCategories/${value}/itemTypes`;
|
|
||||||
|
|
||||||
|
let query = `/item/api/ItemCategories/${value.id}/itemTypes`;
|
||||||
this.$http.get(query).then(res => {
|
this.$http.get(query).then(res => {
|
||||||
this.itemTypes = res.data;
|
this.itemTypes = res.data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
get categoryFk() {
|
get type() {
|
||||||
return this.where['it.categoryFk'];
|
return this._type;
|
||||||
}
|
}
|
||||||
|
|
||||||
set typeFk(value) {
|
set type(value) {
|
||||||
this.where['i.typeFk'] = value;
|
if (value && this.type && this.type.id == value.id) return;
|
||||||
|
|
||||||
this.catalog.applyFilter();
|
if (!value || !value.id) {
|
||||||
}
|
this._type = null;
|
||||||
|
this.updateStateParams();
|
||||||
|
|
||||||
get typeFk() {
|
return;
|
||||||
return this.where['i.typeFk'];
|
|
||||||
}
|
|
||||||
|
|
||||||
onSearch(filter) {
|
|
||||||
if (!Object.keys(filter).length) return;
|
|
||||||
|
|
||||||
if (filter.search) {
|
|
||||||
console.log(this.exprBuilder('search', filter.search));
|
|
||||||
Object.assign(this.where, this.exprBuilder('search', filter.search));
|
|
||||||
} else {
|
|
||||||
Object.assign(this.where, filter);
|
|
||||||
console.log(this.where);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.catalog.applyFilter();
|
this._type = value;
|
||||||
|
this.updateStateParams();
|
||||||
|
this.applyFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
exprBuilder(param, value) {
|
onSearch(event) {
|
||||||
switch (param) {
|
if (event.key !== 'Enter') return;
|
||||||
case 'search':
|
this.tags.push({
|
||||||
return {'itg.value': {like: value}};
|
value: this.value
|
||||||
case 'itg.tagFk':
|
});
|
||||||
case 'itg.value':
|
this.$scope.search.value = null;
|
||||||
return {[param]: value};
|
this.applyFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyFilters() {
|
||||||
|
let newArgs = {orderFk: this.order.id};
|
||||||
|
let model = this.catalog.$scope.model;
|
||||||
|
|
||||||
|
if (this.category)
|
||||||
|
newArgs.categoryFk = this.category.id;
|
||||||
|
|
||||||
|
if (this.type)
|
||||||
|
newArgs.typeFk = this.type.id;
|
||||||
|
|
||||||
|
model.params = {
|
||||||
|
args: newArgs,
|
||||||
|
tags: this.tags
|
||||||
|
};
|
||||||
|
|
||||||
|
this.catalog.$scope.model.refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(index) {
|
||||||
|
this.tags.splice(index, 1);
|
||||||
|
|
||||||
|
this.applyFilters();
|
||||||
|
}
|
||||||
|
|
||||||
|
openPanel(event) {
|
||||||
|
if (event.defaultPrevented) return;
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
this.$panel = this.$compile(`<vn-order-search-panel/>`)(this.$scope.$new());
|
||||||
|
let panel = this.$panel.isolateScope().$ctrl;
|
||||||
|
panel.filter = this.filter;
|
||||||
|
panel.onSubmit = filter => this.onPanelSubmit(filter);
|
||||||
|
|
||||||
|
this.$scope.popover.parent = this.$scope.search.element;
|
||||||
|
this.$scope.popover.child = this.$panel[0];
|
||||||
|
this.$scope.popover.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
onPanelSubmit(filter) {
|
||||||
|
this.$scope.popover.hide();
|
||||||
|
this.tags.push(filter);
|
||||||
|
this.applyFilters();
|
||||||
|
}
|
||||||
|
|
||||||
|
onPopoverClose() {
|
||||||
|
this.$panel.scope().$destroy();
|
||||||
|
this.$panel.remove();
|
||||||
|
this.$panel = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateStateParams() {
|
||||||
|
let params = {};
|
||||||
|
|
||||||
|
if (this.category)
|
||||||
|
params.category = JSON.stringify(this.category);
|
||||||
|
|
||||||
|
if (this.type)
|
||||||
|
params.type = JSON.stringify(this.type);
|
||||||
|
else
|
||||||
|
params.type = undefined;
|
||||||
|
|
||||||
|
this.$state.go(this.$state.current.name, params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.$inject = ['$http'];
|
Controller.$inject = ['$http', '$scope', '$state', '$compile', '$transitions', '$window'];
|
||||||
|
|
||||||
ngModule.component('vnCatalogFilter', {
|
ngModule.component('vnCatalogFilter', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
|
|
|
@ -1,22 +1,6 @@
|
||||||
@import "colors";
|
@import "colors";
|
||||||
|
|
||||||
vn-catalog-filter {
|
vn-catalog-filter {
|
||||||
/* .item-category, .item-category * {
|
|
||||||
|
|
||||||
|
|
||||||
vn-button button {
|
|
||||||
border-radius: 50%;
|
|
||||||
padding: 1em;
|
|
||||||
width: 4.9em;
|
|
||||||
height: 4.9em;
|
|
||||||
|
|
||||||
|
|
||||||
vn-icon i {
|
|
||||||
font-size: 32pt
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} */
|
|
||||||
|
|
||||||
.item-category {
|
.item-category {
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|
|
@ -1,5 +1,18 @@
|
||||||
Address: Consignatario
|
Address: Consignatario
|
||||||
Catalogue: Catálogo
|
Catalog: Catálogo
|
||||||
from: desde
|
from: desde
|
||||||
results: resultados
|
results: resultados
|
||||||
No results: Sin resultados
|
No results: Sin resultados
|
||||||
|
Plant: Planta
|
||||||
|
Flower: Flor
|
||||||
|
Handmade: Confección
|
||||||
|
Green: Verde
|
||||||
|
Accessories: Complemento
|
||||||
|
Category: Reino
|
||||||
|
Search tag: Buscar etiqueta
|
||||||
|
Order by: Ordenar por
|
||||||
|
Default order: Orden predeterminado
|
||||||
|
Ascendant name: Nombre ascendiente
|
||||||
|
Descendant name: Nombre descendiente
|
||||||
|
Ascendant price: Precio ascendiente
|
||||||
|
Descendant price: Precio descendiente
|
|
@ -4,7 +4,7 @@
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
vn-one
|
vn-one
|
||||||
label="Tag"
|
label="Tag"
|
||||||
field="filter['itg.tagFk']"
|
field="filter.tagFk"
|
||||||
url="/api/Tags"
|
url="/api/Tags"
|
||||||
show-field="name"
|
show-field="name"
|
||||||
value-field="id">
|
value-field="id">
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
<vn-textfield
|
<vn-textfield
|
||||||
vn-one
|
vn-one
|
||||||
label="Value"
|
label="Value"
|
||||||
model="filter['itg.value']">
|
model="filter.value">
|
||||||
</vn-textfield>
|
</vn-textfield>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal margin-large-top>
|
<vn-horizontal margin-large-top>
|
||||||
|
|
|
@ -54,6 +54,7 @@ function config($stateProvider, $urlRouterProvider, aclServiceProvider, modulesF
|
||||||
url: route.url,
|
url: route.url,
|
||||||
template: `<${route.component} ${getParams(route)}></${route.component}>`,
|
template: `<${route.component} ${getParams(route)}></${route.component}>`,
|
||||||
description: route.description,
|
description: route.description,
|
||||||
|
reloadOnSearch: false,
|
||||||
resolve: {
|
resolve: {
|
||||||
loader: loader(moduleName, validations)
|
loader: loader(moduleName, validations)
|
||||||
},
|
},
|
||||||
|
|
|
@ -26,15 +26,6 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.catalog-header {
|
|
||||||
border-color: $lines;
|
|
||||||
border-bottom: 1px solid rgba($lines, 0.5);
|
|
||||||
|
|
||||||
span {
|
|
||||||
color: $secondary-font-color
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.catalog-list {
|
.catalog-list {
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|
|
@ -10,6 +10,19 @@ module.exports = Self => {
|
||||||
type: 'Object',
|
type: 'Object',
|
||||||
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
||||||
http: {source: 'query'}
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'args',
|
||||||
|
type: 'Object',
|
||||||
|
description: 'orderFk, categoryFk, typeFk',
|
||||||
|
required: true,
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'tags',
|
||||||
|
type: ['Object'],
|
||||||
|
description: 'Request tags',
|
||||||
|
http: {source: 'query'}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
returns: {
|
returns: {
|
||||||
|
@ -22,7 +35,7 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.catalogFilter = async filter => {
|
Self.catalogFilter = async (filter, args, tags) => {
|
||||||
let stmts = [];
|
let stmts = [];
|
||||||
let stmt;
|
let stmt;
|
||||||
|
|
||||||
|
@ -31,23 +44,46 @@ module.exports = Self => {
|
||||||
stmt = new ParameterizedSQL(
|
stmt = new ParameterizedSQL(
|
||||||
`CREATE TEMPORARY TABLE tmp.item
|
`CREATE TEMPORARY TABLE tmp.item
|
||||||
(PRIMARY KEY (itemFk)) ENGINE = MEMORY
|
(PRIMARY KEY (itemFk)) ENGINE = MEMORY
|
||||||
SELECT
|
SELECT DISTINCT
|
||||||
i.id AS itemFk,
|
i.id AS itemFk,
|
||||||
i.typeFk,
|
i.typeFk,
|
||||||
it.categoryFk
|
it.categoryFk
|
||||||
FROM vn.item i
|
FROM vn.item i
|
||||||
JOIN vn.itemType it ON it.id = i.typeFk
|
JOIN vn.itemType it ON it.id = i.typeFk
|
||||||
JOIN vn.itemCategory ic ON ic.id = it.categoryFk`
|
JOIN vn.itemCategory ic ON ic.id = it.categoryFk`
|
||||||
);
|
);
|
||||||
|
|
||||||
if (filter.where['itg.tagFk'] || filter.where['itg.value']) {
|
if (tags) {
|
||||||
stmt.merge('JOIN vn.itemTag itg ON itg.itemFk = i.id');
|
let i = 1;
|
||||||
|
for (let tag of tags) {
|
||||||
|
let tAlias = `it${i++}`;
|
||||||
|
|
||||||
|
if (tag.tagFk) {
|
||||||
|
stmt.merge({
|
||||||
|
sql: `JOIN vn.itemTag ${tAlias} ON ${tAlias}.itemFk = i.id
|
||||||
|
AND ${tAlias}.tagFk = ?
|
||||||
|
AND ${tAlias}.value LIKE ?`,
|
||||||
|
params: [tag.tagFk, `%${tag.value}%`]
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
stmt.merge({
|
||||||
|
sql: `JOIN vn.itemTag ${tAlias} ON ${tAlias}.itemFk = i.id
|
||||||
|
AND ${tAlias}.value LIKE ?`,
|
||||||
|
params: [`%${tag.value}%`]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt.merge(Self.buildSuffix(filter));
|
if (args.typeFk)
|
||||||
|
stmt.merge({
|
||||||
|
sql: 'WHERE it.categoryFk = ? AND i.typeFk = ?',
|
||||||
|
params: [args.categoryFk, args.typeFk]
|
||||||
|
});
|
||||||
|
|
||||||
stmts.push(stmt);
|
stmts.push(stmt);
|
||||||
|
|
||||||
let order = await Self.findById(filter.orderFk);
|
let order = await Self.findById(args.orderFk);
|
||||||
stmts.push(new ParameterizedSQL(
|
stmts.push(new ParameterizedSQL(
|
||||||
'CALL vn.ticketCalculate(?, ?, ?)', [
|
'CALL vn.ticketCalculate(?, ?, ?)', [
|
||||||
order.landed,
|
order.landed,
|
||||||
|
@ -56,8 +92,7 @@ module.exports = Self => {
|
||||||
]
|
]
|
||||||
));
|
));
|
||||||
|
|
||||||
let itemsIndex = stmts.push(
|
stmt = new ParameterizedSQL(`SELECT
|
||||||
`SELECT
|
|
||||||
i.id,
|
i.id,
|
||||||
i.name,
|
i.name,
|
||||||
i.subName,
|
i.subName,
|
||||||
|
@ -77,9 +112,11 @@ module.exports = Self => {
|
||||||
FROM tmp.ticketCalculateItem tci
|
FROM tmp.ticketCalculateItem tci
|
||||||
JOIN vn.item i ON i.id = tci.itemFk
|
JOIN vn.item i ON i.id = tci.itemFk
|
||||||
JOIN vn.itemType it ON it.id = i.typeFk
|
JOIN vn.itemType it ON it.id = i.typeFk
|
||||||
JOIN vn.worker w on w.id = it.workerFk
|
JOIN vn.worker w on w.id = it.workerFk`
|
||||||
ORDER BY relevancy DESC, itemFk ASC, producer DESC`
|
);
|
||||||
) - 1;
|
stmt.merge(Self.buildSuffix(filter));
|
||||||
|
// stmt.merge(Self.buildOrderBy(orderBy));
|
||||||
|
let itemsIndex = stmts.push(stmt) - 1;
|
||||||
|
|
||||||
let pricesIndex = stmts.push(
|
let pricesIndex = stmts.push(
|
||||||
`SELECT
|
`SELECT
|
||||||
|
|
Loading…
Reference in New Issue