fixes #5206 travel buscador en el lateral #1384

Merged
joan merged 11 commits from 5206-travel-buscadorLateral into dev 2023-03-30 05:21:26 +00:00
22 changed files with 390 additions and 335 deletions

View File

@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Changed ### Changed
- (Envíos -> Extra comunitarios) Se agrupan las entradas del mismo travel. Añadidos campos Referencia y Importe. - (Envíos -> Extra comunitarios) Se agrupan las entradas del mismo travel. Añadidos campos Referencia y Importe.
- (Envíos -> Índice) Cambiado el buscador superior por uno lateral
### Fixed ### Fixed
- -

View File

@ -1138,7 +1138,16 @@ export default {
landingDate: 'vn-travel-create vn-date-picker[ng-model="$ctrl.travel.landed"]', landingDate: 'vn-travel-create vn-date-picker[ng-model="$ctrl.travel.landed"]',
warehouseOut: 'vn-travel-create vn-autocomplete[ng-model="$ctrl.travel.warehouseOutFk"]', warehouseOut: 'vn-travel-create vn-autocomplete[ng-model="$ctrl.travel.warehouseOutFk"]',
warehouseIn: 'vn-travel-create vn-autocomplete[ng-model="$ctrl.travel.warehouseInFk"]', warehouseIn: 'vn-travel-create vn-autocomplete[ng-model="$ctrl.travel.warehouseInFk"]',
save: 'vn-travel-create vn-submit > button' save: 'vn-travel-create vn-submit > button',
generalSearchFilter: 'vn-travel-search-panel vn-textfield[ng-model="$ctrl.search"]',
agencyFilter: 'vn-travel-search-panel vn-autocomplete[ng-model="$ctrl.filter.agencyModeFk"]',
warehouseOutFilter: 'vn-travel-search-panel vn-autocomplete[ng-model="$ctrl.filter.warehouseOutFk"]',
warehouseInFilter: 'vn-travel-search-panel vn-autocomplete[ng-model="$ctrl.filter.warehouseInFk"]',
scopeDaysFilter: 'vn-travel-search-panel vn-input-number[ng-model="$ctrl.filter.scopeDays"]',
continentFilter: 'vn-travel-search-panel vn-autocomplete[ng-model="$ctrl.filter.continent"]',
totalEntriesFilter: 'vn-travel-search-panel vn-input-number[ng-model="$ctrl.totalEntries"]',
chip: 'vn-travel-search-panel vn-chip > vn-icon',
}, },
travelExtraCommunity: { travelExtraCommunity: {
anySearchResult: 'vn-travel-extra-community > vn-card div > tbody > tr[ng-attr-id="{{::travel.id}}"]', anySearchResult: 'vn-travel-extra-community > vn-card div > tbody > tr[ng-attr-id="{{::travel.id}}"]',

View File

@ -9,7 +9,8 @@ describe('Travel basic data path', () => {
browser = await getBrowser(); browser = await getBrowser();
page = browser.page; page = browser.page;
await page.loginAndModule('buyer', 'travel'); await page.loginAndModule('buyer', 'travel');
await page.accessToSearchResult('3'); await page.write(selectors.travelIndex.generalSearchFilter, '3');
await page.keyboard.press('Enter');
await page.accessToSection('travel.card.basicData'); await page.accessToSection('travel.card.basicData');
}); });

View File

