Merge pull request 'fixes #3291 entry.latest-buys añadir el buscador de la cesta' (!1298) from 3291-entryLatestBuys-buscador into dev
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
Reviewed-on: #1298 Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
This commit is contained in:
commit
b5b2e429e5
|
@ -1260,6 +1260,21 @@ export default {
|
||||||
importBuysButton: 'vn-entry-buy-import button[type="submit"]'
|
importBuysButton: 'vn-entry-buy-import button[type="submit"]'
|
||||||
},
|
},
|
||||||
entryLatestBuys: {
|
entryLatestBuys: {
|
||||||
|
table: 'tbody > tr:not(.empty-rows)',
|
||||||
|
chip: 'vn-chip > vn-icon',
|
||||||
|
generalSearchInput: 'vn-textfield[ng-model="$ctrl.filter.search"]',
|
||||||
|
firstReignIcon: 'vn-horizontal.item-category vn-one',
|
||||||
|
typeInput: 'vn-autocomplete[ng-model="$ctrl.filter.typeFk"]',
|
||||||
|
salesPersonInput: 'vn-autocomplete[ng-model="$ctrl.filter.salesPersonFk"]',
|
||||||
|
supplierInput: 'vn-autocomplete[ng-model="$ctrl.filter.supplierFk"]',
|
||||||
|
fromInput: 'vn-date-picker[ng-model="$ctrl.filter.from"]',
|
||||||
|
toInput: 'vn-date-picker[ng-model="$ctrl.filter.to"]',
|
||||||
|
activeCheck: 'vn-check[ng-model="$ctrl.filter.active"]',
|
||||||
|
floramondoCheck: 'vn-check[ng-model="$ctrl.filter.floramondo"]',
|
||||||
|
visibleCheck: 'vn-check[ng-model="$ctrl.filter.visible"]',
|
||||||
|
addTagButton: 'vn-icon-button[vn-tooltip="Add tag"]',
|
||||||
|
itemTagInput: 'vn-autocomplete[ng-model="itemTag.tagFk"]',
|
||||||
|
itemTagValueInput: 'vn-autocomplete[ng-model="itemTag.value"]',
|
||||||
firstBuy: 'vn-entry-latest-buys tbody > tr:nth-child(1)',
|
firstBuy: 'vn-entry-latest-buys tbody > tr:nth-child(1)',
|
||||||
allBuysCheckBox: 'vn-entry-latest-buys thead vn-check',
|
allBuysCheckBox: 'vn-entry-latest-buys thead vn-check',
|
||||||
secondBuyCheckBox: 'vn-entry-latest-buys tbody tr:nth-child(2) vn-check[ng-model="buy.checked"]',
|
secondBuyCheckBox: 'vn-entry-latest-buys tbody tr:nth-child(2) vn-check[ng-model="buy.checked"]',
|
||||||
|
|
|
@ -4,10 +4,15 @@ import getBrowser from '../../helpers/puppeteer';
|
||||||
describe('Entry lastest buys path', () => {
|
describe('Entry lastest buys path', () => {
|
||||||
let browser;
|
let browser;
|
||||||
let page;
|
let page;
|
||||||
|
const httpRequests = [];
|
||||||
|
|
||||||
beforeAll(async() => {
|
beforeAll(async() => {
|
||||||
browser = await getBrowser();
|
browser = await getBrowser();
|
||||||
page = browser.page;
|
page = browser.page;
|
||||||
|
page.on('request', req => {
|
||||||
|
if (req.url().includes(`Buys/latestBuysFilter`))
|
||||||
|
httpRequests.push(req.url());
|
||||||
|
});
|
||||||
await page.loginAndModule('buyer', 'entry');
|
await page.loginAndModule('buyer', 'entry');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -20,6 +25,87 @@ describe('Entry lastest buys path', () => {
|
||||||
await page.waitForSelector(selectors.entryLatestBuys.editBuysButton, {visible: false});
|
await page.waitForSelector(selectors.entryLatestBuys.editBuysButton, {visible: false});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should filter by name', async() => {
|
||||||
|
await page.write(selectors.entryLatestBuys.generalSearchInput, 'Melee');
|
||||||
|
await page.keyboard.press('Enter');
|
||||||
|
await page.waitToClick(selectors.entryLatestBuys.chip);
|
||||||
|
|
||||||
|
expect(httpRequests.find(req => req.includes(('search=Melee')))).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter by reign and type', async() => {
|
||||||
|
await page.click(selectors.entryLatestBuys.firstReignIcon);
|
||||||
|
await page.autocompleteSearch(selectors.entryLatestBuys.typeInput, 'Alstroemeria');
|
||||||
|
await page.click(selectors.entryLatestBuys.chip);
|
||||||
|
|
||||||
|
expect(httpRequests.find(req => req.includes(('categoryFk')))).toBeDefined();
|
||||||
|
expect(httpRequests.find(req => req.includes(('typeFk')))).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter by from date', async() => {
|
||||||
|
await page.pickDate(selectors.entryLatestBuys.fromInput, new Date());
|
||||||
|
await page.waitToClick(selectors.entryLatestBuys.chip);
|
||||||
|
|
||||||
|
expect(httpRequests.find(req => req.includes(('from')))).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter by to date', async() => {
|
||||||
|
await page.pickDate(selectors.entryLatestBuys.toInput, new Date());
|
||||||
|
await page.waitToClick(selectors.entryLatestBuys.chip);
|
||||||
|
|
||||||
|
expect(httpRequests.find(req => req.includes(('to')))).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter by sales person', async() => {
|
||||||
|
await page.autocompleteSearch(selectors.entryLatestBuys.salesPersonInput, 'buyerNick');
|
||||||
|
await page.waitToClick(selectors.entryLatestBuys.chip);
|
||||||
|
|
||||||
|
expect(httpRequests.find(req => req.includes(('salesPersonFk')))).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter by supplier', async() => {
|
||||||
|
await page.autocompleteSearch(selectors.entryLatestBuys.supplierInput, 'Farmer King');
|
||||||
|
await page.waitToClick(selectors.entryLatestBuys.chip);
|
||||||
|
|
||||||
|
expect(httpRequests.find(req => req.includes(('supplierFk')))).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter by active', async() => {
|
||||||
|
await page.waitToClick(selectors.entryLatestBuys.activeCheck);
|
||||||
|
await page.waitToClick(selectors.entryLatestBuys.activeCheck);
|
||||||
|
await page.waitToClick(selectors.entryLatestBuys.chip);
|
||||||
|
|
||||||
|
expect(httpRequests.find(req => req.includes(('active=true')))).toBeDefined();
|
||||||
|
expect(httpRequests.find(req => req.includes(('active=false')))).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter by visible', async() => {
|
||||||
|
await page.waitToClick(selectors.entryLatestBuys.visibleCheck);
|
||||||
|
await page.waitToClick(selectors.entryLatestBuys.visibleCheck);
|
||||||
|
await page.waitToClick(selectors.entryLatestBuys.chip);
|
||||||
|
|
||||||
|
expect(httpRequests.find(req => req.includes(('visible=true')))).toBeDefined();
|
||||||
|
expect(httpRequests.find(req => req.includes(('visible=false')))).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter by floramondo', async() => {
|
||||||
|
await page.waitToClick(selectors.entryLatestBuys.floramondoCheck);
|
||||||
|
await page.waitToClick(selectors.entryLatestBuys.floramondoCheck);
|
||||||
|
await page.waitToClick(selectors.entryLatestBuys.chip);
|
||||||
|
|
||||||
|
expect(httpRequests.find(req => req.includes(('floramondo=true')))).toBeDefined();
|
||||||
|
expect(httpRequests.find(req => req.includes(('floramondo=false')))).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should filter by tag Color', async() => {
|
||||||
|
await page.waitToClick(selectors.entryLatestBuys.addTagButton);
|
||||||
|
await page.autocompleteSearch(selectors.entryLatestBuys.itemTagInput, 'Color');
|
||||||
|
await page.autocompleteSearch(selectors.entryLatestBuys.itemTagValueInput, 'Brown');
|
||||||
|
await page.waitToClick(selectors.entryLatestBuys.chip);
|
||||||
|
|
||||||
|
expect(httpRequests.find(req => req.includes(('tags')))).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
it('should select all lines but one and then check the edit buys button appears', async() => {
|
it('should select all lines but one and then check the edit buys button appears', async() => {
|
||||||
await page.waitToClick(selectors.entryLatestBuys.allBuysCheckBox);
|
await page.waitToClick(selectors.entryLatestBuys.allBuysCheckBox);
|
||||||
await page.waitToClick(selectors.entryLatestBuys.secondBuyCheckBox);
|
await page.waitToClick(selectors.entryLatestBuys.secondBuyCheckBox);
|
||||||
|
|
|
@ -1,198 +1,243 @@
|
||||||
<mg-ajax path="Tags" options="mgIndex as tags"></mg-ajax>
|
<vn-crud-model url="Tags" fields="['id','name', 'isFree']" data="$ctrl.tags" auto-load="true">
|
||||||
<div class="search-panel">
|
<vn-crud-model url="ItemCategories" data="$ctrl.categories" auto-load="true"></vn-crud-model>
|
||||||
<form ng-submit="$ctrl.onSearch()">
|
<vn-side-menu side="right">
|
||||||
<vn-horizontal>
|
<vn-horizontal class="input">
|
||||||
<vn-textfield
|
<vn-textfield
|
||||||
label="General search"
|
label="General search"
|
||||||
ng-model="filter.search"
|
ng-model="$ctrl.filter.search"
|
||||||
info="Search items by id, name or barcode"
|
info="Search items by id, name or barcode"
|
||||||
vn-focus>
|
vn-focus
|
||||||
</vn-textfield>
|
ng-keydown="$ctrl.onKeyPress($event)">
|
||||||
</vn-horizontal>
|
</vn-textfield>
|
||||||
<vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-autocomplete
|
<vn-horizontal class="item-category">
|
||||||
vn-focus
|
<vn-autocomplete
|
||||||
url="ItemCategories"
|
vn-id="category"
|
||||||
label="Category"
|
data="$ctrl.categories"
|
||||||
show-field="name"
|
ng-model="$ctrl.filter.categoryFk"
|
||||||
value-field="id"
|
show-field="name"
|
||||||
ng-model="filter.categoryFk">
|
value-field="id"
|
||||||
</vn-autocomplete>
|
label="Category">
|
||||||
<vn-autocomplete
|
</vn-autocomplete>
|
||||||
url="ItemTypes"
|
<vn-one ng-repeat="category in $ctrl.categories">
|
||||||
label="Type"
|
<vn-icon
|
||||||
where="{categoryFk: filter.categoryFk}"
|
ng-class="{'active': $ctrl.filter.categoryFk == category.id}"
|
||||||
show-field="name"
|
icon="{{::category.icon}}"
|
||||||
value-field="id"
|
vn-tooltip="{{::category.name}}"
|
||||||
ng-model="filter.typeFk"
|
ng-click="$ctrl.changeCategory(category.id)">
|
||||||
fields="['categoryFk']"
|
</vn-icon>
|
||||||
include="'category'">
|
</vn-one>
|
||||||
<tpl-item>
|
</vn-horizontal>
|
||||||
<div>{{name}}</div>
|
<vn-vertical class="input">
|
||||||
<div class="text-caption text-secondary">
|
<vn-autocomplete
|
||||||
{{category.name}}
|
vn-id="type"
|
||||||
</div>
|
disabled="!$ctrl.filter.categoryFk"
|
||||||
</tpl-item>>
|
url="ItemTypes"
|
||||||
</vn-autocomplete>
|
label="Type"
|
||||||
</vn-horizontal>
|
where="{categoryFk: $ctrl.filter.categoryFk}"
|
||||||
<vn-horizontal>
|
show-field="name"
|
||||||
<vn-autocomplete
|
value-field="id"
|
||||||
disabled="false"
|
ng-model="$ctrl.filter.typeFk"
|
||||||
ng-model="filter.salesPersonFk"
|
fields="['categoryFk']"
|
||||||
url="Workers/activeWithRole"
|
include="'category'"
|
||||||
show-field="nickname"
|
on-change="$ctrl.applyFilters()">
|
||||||
search-function="{firstName: $search}"
|
<tpl-item>
|
||||||
value-field="id"
|
<div>{{name}}</div>
|
||||||
where="{role: {inq: ['logistic', 'buyer']}}"
|
<div class="text-caption text-secondary">
|
||||||
label="Buyer">
|
{{category.name}}
|
||||||
</vn-autocomplete>
|
</div> </tpl-item
|
||||||
<vn-autocomplete
|
>>
|
||||||
vn-one
|
</vn-autocomplete>
|
||||||
label="Supplier"
|
</vn-vertical>
|
||||||
ng-model="filter.supplierFk"
|
<vn-horizontal class="input horizontal">
|
||||||
url="Suppliers"
|
<vn-autocomplete
|
||||||
fields="['name','nickname']"
|
vn-id="salesPerson"
|
||||||
search-function="{or: [{nickname: {like: '%'+ $search +'%'}}, {name: {like: '%'+ $search +'%'}}]}"
|
disabled="false"
|
||||||
show-field="name"
|
ng-model="$ctrl.filter.salesPersonFk"
|
||||||
value-field="id">
|
url="Workers/activeWithRole"
|
||||||
<tpl-item>{{name}}: {{nickname}}</tpl-item>
|
show-field="nickname"
|
||||||
</vn-autocomplete>
|
search-function="{firstName: $search}"
|
||||||
</vn-horizontal>
|
value-field="id"
|
||||||
<vn-horizontal>
|
where="{role: {inq: ['logistic', 'buyer']}}"
|
||||||
<vn-date-picker
|
label="Buyer"
|
||||||
vn-one
|
on-change="$ctrl.applyFilters()">
|
||||||
label="From"
|
</vn-autocomplete>
|
||||||
ng-model="filter.from">
|
<vn-autocomplete
|
||||||
</vn-date-picker>
|
vn-id="supplier"
|
||||||
<vn-date-picker
|
label="Supplier"
|
||||||
vn-one
|
ng-model="$ctrl.filter.supplierFk"
|
||||||
label="To"
|
url="Suppliers"
|
||||||
ng-model="filter.to">
|
fields="['name','nickname']"
|
||||||
</vn-date-picker>
|
search-function="{or: [{nickname: {like: '%'+ $search +'%'}}, {name: {like: '%'+ $search +'%'}}]}"
|
||||||
</vn-horizontal>
|
show-field="name"
|
||||||
<vn-horizontal>
|
value-field="id"
|
||||||
<vn-check
|
on-change="$ctrl.applyFilters()">
|
||||||
label="Is active"
|
<tpl-item>{{name}}: {{nickname}}</tpl-item>
|
||||||
ng-model="filter.active"
|
</vn-autocomplete>
|
||||||
triple-state="true">
|
</vn-horizontal>
|
||||||
</vn-check>
|
<vn-vertical class="input">
|
||||||
<vn-check
|
<vn-date-picker
|
||||||
label="Is visible"
|
label="From"
|
||||||
ng-model="filter.visible"
|
ng-model="$ctrl.filter.from"
|
||||||
triple-state="true">
|
on-change="$ctrl.applyFilters()">
|
||||||
</vn-check>
|
</vn-date-picker>
|
||||||
<vn-check
|
<vn-date-picker
|
||||||
label="Is floramondo"
|
label="To"
|
||||||
ng-model="filter.floramondo"
|
ng-model="$ctrl.filter.to"
|
||||||
triple-state="true">
|
on-change="$ctrl.applyFilters()">
|
||||||
</vn-check>
|
</vn-date-picker>
|
||||||
</vn-horizontal>
|
</vn-vertical>
|
||||||
<vn-horizontal class="vn-pt-sm">
|
<vn-horizontal class="checks">
|
||||||
<vn-one class="text-subtitle1" translate>
|
<vn-check
|
||||||
Tags
|
label="Is active"
|
||||||
</vn-one>
|
ng-model="$ctrl.filter.active"
|
||||||
<vn-icon-button
|
triple-state="true"
|
||||||
vn-none
|
ng-click="$ctrl.applyFilters()">
|
||||||
vn-bind="+"
|
</vn-check>
|
||||||
vn-tooltip="Add tag"
|
<vn-check
|
||||||
icon="add_circle"
|
label="Is visible"
|
||||||
ng-click="filter.tags.push({})">
|
ng-model="$ctrl.filter.visible"
|
||||||
</vn-icon-button>
|
triple-state="true"
|
||||||
</vn-horizontal>
|
ng-click="$ctrl.applyFilters()">
|
||||||
<vn-horizontal ng-repeat="itemTag in filter.tags">
|
</vn-check>
|
||||||
<vn-autocomplete
|
<vn-check
|
||||||
vn-id="tag"
|
label="Is floramondo"
|
||||||
ng-model="itemTag.tagFk"
|
ng-model="$ctrl.filter.floramondo"
|
||||||
data="tags.model"
|
triple-state="true"
|
||||||
show-field="name"
|
ng-click="$ctrl.applyFilters()">
|
||||||
label="Tag"
|
</vn-check>
|
||||||
on-change="itemTag.value = null">
|
</vn-horizontal>
|
||||||
</vn-autocomplete>
|
<vn-horizontal class="tags">
|
||||||
<vn-textfield
|
<vn-one class="text-subtitle1" translate> Tags </vn-one>
|
||||||
ng-show="tag.selection.isFree || tag.selection.isFree == undefined"
|
<vn-icon-button
|
||||||
vn-id="text"
|
vn-none
|
||||||
label="Value"
|
vn-tooltip="Add tag"
|
||||||
ng-model="itemTag.value">
|
icon="add_circle"
|
||||||
</vn-textfield>
|
ng-click="$ctrl.filter.tags.push({})">
|
||||||
<vn-autocomplete
|
</vn-icon-button>
|
||||||
vn-one
|
</vn-horizontal>
|
||||||
ng-show="tag.selection.isFree === false"
|
<vn-horizontal class="tags horizontal" ng-repeat="itemTag in $ctrl.filter.tags">
|
||||||
url="{{'Tags/' + itemTag.tagFk + '/filterValue'}}"
|
<vn-autocomplete
|
||||||
search-function="{value: $search}"
|
vn-id="tag"
|
||||||
label="Value"
|
data="$ctrl.tags"
|
||||||
ng-model="itemTag.value"
|
ng-model="itemTag.tagFk"
|
||||||
show-field="value"
|
show-field="name"
|
||||||
value-field="value"
|
label="Tag"
|
||||||
rule>
|
on-change="itemTag.value = null">
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
<vn-icon-button
|
<vn-textfield
|
||||||
vn-none
|
ng-show="tag.selection.isFree || tag.selection.isFree == undefined"
|
||||||
vn-tooltip="Remove tag"
|
label="Value"
|
||||||
icon="delete"
|
ng-model="itemTag.value"
|
||||||
ng-click="filter.tags.splice($index, 1)"
|
ng-keydown="$ctrl.onKeyPress($event)">
|
||||||
tabindex="-1">
|
</vn-textfield>
|
||||||
</vn-icon-button>
|
<vn-autocomplete
|
||||||
</vn-horizontal>
|
ng-show="tag.selection.isFree === false"
|
||||||
<vn-horizontal class="vn-pt-sm">
|
url="{{'Tags/' + itemTag.tagFk + '/filterValue'}}"
|
||||||
<vn-one class="text-subtitle1" translate>
|
search-function="{value: $search}"
|
||||||
More fields
|
label="Value"
|
||||||
</vn-one>
|
ng-model="itemTag.value"
|
||||||
<vn-icon-button
|
show-field="value"
|
||||||
vn-none
|
value-field="value"
|
||||||
vn-bind="+"
|
on-change="$ctrl.applyFilters()">
|
||||||
vn-tooltip="Add field"
|
</vn-autocomplete>
|
||||||
icon="add_circle"
|
<vn-icon-button
|
||||||
ng-click="$ctrl.fieldFilters.push({})">
|
vn-none
|
||||||
</vn-icon-button>
|
vn-tooltip="Remove tag"
|
||||||
</vn-horizontal>
|
icon="delete"
|
||||||
<vn-horizontal ng-repeat="fieldFilter in $ctrl.fieldFilters">
|
ng-click="$ctrl.removeTag(itemTag)">
|
||||||
<vn-autocomplete
|
</vn-icon-button>
|
||||||
label="Field"
|
</vn-horizontal>
|
||||||
ng-model="fieldFilter.name"
|
<div class="chips">
|
||||||
data="$ctrl.moreFields"
|
<vn-chip
|
||||||
value-field="name"
|
ng-if="$ctrl.filter.search"
|
||||||
show-field="label"
|
removable="true"
|
||||||
show-filter="false"
|
vn-tooltip="Item id/name"
|
||||||
translate-fields="['label']"
|
on-remove="$ctrl.removeItemFilter('search')"
|
||||||
selection="info"
|
class="colored">
|
||||||
on-change="fieldFilter.value = null">
|
<span>Id/Name: {{$ctrl.filter.search}}</span>
|
||||||
</vn-autocomplete>
|
</vn-chip>
|
||||||
<vn-one ng-switch="info.type">
|
<vn-chip
|
||||||
<div ng-switch-when="Number">
|
ng-if="category.selection"
|
||||||
<vn-input-number
|
removable="true"
|
||||||
label="Value"
|
vn-tooltip="Category"
|
||||||
ng-model="fieldFilter.value">
|
on-remove="$ctrl.removeItemFilter('categoryFk')"
|
||||||
</vn-input-number>
|
class="colored">
|
||||||
</div>
|
<span>{{category.selection.name}}</span>
|
||||||
<div ng-switch-when="Boolean">
|
</vn-chip>
|
||||||
<vn-check
|
<vn-chip
|
||||||
label="Value"
|
ng-if="type.selection"
|
||||||
ng-model="fieldFilter.value">
|
removable="true"
|
||||||
</vn-check>
|
vn-tooltip="Type"
|
||||||
</div>
|
on-remove="$ctrl.removeItemFilter('typeFk')"
|
||||||
<div ng-switch-when="Date">
|
class="colored">
|
||||||
<vn-date-picker
|
<span>{{type.selection.name}}</span>
|
||||||
label="Value"
|
</vn-chip>
|
||||||
ng-model="fieldFilter.value">
|
<vn-chip
|
||||||
</vn-date-picker>
|
ng-if="salesPerson.selection"
|
||||||
</div>
|
removable="true"
|
||||||
<div ng-switch-default>
|
vn-tooltip="Sales person"
|
||||||
<vn-textfield
|
on-remove="$ctrl.removeItemFilter('salesPersonFk')"
|
||||||
label="Value"
|
class="colored">
|
||||||
ng-model="fieldFilter.value">
|
<span>Sales person: {{salesPerson.selection.nickname}}</span>
|
||||||
</vn-textfield>
|
</vn-chip>
|
||||||
</div>
|
<vn-chip
|
||||||
</vn-one>
|
ng-if="supplier.selection"
|
||||||
<vn-icon-button
|
removable="true"
|
||||||
vn-none
|
vn-tooltip="Supplier"
|
||||||
vn-tooltip="Remove field"
|
on-remove="$ctrl.removeItemFilter('supplierFk')"
|
||||||
icon="delete"
|
class="colored">
|
||||||
ng-click="$ctrl.removeField($index, fieldFilter.name)"
|
<span>Supplier: {{supplier.selection.name}}</span>
|
||||||
tabindex="-1">
|
</vn-chip>
|
||||||
</vn-icon-button>
|
<vn-chip
|
||||||
</vn-horizontal>
|
ng-if="$ctrl.filter.from"
|
||||||
<vn-horizontal class="vn-mt-lg">
|
removable="true"
|
||||||
<vn-submit label="Search"></vn-submit>
|
vn-tooltip="From date"
|
||||||
</vn-horizontal>
|
on-remove="$ctrl.removeItemFilter('from')"
|
||||||
</form>
|
class="colored">
|
||||||
</div>
|
<span>From: {{$ctrl.filter.from | date:'dd/MM/yyyy'}}</span>
|
||||||
|
</vn-chip>
|
||||||
|
<vn-chip
|
||||||
|
ng-if="$ctrl.filter.to"
|
||||||
|
removable="true"
|
||||||
|
vn-tooltip="To date"
|
||||||
|
on-remove="$ctrl.removeItemFilter('to')"
|
||||||
|
class="colored">
|
||||||
|
<span>To: {{$ctrl.filter.to | date:'dd/MM/yyyy'}}</span>
|
||||||
|
</vn-chip>
|
||||||
|
<vn-chip
|
||||||
|
ng-if="$ctrl.filter.active != null"
|
||||||
|
removable="true"
|
||||||
|
vn-tooltip="Active"
|
||||||
|
on-remove="$ctrl.removeItemFilter('active')"
|
||||||
|
class="colored">
|
||||||
|
<span>Active: {{$ctrl.filter.active ? '✓' : '✗'}}</span>
|
||||||
|
</vn-chip>
|
||||||
|
<vn-chip
|
||||||
|
ng-if="$ctrl.filter.floramondo != null"
|
||||||
|
removable="true"
|
||||||
|
vn-tooltip="Floramondo"
|
||||||
|
on-remove="$ctrl.removeItemFilter('floramondo')"
|
||||||
|
class="colored">
|
||||||
|
<span>Floramondo: {{$ctrl.filter.floramondo ? '✓' : '✗'}}</span>
|
||||||
|
</vn-chip>
|
||||||
|
<vn-chip
|
||||||
|
ng-if="$ctrl.filter.visible != null"
|
||||||
|
removable="true"
|
||||||
|
vn-tooltip="Visible"
|
||||||
|
on-remove="$ctrl.removeItemFilter('visible')"
|
||||||
|
class="colored">
|
||||||
|
<span>Visible: {{$ctrl.filter.visible ? '✓' : '✗'}}</span>
|
||||||
|
</vn-chip>
|
||||||
|
<vn-chip
|
||||||
|
ng-repeat="chipTag in $ctrl.filter.tags"
|
||||||
|
removable="true"
|
||||||
|
vn-tooltip="Tag"
|
||||||
|
on-remove="$ctrl.removeTag(chipTag)"
|
||||||
|
class="colored"
|
||||||
|
ng-if="chipTag.value">
|
||||||
|
<span>{{$ctrl.showTagInfo(chipTag)}}</span>
|
||||||
|
</vn-chip>
|
||||||
|
</vn-chip>
|
||||||
|
</div>
|
||||||
|
</vn-side-menu>
|
||||||
|
|
|
@ -1,67 +1,61 @@
|
||||||
import ngModule from '../module';
|
import ngModule from '../module';
|
||||||
import SearchPanel from 'core/components/searchbar/search-panel';
|
import SearchPanel from 'core/components/searchbar/search-panel';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
class Controller extends SearchPanel {
|
class Controller extends SearchPanel {
|
||||||
constructor($element, $) {
|
constructor($element, $) {
|
||||||
super($element, $);
|
super($element, $);
|
||||||
let model = 'Item';
|
}
|
||||||
let moreFields = ['description', 'name'];
|
|
||||||
|
|
||||||
let properties;
|
$onInit() {
|
||||||
let validations = window.validations;
|
this.filter = {
|
||||||
|
isActive: true,
|
||||||
|
tags: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (validations && validations[model])
|
changeCategory(id) {
|
||||||
properties = validations[model].properties;
|
if (this.filter.categoryFk != id) {
|
||||||
else
|
this.filter.categoryFk = id;
|
||||||
properties = {};
|
this.applyFilters();
|
||||||
|
|
||||||
this.moreFields = [];
|
|
||||||
for (let field of moreFields) {
|
|
||||||
let prop = properties[field];
|
|
||||||
this.moreFields.push({
|
|
||||||
name: field,
|
|
||||||
label: prop ? prop.description : field,
|
|
||||||
type: prop ? prop.type : null
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get filter() {
|
removeItemFilter(param) {
|
||||||
let filter = this.$.filter;
|
this.filter[param] = null;
|
||||||
|
if (param == 'categoryFk') this.filter['typeFk'] = null;
|
||||||
for (let fieldFilter of this.fieldFilters)
|
this.applyFilters();
|
||||||
filter[fieldFilter.name] = fieldFilter.value;
|
|
||||||
|
|
||||||
return filter;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set filter(value) {
|
removeTag(tag) {
|
||||||
if (!value)
|
const index = this.filter.tags.indexOf(tag);
|
||||||
value = {};
|
if (index > -1) this.filter.tags.splice(index, 1);
|
||||||
if (!value.tags)
|
this.applyFilters();
|
||||||
value.tags = [{}];
|
}
|
||||||
|
|
||||||
this.fieldFilters = [];
|
onKeyPress($event) {
|
||||||
for (let field of this.moreFields) {
|
if ($event.key === 'Enter')
|
||||||
if (value[field.name] != undefined) {
|
this.applyFilters();
|
||||||
this.fieldFilters.push({
|
}
|
||||||
name: field.name,
|
|
||||||
value: value[field.name],
|
applyFilters() {
|
||||||
info: field
|
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.applyFilter({}, this.filter);
|
||||||
this.$.filter = value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
removeField(index, field) {
|
showTagInfo(itemTag) {
|
||||||
this.fieldFilters.splice(index, 1);
|
if (!itemTag.tagFk) return itemTag.value;
|
||||||
delete this.$.filter[field];
|
return `${this.tags.find(tag => tag.id == itemTag.tagFk).name}: ${itemTag.value}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngModule.component('vnLatestBuysSearchPanel', {
|
ngModule.component('vnLatestBuysSearchPanel', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
controller: Controller
|
controller: Controller,
|
||||||
|
bindings: {
|
||||||
|
model: '<'
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,50 +10,46 @@ describe('Entry', () => {
|
||||||
beforeEach(angular.mock.inject($componentController => {
|
beforeEach(angular.mock.inject($componentController => {
|
||||||
$element = angular.element(`<vn-latest-buys-search-panel></vn-latest-buys-search-panel>`);
|
$element = angular.element(`<vn-latest-buys-search-panel></vn-latest-buys-search-panel>`);
|
||||||
controller = $componentController('vnLatestBuysSearchPanel', {$element});
|
controller = $componentController('vnLatestBuysSearchPanel', {$element});
|
||||||
|
controller.model = {applyFilter: () => {}};
|
||||||
}));
|
}));
|
||||||
|
|
||||||
describe('filter() setter', () => {
|
describe('removeItemFilter()', () => {
|
||||||
it(`should set the tags property to the scope filter with an empty array`, () => {
|
it(`should remove param from filter`, () => {
|
||||||
const expectedFilter = {
|
controller.filter = {tags: [], categoryFk: 1, typeFk: 1};
|
||||||
tags: [{}]
|
const expectFilter = {tags: [], categoryFk: null, typeFk: null};
|
||||||
};
|
|
||||||
controller.filter = null;
|
|
||||||
|
|
||||||
expect(controller.filter).toEqual(expectedFilter);
|
controller.removeItemFilter('categoryFk');
|
||||||
});
|
|
||||||
|
|
||||||
it(`should set the tags property to the scope filter with an array of tags`, () => {
|
expect(controller.filter).toEqual(expectFilter);
|
||||||
const expectedFilter = {
|
|
||||||
description: 'My item',
|
|
||||||
tags: [{}]
|
|
||||||
};
|
|
||||||
const expectedFieldFilter = [{
|
|
||||||
info: {
|
|
||||||
label: 'description',
|
|
||||||
name: 'description',
|
|
||||||
type: null
|
|
||||||
},
|
|
||||||
name: 'description',
|
|
||||||
value: 'My item'
|
|
||||||
}];
|
|
||||||
controller.filter = {
|
|
||||||
description: 'My item'
|
|
||||||
};
|
|
||||||
|
|
||||||
expect(controller.filter).toEqual(expectedFilter);
|
|
||||||
expect(controller.fieldFilters).toEqual(expectedFieldFilter);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('removeField()', () => {
|
describe('removeTag()', () => {
|
||||||
it(`should remove the description property from the fieldFilters and from the scope filter`, () => {
|
it(`should remove tag from filter`, () => {
|
||||||
const expectedFilter = {tags: [{}]};
|
const tag = {tagFk: 1, value: 'Value'};
|
||||||
controller.filter = {description: 'My item'};
|
controller.filter = {tags: [tag]};
|
||||||
|
const expectFilter = {tags: []};
|
||||||
|
|
||||||
controller.removeField(0, 'description');
|
controller.removeTag(tag);
|
||||||
|
|
||||||
expect(controller.filter).toEqual(expectedFilter);
|
expect(controller.filter).toEqual(expectFilter);
|
||||||
expect(controller.fieldFilters).toEqual([]);
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
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');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
|
vn-latest-buys-search-panel vn-side-menu div {
|
||||||
|
& > .input {
|
||||||
|
padding-left: $spacing-md;
|
||||||
|
padding-right: $spacing-md;
|
||||||
|
border-color: $color-spacer;
|
||||||
|
border-bottom: $border-thin;
|
||||||
|
}
|
||||||
|
& > .horizontal {
|
||||||
|
grid-auto-flow: column;
|
||||||
|
grid-column-gap: $spacing-sm;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
& > .checks {
|
||||||
|
padding: $spacing-md;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
border-color: $color-spacer;
|
||||||
|
border-bottom: $border-thin;
|
||||||
|
}
|
||||||
|
& > .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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,17 +7,11 @@
|
||||||
on-data-change="$ctrl.reCheck()"
|
on-data-change="$ctrl.reCheck()"
|
||||||
auto-load="true">
|
auto-load="true">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<vn-portal slot="topbar">
|
<vn-portal slot="topbar">
|
||||||
<vn-searchbar
|
|
||||||
vn-focus
|
|
||||||
panel="vn-latest-buys-search-panel"
|
|
||||||
placeholder="Search by item id or name"
|
|
||||||
info="You can search by item id or name"
|
|
||||||
suggested-filter="{isActive: true}"
|
|
||||||
model="model"
|
|
||||||
auto-state="false">
|
|
||||||
</vn-searchbar>
|
|
||||||
</vn-portal>
|
</vn-portal>
|
||||||
|
<vn-latest-buys-search-panel
|
||||||
|
model="model">
|
||||||
|
</vn-latest-buys-search-panel>
|
||||||
<vn-card>
|
<vn-card>
|
||||||
<smart-table
|
<smart-table
|
||||||
model="model"
|
model="model"
|
||||||
|
@ -261,7 +255,7 @@
|
||||||
</tpl-body>
|
</tpl-body>
|
||||||
<tpl-buttons>
|
<tpl-buttons>
|
||||||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
||||||
<button response="accept" translate>Create</button>
|
<button response="accept" translate>Save</button>
|
||||||
</tpl-buttons>
|
</tpl-buttons>
|
||||||
</vn-dialog>
|
</vn-dialog>
|
||||||
<vn-item-descriptor-popover
|
<vn-item-descriptor-popover
|
||||||
|
|
Loading…
Reference in New Issue