diff --git a/CHANGELOG.md b/CHANGELOG.md index a3e1ef4a1..e89f394b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,13 +8,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [2316.01] - 2023-05-04 ### Added -- - -### Changed - +### Changed +- (Artículo -> Precio fijado) Modificado el buscador superior por uno lateral + ### Fixed -- +- + ## [2314.01] - 2023-04-20 diff --git a/db/changes/231601/.gitkeep b/db/changes/231601/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/e2e/helpers/selectors.js b/e2e/helpers/selectors.js index 7689892f0..7e8b91fa1 100644 --- a/e2e/helpers/selectors.js +++ b/e2e/helpers/selectors.js @@ -414,7 +414,7 @@ export default { saveFieldsButton: '.vn-popover.shown vn-button[label="Save"] > button' }, itemFixedPrice: { - add: 'vn-fixed-price vn-icon-button[icon="add_circle"]', + add: 'vn-fixed-price vn-icon-button[vn-tooltip="Add fixed price"]', firstItemID: 'vn-fixed-price tr:nth-child(2) vn-autocomplete[ng-model="price.itemFk"]', fourthFixedPrice: 'vn-fixed-price tr:nth-child(5)', fourthItemID: 'vn-fixed-price tr:nth-child(5) vn-autocomplete[ng-model="price.itemFk"]', @@ -427,7 +427,18 @@ export default { fourthEnded: 'vn-fixed-price tr:nth-child(5) vn-date-picker[ng-model="price.ended"]', fourthDeleteIcon: 'vn-fixed-price tr:nth-child(5) > td:nth-child(9) > vn-icon-button[icon="delete"]', orderColumnId: 'vn-fixed-price th[field="itemFk"]', - removeWarehouseFilter: 'vn-searchbar > form > vn-textfield > div.container > div.prepend > prepend > div > span:nth-child(1) > vn-icon > i' + removeWarehouseFilter: 'vn-searchbar > form > vn-textfield > div.container > div.prepend > prepend > div > span:nth-child(1) > vn-icon > i', + generalSearchFilter: 'vn-fixed-price-search-panel vn-textfield[ng-model="$ctrl.filter.search"]', + reignFilter: 'vn-fixed-price-search-panel vn-horizontal.item-category vn-one', + typeFilter: 'vn-fixed-price-search-panel vn-autocomplete[ng-model="$ctrl.filter.typeFk"]', + buyerFilter: 'vn-fixed-price-search-panel vn-autocomplete[ng-model="$ctrl.filter.buyerFk"]', + warehouseFilter: 'vn-fixed-price-search-panel vn-autocomplete[ng-model="$ctrl.filter.warehouseFk"]', + mineFilter: 'vn-fixed-price-search-panel vn-check[ng-model="$ctrl.filter.mine"]', + hasMinPriceFilter: 'vn-fixed-price-search-panel vn-check[ng-model="$ctrl.filter.hasMinPrice"]', + addTag: 'vn-fixed-price-search-panel vn-icon-button[icon="add_circle"]', + tagFilter: 'vn-fixed-price-search-panel vn-autocomplete[ng-model="itemTag.tagFk"]', + tagValueFilter: 'vn-fixed-price-search-panel vn-autocomplete[ng-model="itemTag.value"]', + chip: 'vn-fixed-price-search-panel vn-chip > vn-icon' }, itemCreateView: { temporalName: 'vn-item-create vn-textfield[ng-model="$ctrl.item.provisionalName"]', diff --git a/e2e/paths/04-item/13_fixedPrice.spec.js b/e2e/paths/04-item/13_fixedPrice.spec.js index ec8238b87..df3b4f7a3 100644 --- a/e2e/paths/04-item/13_fixedPrice.spec.js +++ b/e2e/paths/04-item/13_fixedPrice.spec.js @@ -4,20 +4,69 @@ import getBrowser from '../../helpers/puppeteer'; describe('Item fixed prices path', () => { let browser; let page; + let httpRequest; + beforeAll(async() => { browser = await getBrowser(); page = browser.page; await page.loginAndModule('buyer', 'item'); await page.accessToSection('item.fixedPrice'); + page.on('request', req => { + if (req.url().includes(`FixedPrices/filter`)) + httpRequest = req.url(); + }); }); afterAll(async() => { await browser.close(); }); + it('should filter using all the fields', async() => { + await page.write(selectors.itemFixedPrice.generalSearchFilter, 'item'); + await page.keyboard.press('Enter'); + + expect(httpRequest).toContain('search=item'); + + await page.click(selectors.itemFixedPrice.chip); + await page.click(selectors.itemFixedPrice.reignFilter); + + expect(httpRequest).toContain('categoryFk'); + + await page.autocompleteSearch(selectors.itemFixedPrice.typeFilter, 'Alstroemeria'); + + expect(httpRequest).toContain('typeFk'); + + await page.click(selectors.itemFixedPrice.chip); + await page.autocompleteSearch(selectors.itemFixedPrice.buyerFilter, 'buyerNick'); + + expect(httpRequest).toContain('buyerFk'); + + await page.click(selectors.itemFixedPrice.chip); + await page.autocompleteSearch(selectors.itemFixedPrice.warehouseFilter, 'Algemesi'); + + expect(httpRequest).toContain('warehouseFk'); + + await page.click(selectors.itemFixedPrice.chip); + await page.click(selectors.itemFixedPrice.mineFilter); + + expect(httpRequest).toContain('mine=true'); + + await page.click(selectors.itemFixedPrice.chip); + await page.click(selectors.itemFixedPrice.hasMinPriceFilter); + + expect(httpRequest).toContain('hasMinPrice=true'); + + await page.click(selectors.itemFixedPrice.chip); + await page.click(selectors.itemFixedPrice.addTag); + await page.autocompleteSearch(selectors.itemFixedPrice.tagFilter, 'Color'); + await page.autocompleteSearch(selectors.itemFixedPrice.tagValueFilter, 'Brown'); + + expect(httpRequest).toContain('tags'); + + await page.click(selectors.itemFixedPrice.chip); + }); + it('should click on the add new fixed price button', async() => { - await page.waitToClick(selectors.itemFixedPrice.removeWarehouseFilter); - await page.waitForSpinnerLoad(); await page.waitToClick(selectors.itemFixedPrice.add); await page.waitForSelector(selectors.itemFixedPrice.fourthFixedPrice); }); @@ -36,10 +85,7 @@ describe('Item fixed prices path', () => { }); it('should reload the section and check the created price has the expected ID', async() => { - await page.accessToSection('item.index'); - await page.accessToSection('item.fixedPrice'); - await page.waitToClick(selectors.itemFixedPrice.removeWarehouseFilter); - await page.waitForSpinnerLoad(); + await page.goto(`http://localhost:5000/#!/item/fixed-price`); const result = await page.waitToGetProperty(selectors.itemFixedPrice.fourthItemID, 'value'); diff --git a/modules/item/back/models/item-shelving.json b/modules/item/back/models/item-shelving.json index 339b9ab6e..b24edfc53 100644 --- a/modules/item/back/models/item-shelving.json +++ b/modules/item/back/models/item-shelving.json @@ -20,9 +20,9 @@ }, "created": { "type": "date" - }, - "isChecked": { - "type": "boolean" + }, + "isChecked": { + "type": "boolean" } }, "relations": { diff --git a/modules/item/front/fixed-price-search-panel/index.html b/modules/item/front/fixed-price-search-panel/index.html index 5c8a58674..ebe210277 100644 --- a/modules/item/front/fixed-price-search-panel/index.html +++ b/modules/item/front/fixed-price-search-panel/index.html @@ -1,136 +1,215 @@ - - -
-
- - - - - - - - - -
{{name}}
-
- {{category.name}} -
-
-
-
- - - - - - - - - - - - - - - - - - - - - Tags - - - - - - - - - - - - - - - - - -
-
+ + + + + + + + + + + + + + + + + + +
{{name}}
+
+ {{category.name}} +
+
+
+
+ + + + + + + + + + + + + + + + + + + + Tags + + + + + + + + + + + + + +
+ + Id/{{$ctrl.$t('Name')}}: {{$ctrl.filter.search}} + + + {{$ctrl.$t('Category')}}: {{category.selection.name}} + + + {{$ctrl.$t('Type')}}: {{type.selection.name}} + + + {{$ctrl.$t('Buyer')}}: {{buyer.selection.nickname}} + + + {{$ctrl.$t('Warehouse')}}: {{warehouse.selection.name}} + + + {{$ctrl.$t('Started')}}: {{$ctrl.filter.started | date:'dd/MM/yyyy'}} + + + {{$ctrl.$t('Ended')}}: {{$ctrl.filter.ended | date:'dd/MM/yyyy'}} + + + {{$ctrl.$t('For me')}}: {{$ctrl.filter.mine ? '✓' : '✗'}} + + + {{$ctrl.$t('Minimum price')}}: {{$ctrl.filter.hasMinPrice ? '✓' : '✗'}} + + + {{$ctrl.showTagInfo(chipTag)}} + +
+
diff --git a/modules/item/front/fixed-price-search-panel/index.js b/modules/item/front/fixed-price-search-panel/index.js index ec13765fd..0882eb5ac 100644 --- a/modules/item/front/fixed-price-search-panel/index.js +++ b/modules/item/front/fixed-price-search-panel/index.js @@ -1,19 +1,60 @@ import ngModule from '../module'; import SearchPanel from 'core/components/searchbar/search-panel'; +import './style.scss'; class Controller extends SearchPanel { - get filter() { - return this.$.filter; + constructor($element, $) { + super($element, $); } - set filter(value = {}) { - if (!value.tags) value.tags = [{}]; + $onInit() { + this.filter = { + tags: [] + }; + } - this.$.filter = value; + changeCategory(id) { + if (this.filter.categoryFk != id) { + this.filter.categoryFk = id; + this.addFilters(); + } + } + + removeItemFilter(param) { + this.filter[param] = null; + if (param == 'categoryFk') this.filter['typeFk'] = null; + this.addFilters(); + } + + removeTag(tag) { + const index = this.filter.tags.indexOf(tag); + if (index > -1) this.filter.tags.splice(index, 1); + this.addFilters(); + } + + onKeyPress($event) { + if ($event.key === 'Enter') + this.addFilters(); + } + + addFilters() { + for (let i = 0; i < this.filter.tags.length; i++) { + if (!this.filter.tags[i].value) + this.filter.tags.splice(i, 1); + } + return this.model.addFilter({}, this.filter); + } + + showTagInfo(itemTag) { + if (!itemTag.tagFk) return itemTag.value; + return `${this.tags.find(tag => tag.id == itemTag.tagFk).name}: ${itemTag.value}`; } } ngModule.vnComponent('vnFixedPriceSearchPanel', { template: require('./index.html'), - controller: Controller + controller: Controller, + bindings: { + model: '<' + } }); diff --git a/modules/item/front/fixed-price-search-panel/index.spec.js b/modules/item/front/fixed-price-search-panel/index.spec.js new file mode 100644 index 000000000..597bc108e --- /dev/null +++ b/modules/item/front/fixed-price-search-panel/index.spec.js @@ -0,0 +1,56 @@ +import './index.js'; + +describe('Item', () => { + describe('Component vnFixedPriceSearchPanel', () => { + let $element; + let controller; + + beforeEach(ngModule('item')); + + beforeEach(angular.mock.inject($componentController => { + $element = angular.element(``); + controller = $componentController('vnFixedPriceSearchPanel', {$element}); + controller.model = {addFilter: () => {}}; + })); + + describe('removeItemFilter()', () => { + it(`should remove param from filter`, () => { + controller.filter = {tags: [], categoryFk: 1, typeFk: 1}; + const expectFilter = {tags: [], categoryFk: null, typeFk: null}; + + controller.removeItemFilter('categoryFk'); + + expect(controller.filter).toEqual(expectFilter); + }); + }); + + describe('removeTag()', () => { + it(`should remove tag from filter`, () => { + const tag = {tagFk: 1, value: 'Value'}; + controller.filter = {tags: [tag]}; + const expectFilter = {tags: []}; + + controller.removeTag(tag); + + expect(controller.filter).toEqual(expectFilter); + }); + }); + + describe('showTagInfo()', () => { + it(`should show tag value`, () => { + const tag = {value: 'Value'}; + const result = controller.showTagInfo(tag); + + expect(result).toEqual('Value'); + }); + + it(`should show tag name and value`, () => { + const tag = {tagFk: 1, value: 'Value'}; + controller.tags = [{id: 1, name: 'tagName'}]; + const result = controller.showTagInfo(tag); + + expect(result).toEqual('tagName: Value'); + }); + }); + }); +}); diff --git a/modules/item/front/fixed-price-search-panel/style.scss b/modules/item/front/fixed-price-search-panel/style.scss new file mode 100644 index 000000000..a63f84f3b --- /dev/null +++ b/modules/item/front/fixed-price-search-panel/style.scss @@ -0,0 +1,71 @@ +@import "variables"; + +vn-fixed-price-search-panel vn-side-menu { + .menu { + min-width: $right-menu-width; + } + & > div { + .input { + padding-left: $spacing-md; + padding-right: $spacing-md; + border-color: $color-spacer; + border-bottom: $border-thin; + } + .horizontal { + padding-left: $spacing-md; + padding-right: $spacing-md; + grid-auto-flow: column; + grid-column-gap: $spacing-sm; + align-items: center; + } + .tags { + padding: $spacing-md; + padding-bottom: 0%; + padding-top: 0%; + align-items: center; + } + .chips { + display: flex; + flex-wrap: wrap; + padding: $spacing-md; + overflow: hidden; + max-width: 100%; + border-color: $color-spacer; + border-top: $border-thin; + } + .item-category { + padding: $spacing-sm; + justify-content: flex-start; + align-items: flex-start; + flex-wrap: wrap; + + vn-autocomplete[vn-id="category"] { + display: none; + } + + & > vn-one { + padding: $spacing-sm; + min-width: 33.33%; + text-align: center; + box-sizing: border-box; + + & > vn-icon { + padding: $spacing-sm; + background-color: $color-font-secondary; + border-radius: 50%; + cursor: pointer; + + &.active { + background-color: $color-main; + color: #fff; + } + & > i:before { + font-size: 2.6rem; + width: 16px; + height: 16px; + } + } + } + } + } +} diff --git a/modules/item/front/fixed-price/index.html b/modules/item/front/fixed-price/index.html index a82fd2742..9a143d10d 100644 --- a/modules/item/front/fixed-price/index.html +++ b/modules/item/front/fixed-price/index.html @@ -14,16 +14,10 @@ order="name">
- - + +