import ngModule from '../module'; import Section from 'salix/components/section'; import './style.scss'; class Controller extends Section { constructor($element, $) { super($element, $); this.itemTypes = []; this._tagGroups = []; // Static autocomplete data this.orderWays = [ {way: 'ASC', name: 'Ascendant'}, {way: 'DESC', name: 'Descendant'}, ]; this.defaultOrderFields = [ {field: 'relevancy DESC, name', name: 'Relevancy', priority: 999}, {field: 'showOrder, price', name: 'Color and price', priority: 999}, {field: 'name', name: 'Name', priority: 999}, {field: 'price', name: 'Price', priority: 999} ]; this.orderFields = [].concat(this.defaultOrderFields); this._orderWay = this.orderWays[0].way; this.orderField = this.orderFields[0].field; } $onChanges() { this.getData().then(() => { if (this.order && this.order.isConfirmed) this.$state.go('order.card.line'); }); } getData() { return this.$http.get(`Orders/${this.$params.id}`) .then(res => this.order = res.data); } /** * 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.$params.categoryId) this.categoryId = parseInt(this.$params.categoryId); if (this.$params.typeId) this.typeId = parseInt(this.$params.typeId); if (this.$params.tagGroups) this.tagGroups = JSON.parse(this.$params.tagGroups); }); } get items() { return this._items; } set items(value) { this._items = value; if (!value) return; this.fetchResultTags(value); this.buildOrderFilter(); } get categoryId() { return this._categoryId; } set categoryId(value = null) { this._categoryId = value; this.itemTypes = []; this.typeId = null; this.updateStateParams(); if (this.tagGroups.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.tagGroups.length > 0) this.applyFilters(); } get tagGroups() { return this._tagGroups; } set tagGroups(value) { this._tagGroups = 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.tagGroups.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 tag value * @param {object} event */ onSearchByTag(event) { const value = this.$.search.value; if (event.key !== 'Enter' || !value) return; this.tagGroups.push({values: [{value: value}]}); this.$.search.value = null; this.updateStateParams(); this.applyFilters(); } remove(index) { this.tagGroups.splice(index, 1); this.updateStateParams(); if (this.tagGroups.length >= 0 || this.itemId || this.typeId) this.applyFilters(); } removeItemId() { this.itemId = null; this.$.searchbar.doSearch({}, 'bar'); } removeItemName() { this.itemName = null; this.$.searchbar.doSearch({}, 'bar'); } applyFilters(filter = {}) { let newParams = {}; let newFilter = Object.assign({}, filter); const model = this.$.model; if (this.categoryId) newFilter.categoryFk = this.categoryId; if (this.typeId) newFilter.typeFk = this.typeId; newParams = { orderFk: this.$params.id, orderBy: this.getOrderBy(), tagGroups: this.tagGroups, }; return 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(); const values = filter.values; const nonEmptyValues = values.filter(tagValue => { return tagValue.value; }); filter.values = nonEmptyValues; if (filter.tagFk && nonEmptyValues.length) { this.tagGroups.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.tagGroups = undefined; if (this.tagGroups && this.tagGroups.length) params.tagGroups = JSON.stringify(this.sanitizedTagGroupParam()); this.$state.go(this.$state.current.name, params); } sanitizedTagGroupParam() { const tagGroups = []; for (let tagGroup of this.tagGroups) { const tagParam = {values: []}; for (let tagValue of tagGroup.values) tagParam.values.push({value: tagValue.value}); if (tagGroup.tagFk) tagParam.tagFk = tagGroup.tagFk; if (tagGroup.tagSelection) { tagParam.tagSelection = { name: tagGroup.tagSelection.name }; } tagGroups.push(tagParam); } return tagGroups; } fetchResultTags(items) { const resultTags = []; for (let item of items) { for (let itemTag of item.tags) { const alreadyAdded = resultTags.findIndex(tag => { return tag.tagFk == itemTag.tagFk; }); if (alreadyAdded == -1) resultTags.push({...itemTag, priority: 1}); else resultTags[alreadyAdded].priority += 1; } } this.resultTags = resultTags; } buildOrderFilter() { const filter = [].concat(this.defaultOrderFields); for (let tag of this.resultTags) filter.push({...tag, field: tag.id, isTag: true}); this.orderFields = filter; } onSearch(params) { if (!params) return; this.itemId = null; this.itemName = null; if (params.search) { if (/^\d+$/.test(params.search)) { this.itemId = params.search; return this.applyFilters({ 'i.id': params.search }); } else { this.itemName = params.search; return this.applyFilters({ 'i.name': {like: `%${params.search}%`} }); } } else return this.applyFilters(); } formatTooltip(tagGroup) { const tagValues = tagGroup.values; let title = ''; if (tagGroup.tagFk) { const tagName = tagGroup.tagSelection.name; title += `${tagName}: `; } for (let [i, tagValue] of tagValues.entries()) { if (i > 0) title += ', '; title += `"${tagValue.value}"`; } return `${title}`; } } ngModule.vnComponent('vnOrderCatalog', { template: require('./index.html'), controller: Controller });