import ngModule from '../module'; import './style.scss'; class Controller { constructor($http, $scope, $state, $compile, $transitions) { this.$http = $http; this.$ = $scope; this.$state = $state; this.$stateParams = $state.params; this.$compile = $compile; this.$transitions = $transitions; this.itemTypes = []; this._tags = []; // Static autocomplete data this.orderWays = [ {way: 'ASC', name: 'Ascendant'}, {way: 'DESC', name: 'Descendant'}, ]; this.defaultOrderFields = [ {field: 'relevancy DESC, name', name: 'Relevancy'}, {field: 'showOrder, price', name: 'Color and price'}, {field: 'name', name: 'Name'}, {field: 'price', name: 'Price'} ]; this.orderFields = [].concat(this.defaultOrderFields); this._orderWay = this.orderWays[0].way; this.orderField = this.orderFields[0].field; } $onChanges() { if (this.order && this.order.isConfirmed) this.$state.go('order.card.line'); } /** * Fills order autocomplete with tags * obtained from last filtered */ get order() { return this._order; } /** * Sets filter values from state params * * @param {Object} value - Order data */ set order(value) { this._order = value; if (!value) return; this.$.$applyAsync(() => { if (this.$stateParams.itemId) this.itemId = parseInt(this.$stateParams.itemId); if (this.$stateParams.categoryId) this.categoryId = parseInt(this.$stateParams.categoryId); if (this.$stateParams.typeId) this.typeId = parseInt(this.$stateParams.typeId); if (this.$stateParams.tags) this.tags = JSON.parse(this.$stateParams.tags); }); } get items() { return this._items; } set items(value) { this._items = value; if (!value) return; this.buildTagsFilter(value); this.buildOrderFilter(value); } get categoryId() { return this._categoryId; } set categoryId(value = null) { this._categoryId = value; this.itemTypes = []; this.typeId = null; this.updateStateParams(); if (this.tags.length > 0) this.applyFilters(); if (value) this.updateItemTypes(); } changeCategory(id) { if (this._categoryId == id) id = null; this.categoryId = id; } get typeId() { return this._typeId; } set typeId(value) { this._typeId = value; this.updateStateParams(); if (value || this.tags.length > 0) this.applyFilters(); } get itemId() { return this._itemId; } set itemId(value) { this._itemId = value; this.updateStateParams(); this.applyFilters(); } get tags() { return this._tags; } set tags(value) { this._tags = value; this.updateStateParams(); if (value.length) this.applyFilters(); } /** * Get order way ASC/DESC */ get orderWay() { return this._orderWay; } set orderWay(value) { this._orderWay = value; if (value) this.applyOrder(); } /** * Returns the order way selection */ get orderSelection() { return this._orderSelection; } set orderSelection(value) { this._orderSelection = value; if (value) this.applyOrder(); } /** * Apply order to model */ applyOrder() { if (this.typeId || this.tags.length > 0) this.$.model.addFilter(null, {orderBy: this.getOrderBy()}); } /** * Returns order param * * @return {Object} - Order param */ getOrderBy() { const isTag = !!(this.orderSelection && this.orderSelection.isTag); return { field: this.orderField, way: this.orderWay, isTag: isTag }; } /** * Refreshes item type dropdown data */ updateItemTypes() { let params = { itemCategoryId: this.categoryId }; const query = `Orders/${this.order.id}/getItemTypeAvailable`; this.$http.get(query, {params}).then(res => this.itemTypes = res.data); } /** * Search by item id filter * @param {object} event */ onSearchById(event) { const value = this.$.itemId.value; if (event.key === 'Enter' && value) { this.itemId = value; this.$.itemId.value = null; } } /** * Search by tag value * @param {object} event */ onSearchByTag(event) { const value = this.$.search.value; if (event.key !== 'Enter' || !value) return; this.tags.push({ value: value, }); this.$.search.value = null; this.updateStateParams(); this.applyFilters(); } remove(index) { this.tags.splice(index, 1); this.updateStateParams(); if (this.tags.length >= 0 || this.itemId || this.typeId) this.applyFilters(); } applyFilters() { let newParams = {}; let newFilter = {}; const model = this.$.model; if (this.categoryId) newFilter.categoryFk = this.categoryId; if (this.typeId) newFilter.typeFk = this.typeId; if (this.itemId) newFilter = {'i.id': this.itemId}; newParams = { orderFk: this.order.id, orderBy: this.getOrderBy(), tags: this.tags, }; model.applyFilter({where: newFilter}, newParams); } openPanel(event) { if (event.defaultPrevented) return; event.preventDefault(); this.panelFilter = {}; this.$.popover.show(this.$.search.element); } onPanelSubmit(filter) { this.$.popover.hide(); this.tags.push(filter); this.updateStateParams(); this.applyFilters(); } /** * Updates url state params from filter values */ updateStateParams() { const params = {}; params.categoryId = undefined; if (this.categoryId) params.categoryId = this.categoryId; params.typeId = undefined; if (this.typeId) params.typeId = this.typeId; params.itemId = undefined; if (this.itemId) params.itemId = this.itemId; params.tags = undefined; if (this.tags.length) { const tags = []; for (let tag of this.tags) { const tagParam = {value: tag.value}; if (tag.tagSelection) { tagParam.tagFk = tag.tagFk; tagParam.tagSelection = { name: tag.tagSelection.name }; } tags.push(tagParam); } params.tags = JSON.stringify(tags); } this.$state.go(this.$state.current.name, params); } buildTagsFilter(items) { const tagValues = []; items.forEach(item => { item.tags.forEach(itemTag => { const alreadyAdded = tagValues.findIndex(tag => { return tag.value == itemTag.value; }); if (alreadyAdded == -1) tagValues.push(itemTag); }); }); this.tagValues = tagValues; } buildOrderFilter(items) { const tags = []; items.forEach(item => { item.tags.forEach(itemTag => { const alreadyAdded = tags.findIndex(tag => { return tag.field == itemTag.tagFk; }); if (alreadyAdded == -1) { tags.push({ name: itemTag.name, field: itemTag.tagFk, isTag: true }); } }); }); let newFilterList = [].concat(this.defaultOrderFields); newFilterList = newFilterList.concat(tags); this.orderFields = newFilterList; } } Controller.$inject = ['$http', '$scope', '$state', '$compile', '$transitions']; ngModule.component('vnOrderCatalog', { template: require('./index.html'), controller: Controller, bindings: { order: '<' } });