@ -9,7 +9,8 @@ describe('Travel descriptor path', () => {
browser = await getBrowser(); browser = await getBrowser();
page = browser.page; page = browser.page;
await page.loginAndModule('buyer', 'travel'); await page.loginAndModule('buyer', 'travel');
await page.accessToSearchResult('1'); await page.write(selectors.travelIndex.generalSearchFilter, '1');
Review

També desapareix la barra de búsqueda general, aso es lo que es vol fer? No es pot buscar desde dins de la entitat

També desapareix la barra de búsqueda general, aso es lo que es vol fer? No es pot buscar desde dins de la entitat
Review

Me varen dir que ho posara tot el en el buscador de la dreta, encara aixina també vaig implementar per a que si al filtrar te troba un únic resultat que te redirigixca a ell

Me varen dir que ho posara tot el en el buscador de la dreta, encara aixina també vaig implementar per a que si al filtrar te troba un únic resultat que te redirigixca a ell
await page.keyboard.press('Enter');
await page.waitForState('travel.card.summary'); await page.waitForState('travel.card.summary');
}); });
@ -81,7 +82,8 @@ describe('Travel descriptor path', () => {
await page.waitToClick('.cancel'); await page.waitToClick('.cancel');
await page.waitToClick(selectors.globalItems.homeButton); await page.waitToClick(selectors.globalItems.homeButton);
await page.selectModule('travel'); await page.selectModule('travel');
await page.accessToSearchResult('3'); await page.write(selectors.travelIndex.generalSearchFilter, '3');
await page.keyboard.press('Enter');
await page.waitForState('travel.card.summary'); await page.waitForState('travel.card.summary');
const state = await page.getState(); const state = await page.getState();

View File

@ -10,7 +10,8 @@ describe('Travel thermograph path', () => {
browser = await getBrowser(); browser = await getBrowser();
page = browser.page; page = browser.page;
await page.loginAndModule('buyer', 'travel'); await page.loginAndModule('buyer', 'travel');
await page.accessToSearchResult('3'); await page.write(selectors.travelIndex.generalSearchFilter, '3');
await page.keyboard.press('Enter');
await page.accessToSection('travel.card.thermograph.index'); await page.accessToSection('travel.card.thermograph.index');
}); });

View File

@ -0,0 +1,62 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Travel search panel path', () => {
let browser;
let page;
let httpRequest;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('buyer', 'travel');
page.on('request', req => {
if (req.url().includes(`Travels/filter`))
httpRequest = req.url();
});
});
afterAll(async() => {
await browser.close();
});
it('should filter using all the fields', async() => {
await page.click(selectors.travelIndex.chip);
await page.write(selectors.travelIndex.generalSearchFilter, 'travel');
await page.keyboard.press('Enter');
expect(httpRequest).toContain('search=travel');
await page.click(selectors.travelIndex.chip);
await page.autocompleteSearch(selectors.travelIndex.agencyFilter, 'Entanglement');
expect(httpRequest).toContain('agencyModeFk');
await page.click(selectors.travelIndex.chip);
await page.autocompleteSearch(selectors.travelIndex.warehouseOutFilter, 'Warehouse One');
expect(httpRequest).toContain('warehouseOutFk');
await page.click(selectors.travelIndex.chip);
await page.autocompleteSearch(selectors.travelIndex.warehouseInFilter, 'Warehouse Two');
expect(httpRequest).toContain('warehouseInFk');
await page.click(selectors.travelIndex.chip);
await page.overwrite(selectors.travelIndex.scopeDaysFilter, '15');
await page.keyboard.press('Enter');
expect(httpRequest).toContain('scopeDays=15');
await page.click(selectors.travelIndex.chip);
await page.autocompleteSearch(selectors.travelIndex.continentFilter, 'Asia');
expect(httpRequest).toContain('continent');
await page.click(selectors.travelIndex.chip);
await page.write(selectors.travelIndex.totalEntriesFilter, '1');
await page.keyboard.press('Enter');
expect(httpRequest).toContain('totalEntries=1');
});
});

View File

@ -26,7 +26,7 @@ Value should have at most %s characters: El valor debe tener un máximo de %s ca
Enter a new search: Introduce una nueva búsqueda Enter a new search: Introduce una nueva búsqueda
No results: Sin resultados No results: Sin resultados
Ups! It seems there was an error: ¡Vaya! Parece que ha habido un error Ups! It seems there was an error: ¡Vaya! Parece que ha habido un error
General search: Busqueda general General search: Búsqueda general
January: Enero January: Enero
February: Febrero February: Febrero
March: Marzo March: Marzo

View File

@ -2,6 +2,7 @@
$font-size: 11pt; $font-size: 11pt;
$menu-width: 256px; $menu-width: 256px;
$right-menu-width: 318px;
$topbar-height: 56px; $topbar-height: 56px;
$mobile-width: 800px; $mobile-width: 800px;
$float-spacing: 20px; $float-spacing: 20px;

View File

