Merge branch '2138-zone_event_m3' of verdnatura/salix into dev
gitea/salix/dev This commit looks good
Details
gitea/salix/dev This commit looks good
Details
This commit is contained in:
commit
87d7b773f1
|
@ -23,7 +23,7 @@
|
||||||
<section
|
<section
|
||||||
ng-repeat="day in ::$ctrl.weekDays"
|
ng-repeat="day in ::$ctrl.weekDays"
|
||||||
translate-attr="::{title: day.name}"
|
translate-attr="::{title: day.name}"
|
||||||
ng-click="$ctrl.selectWeekDay(day.index)">
|
ng-click="$ctrl.selectWeekDay($event, day.index)">
|
||||||
<span>{{::day.localeChar}}</span>
|
<span>{{::day.localeChar}}</span>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
on-last="$ctrl.repeatLast()">
|
on-last="$ctrl.repeatLast()">
|
||||||
<div
|
<div
|
||||||
class="day-number"
|
class="day-number"
|
||||||
ng-click="$ctrl.select(day)">
|
ng-click="$ctrl.select($event, day)">
|
||||||
{{::day | date: 'd'}}
|
{{::day | date: 'd'}}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -127,10 +127,11 @@ export default class Calendar extends FormInput {
|
||||||
/*
|
/*
|
||||||
* Day selection event
|
* Day selection event
|
||||||
*/
|
*/
|
||||||
select(day) {
|
select($event, day) {
|
||||||
if (!this.editable) return;
|
if (!this.editable) return;
|
||||||
this.change(day);
|
this.change(day);
|
||||||
this.emit('selection', {
|
this.emit('selection', {
|
||||||
|
$event: $event,
|
||||||
$days: [day],
|
$days: [day],
|
||||||
$type: 'day'
|
$type: 'day'
|
||||||
});
|
});
|
||||||
|
@ -140,7 +141,7 @@ export default class Calendar extends FormInput {
|
||||||
/*
|
/*
|
||||||
* WeekDay selection event
|
* WeekDay selection event
|
||||||
*/
|
*/
|
||||||
selectWeekDay(weekday) {
|
selectWeekDay($event, weekday) {
|
||||||
if (!this.editable) return;
|
if (!this.editable) return;
|
||||||
let days = [];
|
let days = [];
|
||||||
for (let day of this.days) {
|
for (let day of this.days) {
|
||||||
|
@ -149,6 +150,7 @@ export default class Calendar extends FormInput {
|
||||||
}
|
}
|
||||||
this.field = days[0];
|
this.field = days[0];
|
||||||
this.emit('selection', {
|
this.emit('selection', {
|
||||||
|
$event: $event,
|
||||||
$days: days,
|
$days: days,
|
||||||
$type: 'weekday',
|
$type: 'weekday',
|
||||||
$weekday: weekday
|
$weekday: weekday
|
||||||
|
|
|
@ -50,9 +50,15 @@ describe('Component vnCalendar', () => {
|
||||||
|
|
||||||
const day = new Date();
|
const day = new Date();
|
||||||
day.setHours(0, 0, 0, 0);
|
day.setHours(0, 0, 0, 0);
|
||||||
controller.select(day);
|
|
||||||
|
const clickEvent = new Event('click');
|
||||||
|
const target = document.createElement('div');
|
||||||
|
target.dispatchEvent(clickEvent);
|
||||||
|
|
||||||
|
controller.select(clickEvent, day);
|
||||||
|
|
||||||
let res = {
|
let res = {
|
||||||
|
$event: clickEvent,
|
||||||
$days: [day],
|
$days: [day],
|
||||||
$type: 'day'
|
$type: 'day'
|
||||||
};
|
};
|
||||||
|
|
|
@ -37,6 +37,22 @@ export default class Popover extends Popup {
|
||||||
super.hide();
|
super.hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get parent() {
|
||||||
|
return this.__parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bug #2147 Popover loses parent location
|
||||||
|
set parent(value) {
|
||||||
|
this.__parent = value;
|
||||||
|
|
||||||
|
if (!value) return;
|
||||||
|
|
||||||
|
const parentRect = value.getBoundingClientRect();
|
||||||
|
this.parentRect = {};
|
||||||
|
for (let prop in parentRect)
|
||||||
|
this.parentRect[prop] = parentRect[prop];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Repositions the popover to a correct location relative to the parent.
|
* Repositions the popover to a correct location relative to the parent.
|
||||||
*/
|
*/
|
||||||
|
@ -55,7 +71,7 @@ export default class Popover extends Popup {
|
||||||
arrowStyle.top = '';
|
arrowStyle.top = '';
|
||||||
arrowStyle.bottom = '';
|
arrowStyle.bottom = '';
|
||||||
|
|
||||||
let parentRect = this.parent.getBoundingClientRect();
|
let parentRect = this.parentRect;
|
||||||
let popoverRect = this.windowEl.getBoundingClientRect();
|
let popoverRect = this.windowEl.getBoundingClientRect();
|
||||||
let arrowRect = arrow.getBoundingClientRect();
|
let arrowRect = arrow.getBoundingClientRect();
|
||||||
let clamp = (value, min, max) => Math.min(Math.max(value, min), max);
|
let clamp = (value, min, max) => Math.min(Math.max(value, min), max);
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
const popover = {
|
||||||
|
show: () => {
|
||||||
|
return {
|
||||||
|
then: callback => {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
hide: () => {
|
||||||
|
return {
|
||||||
|
then: callback => {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
relocate: () => {
|
||||||
|
return {
|
||||||
|
then: callback => {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = popover;
|
|
@ -25,7 +25,7 @@
|
||||||
hide-contiguous="true"
|
hide-contiguous="true"
|
||||||
has-events="$ctrl.hasEvents($day)"
|
has-events="$ctrl.hasEvents($day)"
|
||||||
get-class="$ctrl.getClass($day)"
|
get-class="$ctrl.getClass($day)"
|
||||||
on-selection="$ctrl.onSelection($days, $type, $weekday)"
|
on-selection="$ctrl.onSelection($event, $days, $type, $weekday)"
|
||||||
class="vn-pa-md"
|
class="vn-pa-md"
|
||||||
style="min-width: 250px; flex: 1;">
|
style="min-width: 250px; flex: 1;">
|
||||||
</vn-calendar>
|
</vn-calendar>
|
||||||
|
|
|
@ -130,7 +130,7 @@ class Controller extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelection($days, $type, $weekday) {
|
onSelection($event, $days, $type, $weekday) {
|
||||||
let $events = [];
|
let $events = [];
|
||||||
let $exclusions = [];
|
let $exclusions = [];
|
||||||
|
|
||||||
|
@ -141,6 +141,7 @@ class Controller extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emit('selection', {
|
this.emit('selection', {
|
||||||
|
$event,
|
||||||
$days,
|
$days,
|
||||||
$type,
|
$type,
|
||||||
$weekday,
|
$weekday,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import './index.js';
|
import './index.js';
|
||||||
|
|
||||||
describe('Agency Component vnZoneCard', () => {
|
describe('Zone Component vnZoneCard', () => {
|
||||||
let controller;
|
let controller;
|
||||||
let $httpBackend;
|
let $httpBackend;
|
||||||
let data = {id: 1, name: 'fooName'};
|
let data = {id: 1, name: 'fooName'};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import './index';
|
import './index';
|
||||||
import watcher from 'core/mocks/watcher';
|
import watcher from 'core/mocks/watcher';
|
||||||
|
|
||||||
describe('Agency Component vnZoneCreate', () => {
|
describe('Zone Component vnZoneCreate', () => {
|
||||||
let $scope;
|
let $scope;
|
||||||
let $state;
|
let $state;
|
||||||
let controller;
|
let controller;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<div class="vn-w-md">
|
<div class="vn-w-md">
|
||||||
<vn-zone-calendar
|
<vn-zone-calendar
|
||||||
data="data">
|
data="data"
|
||||||
|
on-selection="$ctrl.onSelection($event, $events)">
|
||||||
</vn-zone-calendar>
|
</vn-zone-calendar>
|
||||||
</div>
|
</div>
|
||||||
<vn-side-menu side="right">
|
<vn-side-menu side="right">
|
||||||
|
@ -31,3 +32,11 @@
|
||||||
<vn-submit label="Query" class="vn-mt-sm"></vn-submit>
|
<vn-submit label="Query" class="vn-mt-sm"></vn-submit>
|
||||||
</form>
|
</form>
|
||||||
</vn-side-menu>
|
</vn-side-menu>
|
||||||
|
|
||||||
|
<!-- Zone Popover -->
|
||||||
|
<vn-popover vn-id="zoneEvents">
|
||||||
|
<div class="zoneEvents">
|
||||||
|
<div class="header vn-pa-sm" translate>Zones</div>
|
||||||
|
<vn-zone-index vn-id="zoneIndex"></vn-zone-index>
|
||||||
|
</div>
|
||||||
|
</vn-popover>
|
|
@ -17,6 +17,27 @@ class Controller extends Section {
|
||||||
this.vnApp.showMessage(this.$t('No service for the specified zone'));
|
this.vnApp.showMessage(this.$t('No service for the specified zone'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onSelection($event, $events) {
|
||||||
|
if (!$events.length) return;
|
||||||
|
|
||||||
|
const zones = [];
|
||||||
|
for (let event of $events)
|
||||||
|
zones.push(event.zoneFk);
|
||||||
|
|
||||||
|
this.$.zoneEvents.show($event.target);
|
||||||
|
const zoneIndex = this.$.zoneIndex;
|
||||||
|
const zoneModel = zoneIndex.$scope.model;
|
||||||
|
zoneModel.applyFilter({
|
||||||
|
include: {
|
||||||
|
relation: 'agencyMode',
|
||||||
|
scope: {fields: ['name']}
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
id: {inq: zones}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngModule.component('vnZoneDeliveryDays', {
|
ngModule.component('vnZoneDeliveryDays', {
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
import './index.js';
|
||||||
|
import popover from 'core/mocks/popover';
|
||||||
|
import crudModel from 'core/mocks/crud-model';
|
||||||
|
|
||||||
|
describe('Zone Component vnZoneDeliveryDays', () => {
|
||||||
|
let $componentController;
|
||||||
|
let $httpBackend;
|
||||||
|
let controller;
|
||||||
|
let $element;
|
||||||
|
|
||||||
|
beforeEach(ngModule('zone'));
|
||||||
|
|
||||||
|
beforeEach(angular.mock.inject((_$componentController_, _$httpBackend_) => {
|
||||||
|
$componentController = _$componentController_;
|
||||||
|
$httpBackend = _$httpBackend_;
|
||||||
|
$element = angular.element('<vn-zone-delivery-days></vn-zone-delivery-days');
|
||||||
|
controller = $componentController('vnZoneDeliveryDays', {$element});
|
||||||
|
controller.$.zoneEvents = popover;
|
||||||
|
controller.$.zoneIndex = {
|
||||||
|
$scope: {
|
||||||
|
model: crudModel
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('onSubmit()', () => {
|
||||||
|
it('should make an HTTP GET query and then call the showMessage() method', () => {
|
||||||
|
jest.spyOn(controller.vnApp, 'showMessage');
|
||||||
|
|
||||||
|
const expectedData = {events: []};
|
||||||
|
$httpBackend.when('GET', 'Zones/getEvents').respond({events: []});
|
||||||
|
controller.onSubmit();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.$.data).toBeDefined();
|
||||||
|
expect(controller.$.data).toEqual(expectedData);
|
||||||
|
expect(controller.vnApp.showMessage).toHaveBeenCalledWith('No service for the specified zone');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should make an HTTP GET query and then set the data property', () => {
|
||||||
|
const expectedData = {events: [{zoneFk: 1}]};
|
||||||
|
$httpBackend.when('GET', 'Zones/getEvents').respond({events: [{zoneFk: 1}]});
|
||||||
|
controller.onSubmit();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.$.data).toBeDefined();
|
||||||
|
expect(controller.$.data).toEqual(expectedData);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('onSelection()', () => {
|
||||||
|
it('should not call the show popover method if events array is empty', () => {
|
||||||
|
jest.spyOn(controller.$.zoneEvents, 'show');
|
||||||
|
|
||||||
|
const event = new Event('click');
|
||||||
|
const target = document.createElement('div');
|
||||||
|
target.dispatchEvent(event);
|
||||||
|
const events = [];
|
||||||
|
controller.onSelection(event, events);
|
||||||
|
|
||||||
|
expect(controller.$.zoneEvents.show).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call the show() method and then call the applyFilter() method with the expected ids', () => {
|
||||||
|
const zoneModel = controller.$.zoneIndex.$scope.model;
|
||||||
|
jest.spyOn(controller.$.zoneEvents, 'show');
|
||||||
|
jest.spyOn(zoneModel, 'applyFilter');
|
||||||
|
|
||||||
|
const event = new Event('click');
|
||||||
|
const target = document.createElement('div');
|
||||||
|
target.dispatchEvent(event);
|
||||||
|
const events = [
|
||||||
|
{zoneFk: 1},
|
||||||
|
{zoneFk: 2},
|
||||||
|
{zoneFk: 8}
|
||||||
|
];
|
||||||
|
controller.onSelection(event, events);
|
||||||
|
const expectedFilter = {
|
||||||
|
include: {
|
||||||
|
relation: 'agencyMode',
|
||||||
|
scope: {fields: ['name']}
|
||||||
|
},
|
||||||
|
where: {
|
||||||
|
id: {inq: [1, 2, 8]}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(controller.$.zoneEvents.show).toHaveBeenCalledWith(target);
|
||||||
|
expect(zoneModel.applyFilter).toHaveBeenCalledWith(expectedFilter);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,3 +1,4 @@
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
vn-zone-delivery-days {
|
vn-zone-delivery-days {
|
||||||
vn-zone-calendar {
|
vn-zone-calendar {
|
||||||
|
@ -14,3 +15,26 @@ vn-zone-delivery-days {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.zoneEvents {
|
||||||
|
width: 700px;
|
||||||
|
max-height: 450px;
|
||||||
|
|
||||||
|
vn-float-button {
|
||||||
|
display: none
|
||||||
|
}
|
||||||
|
|
||||||
|
vn-data-viewer {
|
||||||
|
margin-bottom: 0;
|
||||||
|
vn-pagination {
|
||||||
|
padding: 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .header {
|
||||||
|
background-color: $color-main;
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
text-align: center
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,7 @@
|
||||||
filter="::$ctrl.filter"
|
filter="::$ctrl.filter"
|
||||||
limit="20"
|
limit="20"
|
||||||
data="zones"
|
data="zones"
|
||||||
auto-load="true">
|
auto-load="false">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<vn-auto-search
|
<vn-auto-search
|
||||||
model="model"
|
model="model"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import './index.js';
|
import './index.js';
|
||||||
|
|
||||||
describe('Agency Component vnZoneIndex', () => {
|
describe('Zone Component vnZoneIndex', () => {
|
||||||
let $componentController;
|
let $componentController;
|
||||||
let controller;
|
let controller;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue