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

Reviewed-on: #1298
Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
This commit is contained in:
Alexandre Riera 2023-02-06 06:42:06 +00:00
commit b5b2e429e5
7 changed files with 488 additions and 288 deletions

View File

@ -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"]',

View File

@ -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);

View File

@ -1,121 +1,137 @@
<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
ng-keydown="$ctrl.onKeyPress($event)">
</vn-textfield> </vn-textfield>
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-horizontal class="item-category">
<vn-autocomplete <vn-autocomplete
vn-focus vn-id="category"
url="ItemCategories" data="$ctrl.categories"
label="Category" ng-model="$ctrl.filter.categoryFk"
show-field="name" show-field="name"
value-field="id" value-field="id"
ng-model="filter.categoryFk"> label="Category">
</vn-autocomplete> </vn-autocomplete>
<vn-one ng-repeat="category in $ctrl.categories">
<vn-icon
ng-class="{'active': $ctrl.filter.categoryFk == category.id}"
icon="{{::category.icon}}"
vn-tooltip="{{::category.name}}"
ng-click="$ctrl.changeCategory(category.id)">
</vn-icon>
</vn-one>
</vn-horizontal>
<vn-vertical class="input">
<vn-autocomplete <vn-autocomplete
vn-id="type"
disabled="!$ctrl.filter.categoryFk"
url="ItemTypes" url="ItemTypes"
label="Type" label="Type"
where="{categoryFk: filter.categoryFk}" where="{categoryFk: $ctrl.filter.categoryFk}"
show-field="name" show-field="name"
value-field="id" value-field="id"
ng-model="filter.typeFk" ng-model="$ctrl.filter.typeFk"
fields="['categoryFk']" fields="['categoryFk']"
include="'category'"> include="'category'"
on-change="$ctrl.applyFilters()">
<tpl-item> <tpl-item>
<div>{{name}}</div> <div>{{name}}</div>
<div class="text-caption text-secondary"> <div class="text-caption text-secondary">
{{category.name}} {{category.name}}
</div> </div> </tpl-item
</tpl-item>> >>
</vn-autocomplete> </vn-autocomplete>
</vn-horizontal> </vn-vertical>
<vn-horizontal> <vn-horizontal class="input horizontal">
<vn-autocomplete <vn-autocomplete
vn-id="salesPerson"
disabled="false" disabled="false"
ng-model="filter.salesPersonFk" ng-model="$ctrl.filter.salesPersonFk"
url="Workers/activeWithRole" url="Workers/activeWithRole"
show-field="nickname" show-field="nickname"
search-function="{firstName: $search}" search-function="{firstName: $search}"
value-field="id" value-field="id"
where="{role: {inq: ['logistic', 'buyer']}}" where="{role: {inq: ['logistic', 'buyer']}}"
label="Buyer"> label="Buyer"
on-change="$ctrl.applyFilters()">
</vn-autocomplete> </vn-autocomplete>
<vn-autocomplete <vn-autocomplete
vn-one vn-id="supplier"
label="Supplier" label="Supplier"
ng-model="filter.supplierFk" ng-model="$ctrl.filter.supplierFk"
url="Suppliers" url="Suppliers"
fields="['name','nickname']" fields="['name','nickname']"
search-function="{or: [{nickname: {like: '%'+ $search +'%'}}, {name: {like: '%'+ $search +'%'}}]}" search-function="{or: [{nickname: {like: '%'+ $search +'%'}}, {name: {like: '%'+ $search +'%'}}]}"
show-field="name" show-field="name"
value-field="id"> value-field="id"
on-change="$ctrl.applyFilters()">
<tpl-item>{{name}}: {{nickname}}</tpl-item> <tpl-item>{{name}}: {{nickname}}</tpl-item>
</vn-autocomplete> </vn-autocomplete>
</vn-horizontal> </vn-horizontal>
<vn-horizontal> <vn-vertical class="input">
<vn-date-picker <vn-date-picker
vn-one
label="From" label="From"
ng-model="filter.from"> ng-model="$ctrl.filter.from"
on-change="$ctrl.applyFilters()">
</vn-date-picker> </vn-date-picker>
<vn-date-picker <vn-date-picker
vn-one
label="To" label="To"
ng-model="filter.to"> ng-model="$ctrl.filter.to"
on-change="$ctrl.applyFilters()">
</vn-date-picker> </vn-date-picker>
</vn-horizontal> </vn-vertical>
<vn-horizontal> <vn-horizontal class="checks">
<vn-check <vn-check
label="Is active" label="Is active"
ng-model="filter.active" ng-model="$ctrl.filter.active"
triple-state="true"> triple-state="true"
ng-click="$ctrl.applyFilters()">
</vn-check> </vn-check>
<vn-check <vn-check
label="Is visible" label="Is visible"
ng-model="filter.visible" ng-model="$ctrl.filter.visible"
triple-state="true"> triple-state="true"
ng-click="$ctrl.applyFilters()">
</vn-check> </vn-check>
<vn-check <vn-check
label="Is floramondo" label="Is floramondo"
ng-model="filter.floramondo" ng-model="$ctrl.filter.floramondo"
triple-state="true"> triple-state="true"
ng-click="$ctrl.applyFilters()">
</vn-check> </vn-check>
</vn-horizontal> </vn-horizontal>
<vn-horizontal class="vn-pt-sm"> <vn-horizontal class="tags">
<vn-one class="text-subtitle1" translate> <vn-one class="text-subtitle1" translate> Tags </vn-one>
Tags
</vn-one>
<vn-icon-button <vn-icon-button
vn-none vn-none
vn-bind="+"
vn-tooltip="Add tag" vn-tooltip="Add tag"
icon="add_circle" icon="add_circle"
ng-click="filter.tags.push({})"> ng-click="$ctrl.filter.tags.push({})">
</vn-icon-button> </vn-icon-button>
</vn-horizontal> </vn-horizontal>
<vn-horizontal ng-repeat="itemTag in filter.tags"> <vn-horizontal class="tags horizontal" ng-repeat="itemTag in $ctrl.filter.tags">
<vn-autocomplete <vn-autocomplete
vn-id="tag" vn-id="tag"
data="$ctrl.tags"
ng-model="itemTag.tagFk" ng-model="itemTag.tagFk"
data="tags.model"
show-field="name" show-field="name"
label="Tag" label="Tag"
on-change="itemTag.value = null"> on-change="itemTag.value = null">
</vn-autocomplete> </vn-autocomplete>
<vn-textfield <vn-textfield
ng-show="tag.selection.isFree || tag.selection.isFree == undefined" ng-show="tag.selection.isFree || tag.selection.isFree == undefined"
vn-id="text"
label="Value" label="Value"
ng-model="itemTag.value"> ng-model="itemTag.value"
ng-keydown="$ctrl.onKeyPress($event)">
</vn-textfield> </vn-textfield>
<vn-autocomplete <vn-autocomplete
vn-one
ng-show="tag.selection.isFree === false" ng-show="tag.selection.isFree === false"
url="{{'Tags/' + itemTag.tagFk + '/filterValue'}}" url="{{'Tags/' + itemTag.tagFk + '/filterValue'}}"
search-function="{value: $search}" search-function="{value: $search}"
@ -123,76 +139,105 @@
ng-model="itemTag.value" ng-model="itemTag.value"
show-field="value" show-field="value"
value-field="value" value-field="value"
rule> on-change="$ctrl.applyFilters()">
</vn-autocomplete> </vn-autocomplete>
<vn-icon-button <vn-icon-button
vn-none vn-none
vn-tooltip="Remove tag" vn-tooltip="Remove tag"
icon="delete" icon="delete"
ng-click="filter.tags.splice($index, 1)" ng-click="$ctrl.removeTag(itemTag)">
tabindex="-1">
</vn-icon-button> </vn-icon-button>
</vn-horizontal> </vn-horizontal>
<vn-horizontal class="vn-pt-sm"> <div class="chips">
<vn-one class="text-subtitle1" translate> <vn-chip
More fields ng-if="$ctrl.filter.search"
</vn-one> removable="true"
<vn-icon-button vn-tooltip="Item id/name"
vn-none on-remove="$ctrl.removeItemFilter('search')"
vn-bind="+" class="colored">
vn-tooltip="Add field" <span>Id/Name: {{$ctrl.filter.search}}</span>
icon="add_circle" </vn-chip>
ng-click="$ctrl.fieldFilters.push({})"> <vn-chip
</vn-icon-button> ng-if="category.selection"
</vn-horizontal> removable="true"
<vn-horizontal ng-repeat="fieldFilter in $ctrl.fieldFilters"> vn-tooltip="Category"
<vn-autocomplete on-remove="$ctrl.removeItemFilter('categoryFk')"
label="Field" class="colored">
ng-model="fieldFilter.name" <span>{{category.selection.name}}</span>
data="$ctrl.moreFields" </vn-chip>
value-field="name" <vn-chip
show-field="label" ng-if="type.selection"
show-filter="false" removable="true"
translate-fields="['label']" vn-tooltip="Type"
selection="info" on-remove="$ctrl.removeItemFilter('typeFk')"
on-change="fieldFilter.value = null"> class="colored">
</vn-autocomplete> <span>{{type.selection.name}}</span>
<vn-one ng-switch="info.type"> </vn-chip>
<div ng-switch-when="Number"> <vn-chip
<vn-input-number ng-if="salesPerson.selection"
label="Value" removable="true"
ng-model="fieldFilter.value"> vn-tooltip="Sales person"
</vn-input-number> on-remove="$ctrl.removeItemFilter('salesPersonFk')"
class="colored">
<span>Sales person: {{salesPerson.selection.nickname}}</span>
</vn-chip>
<vn-chip
ng-if="supplier.selection"
removable="true"
vn-tooltip="Supplier"
on-remove="$ctrl.removeItemFilter('supplierFk')"
class="colored">
<span>Supplier: {{supplier.selection.name}}</span>
</vn-chip>
<vn-chip
ng-if="$ctrl.filter.from"
removable="true"
vn-tooltip="From date"
on-remove="$ctrl.removeItemFilter('from')"
class="colored">
<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> </div>
<div ng-switch-when="Boolean"> </vn-side-menu>
<vn-check
label="Value"
ng-model="fieldFilter.value">
</vn-check>
</div>
<div ng-switch-when="Date">
<vn-date-picker
label="Value"
ng-model="fieldFilter.value">
</vn-date-picker>
</div>
<div ng-switch-default>
<vn-textfield
label="Value"
ng-model="fieldFilter.value">
</vn-textfield>
</div>
</vn-one>
<vn-icon-button
vn-none
vn-tooltip="Remove field"
icon="delete"
ng-click="$ctrl.removeField($index, fieldFilter.name)"
tabindex="-1">
</vn-icon-button>
</vn-horizontal>
<vn-horizontal class="vn-mt-lg">
<vn-submit label="Search"></vn-submit>
</vn-horizontal>
</form>
</div>

View File

@ -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 = [];
for (let field of this.moreFields) {
if (value[field.name] != undefined) {
this.fieldFilters.push({
name: field.name,
value: value[field.name],
info: field
});
}
} }
this.$.filter = value; onKeyPress($event) {
if ($event.key === 'Enter')
this.applyFilters();
} }
removeField(index, field) { applyFilters() {
this.fieldFilters.splice(index, 1); for (let i = 0; i < this.filter.tags.length; i++) {
delete this.$.filter[field]; if (!this.filter.tags[i].value)
this.filter.tags.splice(i, 1);
}
return this.model.applyFilter({}, this.filter);
}
showTagInfo(itemTag) {
if (!itemTag.tagFk) return itemTag.value;
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: '<'
}
}); });

View File

@ -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');
}); });
}); });
}); });

View File

@ -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;
}
}
}
}
}

View File

@ -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