@ -88,13 +88,13 @@ vn-layout {
} }
&.right-menu { &.right-menu {
& > vn-topbar > .end { & > vn-topbar > .end {
width: 80px + $menu-width; width: 80px + $right-menu-width;
} }
& > .main-view { & > .main-view {
padding-right: $menu-width; padding-right: $right-menu-width;
} }
[fixed-bottom-right] { [fixed-bottom-right] {
right: $menu-width; right: $right-menu-width;
} }
} }
& > .main-view { & > .main-view {

View File

@ -6,6 +6,6 @@ Phy. KG: KG físico
Vol. KG: KG Vol. Vol. KG: KG Vol.
Search by travel id or reference: Buscar por id de travel o referencia Search by travel id or reference: Buscar por id de travel o referencia
Search by extra community travel: Buscar por envío extra comunitario Search by extra community travel: Buscar por envío extra comunitario
Continent Out: Continente salida Continent Out: Cont. salida
W. Shipped: F. envío W. Shipped: F. envío
W. Landed: F. llegada W. Landed: F. llegada

View File

@ -2,6 +2,15 @@
<vn-auto-search <vn-auto-search
model="model"> model="model">
</vn-auto-search> </vn-auto-search>
<vn-travel-search-panel
model="model">
</vn-travel-search-panel>
<vn-crud-model
vn-id="model"
url="Travels/filter"
limit="20"
order="shipped DESC, landed DESC">
</vn-crud-model>
<vn-data-viewer <vn-data-viewer
model="model" model="model"
class="vn-mb-xl vn-w-xl"> class="vn-mb-xl vn-w-xl">
@ -9,15 +18,15 @@
<vn-table model="model"> <vn-table model="model">
<vn-thead> <vn-thead>
<vn-tr> <vn-tr>
<vn-th field="id" number filter-enabled="false">Id</vn-th>
<vn-th field="ref">Reference</vn-th> <vn-th field="ref">Reference</vn-th>
<vn-th field="agencyModeFk">Agency</vn-th> <vn-th field="agencyModeFk">Agency</vn-th>
<vn-th field="warehouseOutFk">Warehouse Out</vn-th> <vn-th field="warehouseOutFk">Warehouse Out</vn-th>
<vn-th field="shipped" center shrink-date>Shipped</vn-th> <vn-th field="shipped" center shrink-date>Shipped</vn-th>
<vn-th field="isDelivered" center>Delivered</vn-th> <vn-th shrink></vn-th>
<vn-th field="warehouseInFk">Warehouse In</vn-th> <vn-th field="warehouseInFk">Warehouse In</vn-th>
<vn-th field="landed" center shrink-date>Landed</vn-th> <vn-th field="landed" center shrink-date>Landed</vn-th>
<vn-th field="isReceived" center>Received</vn-th> <vn-th shrink></vn-th>
<vn-th shrink field="totalEntries">Total entries</vn-th>
<vn-th shrink></vn-th> <vn-th shrink></vn-th>
</vn-tr> </vn-tr>
</vn-thead> </vn-thead>
@ -25,7 +34,6 @@
<a ng-repeat="travel in model.data" <a ng-repeat="travel in model.data"
class="clickable vn-tr search-result" class="clickable vn-tr search-result"
ui-sref="travel.card.summary({id: {{::travel.id}}})"> ui-sref="travel.card.summary({id: {{::travel.id}}})">
<vn-td number>{{::travel.id}}</vn-td>
<vn-td>{{::travel.ref}}</vn-td> <vn-td>{{::travel.ref}}</vn-td>
<vn-td>{{::travel.agencyModeName}}</vn-td> <vn-td>{{::travel.agencyModeName}}</vn-td>
<vn-td>{{::travel.warehouseOutName}}</vn-td> <vn-td>{{::travel.warehouseOutName}}</vn-td>
@ -34,14 +42,27 @@
{{::travel.shipped | date:'dd/MM/yyyy'}} {{::travel.shipped | date:'dd/MM/yyyy'}}
</span> </span>
</vn-td> </vn-td>
<vn-td center><vn-check ng-model="travel.isDelivered" disabled="true"></vn-check></vn-td> <vn-td shrink>
<vn-icon
icon="flight_takeoff"
translate-attr="{title: 'Delivered'}"
ng-class="{active: travel.isDelivered}">
</vn-icon>
</vn-td>
<vn-td expand>{{::travel.warehouseInName}}</vn-td> <vn-td expand>{{::travel.warehouseInName}}</vn-td>
<vn-td center shrink-date> <vn-td center shrink-date>
<span class="chip {{$ctrl.compareDate(travel.landed)}}"> <span class="chip {{$ctrl.compareDate(travel.landed)}}">
{{::travel.landed | date:'dd/MM/yyyy'}} {{::travel.landed | date:'dd/MM/yyyy'}}
</span> </span>
</vn-td> </vn-td>
<vn-td center><vn-check ng-model="travel.isReceived" disabled="true"></vn-check></vn-td> <vn-td shrink>
<vn-icon
icon="flight_land"
translate-attr="{title: 'Received'}"
ng-class="{active: travel.isReceived}">
</vn-icon>
</vn-td>
<vn-td shrink>{{::travel.totalEntries}}</vn-td>
<vn-td shrink> <vn-td shrink>
<vn-horizontal class="buttons"> <vn-horizontal class="buttons">
<vn-icon-button <vn-icon-button
@ -84,32 +105,3 @@
question="Do you want to clone this travel?" question="Do you want to clone this travel?"
message="All it's properties will be copied"> message="All it's properties will be copied">
</vn-confirm> </vn-confirm>
<vn-contextmenu vn-id="contextmenu" targets="['vn-data-viewer']" model="model"
expr-builder="$ctrl.exprBuilder(param, value)">
<slot-menu>
<vn-item translate
ng-if="contextmenu.isFilterAllowed()"
ng-click="contextmenu.filterBySelection()">
Filter by selection
</vn-item>
<vn-item translate
ng-if="contextmenu.isFilterAllowed()"
ng-click="contextmenu.excludeSelection()">
Exclude selection
</vn-item>
<vn-item translate
ng-if="contextmenu.isFilterAllowed()"
ng-click="contextmenu.removeFilter()">
Remove filter
</vn-item>
<vn-item translate
ng-click="contextmenu.removeAllFilters()" >
Remove all filters
</vn-item>
<vn-item translate
ng-if="contextmenu.isActionAllowed()"
ng-click="contextmenu.copyValue()">
Copy value
</vn-item>
</slot-menu>
</vn-contextmenu>

View File

@ -1,5 +1,6 @@
import ngModule from '../module'; import ngModule from '../module';
import Section from 'salix/components/section'; import Section from 'salix/components/section';
import './style.scss';
export default class Controller extends Section { export default class Controller extends Section {
preview(travel) { preview(travel) {
@ -30,37 +31,6 @@ export default class Controller extends Section {
if (timeDifference == 0) return 'warning'; if (timeDifference == 0) return 'warning';
if (timeDifference < 0) return 'success'; if (timeDifference < 0) return 'success';
} }
exprBuilder(param, value) {
switch (param) {
case 'search':
return /^\d+$/.test(value)
? {'t.id': value}
: {'t.ref': {like: `%${value}%`}};
case 'ref':
return {'t.ref': {like: `%${value}%`}};
case 'shipped':
return {'t.shipped': {between: this.dateRange(value)}};
case 'landed':
return {'t.landed': {between: this.dateRange(value)}};
case 'id':
case 'agencyModeFk':
case 'warehouseOutFk':
case 'warehouseInFk':
case 'totalEntries':
param = `t.${param}`;
return {[param]: value};
}
}
dateRange(value) {
const minHour = new Date(value);
minHour.setHours(0, 0, 0, 0);
const maxHour = new Date(value);
maxHour.setHours(23, 59, 59, 59);
return [minHour, maxHour];
}
} }
ngModule.vnComponent('vnTravelIndex', { ngModule.vnComponent('vnTravelIndex', {

View File

@ -0,0 +1,11 @@
@import "variables";
vn-travel-index {
vn-icon {
color: $color-font-secondary
}
vn-icon.active {
color: $color-success
}
}

View File

@ -1,7 +1,7 @@
#Ordenar alfabeticamente #Ordenar alfabeticamente
Reference: Referencia Reference: Referencia
Warehouse Out: Almacén salida Warehouse Out: Alm salida
Warehouse In: Almacén llegada Warehouse In: Alm llegada
Shipped from: Salida desde Shipped from: Salida desde
Shipped to: Salida hasta Shipped to: Salida hasta
Landed from: Llegada desde Landed from: Llegada desde
@ -10,8 +10,8 @@ Shipped: F. salida
Landed: F. llegada Landed: F. llegada
Delivered: Enviado Delivered: Enviado
Received: Recibido Received: Recibido
Travel id: Id envío Travel id: Id
Search travels by id: Buscar envíos por identificador Search travels by id: Buscar envíos por identificador o referencia
New travel: Nuevo envío New travel: Nuevo envío
travel: envío travel: envío

View File

@ -1,18 +1,4 @@
<vn-crud-model
vn-id="model"
url="Travels/filter"
limit="20"
order="shipped DESC, landed DESC">
</vn-crud-model>
<vn-portal slot="topbar"> <vn-portal slot="topbar">
<vn-searchbar
vn-focus
panel="vn-travel-search-panel"
info="Search travels by id"
model="model"
fetch-params="$ctrl.fetchParams($params)"
suggested-filter="$ctrl.filterParams">
</vn-searchbar>
</vn-portal> </vn-portal>
<vn-portal slot="menu"> <vn-portal slot="menu">
<vn-left-menu></vn-left-menu> <vn-left-menu></vn-left-menu>

View File

@ -4,28 +4,6 @@ import ModuleMain from 'salix/components/module-main';
export default class Travel extends ModuleMain { export default class Travel extends ModuleMain {
constructor() { constructor() {
super(); super();
this.filterParams = {
scopeDays: 1
};
}
fetchParams($params) {
if (!Object.entries($params).length)
$params.scopeDays = 1;
if (typeof $params.scopeDays === 'number') {
const shippedFrom = Date.vnNew();
shippedFrom.setHours(0, 0, 0, 0);
const shippedTo = new Date(shippedFrom.getTime());
shippedTo.setDate(shippedTo.getDate() + $params.scopeDays);
shippedTo.setHours(23, 59, 59, 999);
Object.assign($params, {shippedFrom, shippedTo});
}
return $params;
} }
} }

View File

@ -1,49 +0,0 @@
import './index.js';
describe('Travel Component vnTravel', () => {
let controller;
beforeEach(ngModule('travel'));
beforeEach(inject($componentController => {
let $element = angular.element(`<div></div>`);
controller = $componentController('vnTravel', {$element});
}));
describe('fetchParams()', () => {
it('should return a range of dates with passed scope days', () => {
let params = controller.fetchParams({
scopeDays: 2
});
const shippedFrom = Date.vnNew();
shippedFrom.setHours(0, 0, 0, 0);
const shippedTo = new Date(shippedFrom.getTime());
shippedTo.setDate(shippedTo.getDate() + params.scopeDays);
shippedTo.setHours(23, 59, 59, 999);
const expectedParams = {
shippedFrom,
scopeDays: params.scopeDays,
shippedTo
};
expect(params).toEqual(expectedParams);
});
it('should return default value for scope days', () => {
let params = controller.fetchParams({
scopeDays: 1
});
expect(params.scopeDays).toEqual(1);
});
it('should return the given scope days', () => {
let params = controller.fetchParams({
scopeDays: 2
});
expect(params.scopeDays).toEqual(2);
});
});
});

View File

@ -1,109 +1,146 @@
<div class="search-panel"> <vn-side-menu side="right">
<form ng-submit="$ctrl.onSearch()" id="manifold-form"> <vn-horizontal class="input">
<vn-horizontal class="vn-px-lg vn-pt-lg"> <vn-textfield
<vn-textfield label="General search"
vn-one info="Search travels by id"
label="General search" ng-model="$ctrl.search"
ng-model="filter.search" ng-keydown="$ctrl.onKeyPress($event, 'search')">
info="Search travels by id" </vn-textfield>
vn-focus> </vn-horizontal>
</vn-textfield> <vn-horizontal class="input horizontal">
</vn-horizontal> <vn-autocomplete
<vn-horizontal class="vn-px-lg"> vn-id="agency"
<vn-textfield label="Agency"
vn-one ng-model="$ctrl.filter.agencyModeFk"
label="Reference" data="$ctrl.agencyModes"
ng-model="filter.ref"> show-field="name"
</vn-textfield> value-field="id"
<vn-textfield on-change="$ctrl.applyFilters()">
vn-one </vn-autocomplete>
label="Total entries" </vn-horizontal>
ng-model="filter.totalEntries"> <vn-horizontal class="input horizontal">
</vn-textfield> <vn-autocomplete
</vn-horizontal> vn-id="warehouseOut"
<vn-horizontal class="vn-px-lg"> label="Warehouse Out"
<vn-textfield ng-model="$ctrl.filter.warehouseOutFk"
vn-one data="$ctrl.warehouses"
label="Travel id" show-field="name"
ng-model="filter.id"> value-field="id"
</vn-textfield> on-change="$ctrl.applyFilters()">
<vn-autocomplete vn-one </vn-autocomplete>
label="Agency" <vn-autocomplete
ng-model="filter.agencyModeFk" vn-id="warehouseIn"
url="AgencyModes" label="Warehouse In"
show-field="name" ng-model="$ctrl.filter.warehouseInFk"
value-field="id"> data="$ctrl.warehouses"
</vn-autocomplete> show-field="name"
</vn-horizontal> value-field="id"
<section class="vn-px-md"> on-change="$ctrl.applyFilters()">
<vn-horizontal class="manifold-panel vn-pa-md"> </vn-autocomplete>
<vn-date-picker </vn-horizontal>
vn-one <vn-horizontal class="input horizontal">
label="Shipped from" <vn-input-number
ng-model="filter.shippedFrom" min="0"
on-change="$ctrl.shippedFrom = value"> step="1"
</vn-date-picker> label="Days onward"
<vn-date-picker ng-model="$ctrl.filter.scopeDays"
vn-one on-change="$ctrl.applyFilters()"
label="Shipped to" display-controls="true"
ng-model="filter.shippedTo" info="Cannot choose a range of dates and days onward at the same time">
on-change="$ctrl.shippedTo = value"> </vn-input-number>
</vn-date-picker> </vn-horizontal>
<vn-none class="or vn-px-md" translate>Or</vn-none> <vn-horizontal class="input horizontal">
<vn-input-number <vn-date-picker
vn-one label="Landed from"
min="0" ng-model="$ctrl.filter.landedFrom"
step="1" on-change="$ctrl.applyFilters()">
label="Days onward" </vn-date-picker>
ng-model="filter.scopeDays" <vn-date-picker
on-change="$ctrl.scopeDays = value" label="Landed to"
display-controls="true"> ng-model="$ctrl.filter.landedTo"
</vn-input-number> on-change="$ctrl.applyFilters()">
<vn-icon color-marginal </vn-date-picker>
icon="info" </vn-horizontal>
vn-tooltip="Cannot choose a range of dates and days onward at the same time"> <vn-horizontal class="input horizontal">
</vn-icon> <vn-autocomplete
</vn-horizontal> vn-id="continent"
</section> label="Continent Out"
<vn-horizontal class="vn-px-lg"> ng-model="$ctrl.filter.continent"
<vn-date-picker data="$ctrl.continents"
vn-one show-field="name"
label="Landed from" value-field="code"
ng-model="filter.landedFrom"> on-change="$ctrl.applyFilters()">
</vn-date-picker> </vn-autocomplete>
<vn-date-picker <vn-input-number
vn-one min="0"
label="Landed to" label="Total entries"
ng-model="filter.landedTo"> ng-model="$ctrl.totalEntries"
</vn-date-picker> ng-keydown="$ctrl.onKeyPress($event, 'totalEntries')">
</vn-horizontal> </vn-input-number>
<vn-horizontal class="vn-px-lg"> </vn-horizontal>
<vn-autocomplete vn-one <div class="chips">
Review

Els tags ho podríes automatitzar obtinguent les claus dels params aplicats al objecte filter

Exemple:

Object.keys($ctrl.filter).map(tag => ({
	label: tag,
    value: $ctrl.filter[tag]
}))

En Lilium ho fa aixi
https://gitea.verdnatura.es/verdnatura/salix-front/src/branch/dev/src/components/ui/VnFilterPanel.vue#L70

Els tags ho podríes automatitzar obtinguent les claus dels params aplicats al objecte filter Exemple: ``` Object.keys($ctrl.filter).map(tag => ({ label: tag, value: $ctrl.filter[tag] })) ``` En Lilium ho fa aixi https://gitea.verdnatura.es/verdnatura/salix-front/src/branch/dev/src/components/ui/VnFilterPanel.vue#L70
Review

Es que si ho feia d'ixa forma hi havia valors que no podia mostrar en els chips com els noms dels warehouses o els continents perque ho havia d'agafar del selection en el autocomplete, no del filter

Es que si ho feia d'ixa forma hi havia valors que no podia mostrar en els chips com els noms dels warehouses o els continents perque ho havia d'agafar del selection en el autocomplete, no del filter
label="Warehouse Out" <vn-chip
ng-model="filter.warehouseOutFk" ng-if="$ctrl.filter.search"
url="Warehouses" removable="true"
show-field="name" on-remove="$ctrl.removeParamFilter('search')"
value-field="id"> class="colored">
</vn-autocomplete> <span>Id/{{$ctrl.$t('Reference')}}: {{$ctrl.filter.search}}</span>
<vn-autocomplete vn-one </vn-chip>
label="Warehouse In" <vn-chip
ng-model="filter.warehouseInFk" ng-if="agency.selection"
url="Warehouses" removable="true"
show-field="name" on-remove="$ctrl.removeParamFilter('agencyModeFk')"
value-field="id"> class="colored">
</vn-autocomplete> <span>{{$ctrl.$t('Agency')}}: {{agency.selection.name}}</span>
</vn-horizontal> </vn-chip>
<vn-horizontal class="vn-px-lg"> <vn-chip
<vn-autocomplete vn-one ng-if="warehouseOut.selection"
label="Continent Out" removable="true"
ng-model="filter.continent" on-remove="$ctrl.removeParamFilter('warehouseOutFk')"
url="Continents" class="colored">
show-field="name" <span>{{$ctrl.$t('Warehouse Out')}}: {{warehouseOut.selection.name}}</span>
value-field="code"> </vn-chip>
</vn-autocomplete> <vn-chip
</vn-horizontal> ng-if="warehouseIn.selection"
<vn-horizontal class="vn-px-lg vn-pb-lg vn-mt-lg"> removable="true"
<vn-submit label="Search"></vn-submit> on-remove="$ctrl.removeParamFilter('warehouseInFk')"
</vn-horizontal> class="colored">
</form> <span>{{$ctrl.$t('Warehouse In')}}: {{warehouseIn.selection.name}}</span>
</div> </vn-chip>
<vn-chip
ng-if="$ctrl.filter.scopeDays"
removable="true"
on-remove="$ctrl.removeParamFilter('scopeDays')"
class="colored">
<span>{{$ctrl.$t('Days onward')}}: {{$ctrl.filter.scopeDays}}</span>
</vn-chip>
<vn-chip
ng-if="$ctrl.filter.landedFrom"
removable="true"
on-remove="$ctrl.removeParamFilter('landedFrom')"
class="colored">
<span>{{$ctrl.$t('Landed from')}}: {{$ctrl.filter.landedFrom | date:'dd/MM/yyyy'}}</span>
</vn-chip>
<vn-chip
ng-if="$ctrl.filter.landedTo"
removable="true"
on-remove="$ctrl.removeParamFilter('landedTo')"
class="colored">
<span>{{$ctrl.$t('Landed to')}}: {{$ctrl.filter.landedTo | date:'dd/MM/yyyy'}}</span>
</vn-chip>
<vn-chip
ng-if="continent.selection"
removable="true"
on-remove="$ctrl.removeParamFilter('continent')"
class="colored">
<span>{{$ctrl.$t('Continent Out')}}: {{continent.selection.name}}</span>
</vn-chip>
<vn-chip
ng-if="$ctrl.filter.totalEntries"
removable="true"
on-remove="$ctrl.removeParamFilter('totalEntries')"
class="colored">
<span>{{$ctrl.$t('Total entries')}}: {{$ctrl.filter.totalEntries}}</span>
</vn-chip>
</div>
</vn-side-menu>

View File

@ -1,43 +1,69 @@
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);
this.filter = this.$.filter; this.initFilter();
this.fetchData();
} }
get shippedFrom() { $onChanges() {
return this._shippedFrom; if (this.model)
this.applyFilters();
} }
set shippedFrom(value) { fetchData() {
this._shippedFrom = value; this.$http.get('AgencyModes').then(res => {
this.filter.scopeDays = null; this.agencyModes = res.data;
});
this.$http.get('Warehouses').then(res => {
this.warehouses = res.data;
});
this.$http.get('Continents').then(res => {
this.continents = res.data;
});
} }
get shippedTo() { initFilter() {
return this._shippedTo; this.filter = {};
if (this.$params.q) {
this.filter = JSON.parse(this.$params.q);
this.search = this.filter.search;
this.totalEntries = this.filter.totalEntries;
}
if (!this.filter.scopeDays) this.filter.scopeDays = 7;
} }
set shippedTo(value) { applyFilters(param) {
this._shippedTo = value; this.model.applyFilter({}, this.filter)
this.filter.scopeDays = null; .then(() => {
if (param && this.model._orgData.length === 1)
this.$state.go('travel.card.summary', {id: this.model._orgData[0].id});
else
this.$state.go(this.$state.current.name, {q: JSON.stringify(this.filter)}, {location: 'replace'});
});
} }
get scopeDays() { removeParamFilter(param) {
return this._scopeDays; if (this[param]) delete this[param];
delete this.filter[param];
this.applyFilters();
} }
set scopeDays(value) { onKeyPress($event, param) {
this._scopeDays = value; if ($event.key === 'Enter') {
this.filter[param] = this[param];
this.filter.shippedFrom = null; this.applyFilters(param === 'search');
this.filter.shippedTo = null; }
} }
} }
ngModule.vnComponent('vnTravelSearchPanel', { ngModule.vnComponent('vnTravelSearchPanel', {
template: require('./index.html'), template: require('./index.html'),
controller: Controller controller: Controller,
bindings: {
model: '<'
}
}); });

View File

@ -8,41 +8,31 @@ describe('Travel Component vnTravelSearchPanel', () => {
beforeEach(inject($componentController => { beforeEach(inject($componentController => {
controller = $componentController('vnTravelSearchPanel', {$element: null}); controller = $componentController('vnTravelSearchPanel', {$element: null});
controller.$t = () => {}; controller.$t = () => {};
controller.filter = {};
})); }));
describe('shippedFrom() setter', () => { describe('applyFilters()', () => {
it('should clear the scope days when setting the from property', () => { it('should apply filters', async() => {
controller.filter.scopeDays = 1; controller.filter = {foo: 'bar'};
controller.model = {
applyFilter: jest.fn().mockResolvedValue(),
_orgData: [{id: 1}]
};
controller.$state = {
current: {
name: 'foo'
},
go: jest.fn()
};
controller.shippedFrom = Date.vnNew(); await controller.applyFilters(true);
expect(controller.filter.scopeDays).toBeNull(); expect(controller.model.applyFilter).toHaveBeenCalledWith({}, controller.filter);
expect(controller.shippedFrom).toBeDefined(); expect(controller.$state.go).toHaveBeenCalledWith('travel.card.summary', {id: 1});
});
});
describe('shippedTo() setter', () => { await controller.applyFilters(false);
it('should clear the scope days when setting the to property', () => {
controller.filter.scopeDays = 1;
controller.shippedTo = Date.vnNew(); expect(controller.$state.go).toHaveBeenCalledWith(controller.$state.current.name,
{q: JSON.stringify(controller.filter)}, {location: 'replace'});
expect(controller.filter.scopeDays).toBeNull();
expect(controller.shippedTo).toBeDefined();
});
});
describe('scopeDays() setter', () => {
it('should clear the date range when setting the scopeDays property', () => {
controller.filter.shippedFrom = Date.vnNew();
controller.filter.shippedTo = Date.vnNew();
controller.scopeDays = 1;
expect(controller.filter.shippedFrom).toBeNull();
expect(controller.filter.shippedTo).toBeNull();
expect(controller.scopeDays).toBeDefined();
}); });
}); });
}); });

View File

@ -0,0 +1,37 @@
@import "variables";
vn-travel-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;
}
.chips {
display: flex;
flex-wrap: wrap;
padding: $spacing-md;
overflow: hidden;
max-width: 100%;
border-color: $color-spacer;
}
.or {
align-self: center;
font-weight: bold;
font-size: 26px;
color: $color-font-secondary;
}
}
}

View File

@ -1,9 +1,9 @@
Reference: Referencia Reference: Referencia
Warehouse In: Almacén entrada Warehouse In: Alm. entrada
Warehouse Out: Almacén salida Warehouse Out: Alm. salida
Shipped: F. envío Shipped: F. envío
Landed: F. entrega Landed: F. entrega
Total entries: Entradas totales Total entries: Ent. totales
Delivered: Enviada Delivered: Enviada
Received: Recibida Received: Recibida
Agency: Agencia Agency: Agencia