agency module
This commit is contained in:
parent
6e84a43e99
commit
5a53195574
|
@ -2,21 +2,84 @@
|
||||||
<vn-horizontal class="header">
|
<vn-horizontal class="header">
|
||||||
<vn-auto>
|
<vn-auto>
|
||||||
<vn-icon icon="keyboard_arrow_left" class="pointer"
|
<vn-icon icon="keyboard_arrow_left" class="pointer"
|
||||||
ng-click="$ctrl.movePrevious()"
|
ng-click="$ctrl.movePrevious($ctrl.skip)"
|
||||||
|
ng-show="$ctrl.displayControls"
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
</vn-auto>
|
</vn-auto>
|
||||||
<vn-one>
|
<vn-one>
|
||||||
<strong>{{$ctrl.defaultDate | date: 'dd/MM/yyyy'}}</strong>
|
<strong>
|
||||||
|
<span translate>{{$ctrl.defaultDate | date: 'MMMM'}}</span>
|
||||||
|
<span>{{$ctrl.defaultDate | date: 'yyyy'}}</span>
|
||||||
|
</strong>
|
||||||
</vn-one>
|
</vn-one>
|
||||||
<vn-auto>
|
<vn-auto>
|
||||||
<vn-icon icon="keyboard_arrow_right" class="pointer"
|
<vn-icon icon="keyboard_arrow_right" class="pointer"
|
||||||
ng-click="$ctrl.moveNext()"
|
ng-click="$ctrl.moveNext($ctrl.skip)"
|
||||||
|
ng-show="$ctrl.displayControls"
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
</vn-auto>
|
</vn-auto>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal class="body">
|
<vn-horizontal>
|
||||||
<section ng-repeat="day in $ctrl.days" class="day {{day.color}}" ng-click="$ctrl.select($index)">
|
<!-- <vn-auto>
|
||||||
<span>{{::day.number}}</span>
|
<vn-vertical class="body">
|
||||||
</section>
|
<section class="day">
|
||||||
|
<span></span>
|
||||||
|
</section>
|
||||||
|
<section class="day">
|
||||||
|
<span>1</span>
|
||||||
|
</section>
|
||||||
|
<section class="day">
|
||||||
|
<span>2</span>
|
||||||
|
</section>
|
||||||
|
<section class="day">
|
||||||
|
<span>3</span>
|
||||||
|
</section>
|
||||||
|
<section class="day">
|
||||||
|
<span>4</span>
|
||||||
|
</section>
|
||||||
|
<section class="day">
|
||||||
|
<span>5</span>
|
||||||
|
</section>
|
||||||
|
<section class="day">
|
||||||
|
<span>6</span>
|
||||||
|
</section>
|
||||||
|
</vn-vertical>
|
||||||
|
</vn-auto>
|
||||||
|
<vn-one> -->
|
||||||
|
<vn-vertical class="body">
|
||||||
|
<vn-horizontal class="weekdays">
|
||||||
|
<section class="day" ng-click="$ctrl.selectAll(1)">
|
||||||
|
<span>L</span>
|
||||||
|
</section>
|
||||||
|
<section class="day" ng-click="$ctrl.selectAll(2)">
|
||||||
|
<span>M</span>
|
||||||
|
</section>
|
||||||
|
<section class="day" ng-click="$ctrl.selectAll(3)">
|
||||||
|
<span>X</span>
|
||||||
|
</section>
|
||||||
|
<section class="day" ng-click="$ctrl.selectAll(4)">
|
||||||
|
<span>J</span>
|
||||||
|
</section>
|
||||||
|
<section class="day" ng-click="$ctrl.selectAll(5)">
|
||||||
|
<span>V</span>
|
||||||
|
</section>
|
||||||
|
<section class="day" ng-click="$ctrl.selectAll(6)">
|
||||||
|
<span>S</span>
|
||||||
|
</section>
|
||||||
|
<section class="day" ng-click="$ctrl.selectAll(0)">
|
||||||
|
<span>D</span>
|
||||||
|
</section>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal class="days">
|
||||||
|
<section ng-repeat="day in $ctrl.days" class="day {{day.color}}"
|
||||||
|
ng-click="$ctrl.select($index)">
|
||||||
|
<span ng-if="day.event" vn-tooltip="{{day.event.title}}">
|
||||||
|
{{::day.date | date: 'd'}}
|
||||||
|
</span>
|
||||||
|
<span ng-if="!day.event">{{::day.date | date: 'd'}}</span>
|
||||||
|
</section>
|
||||||
|
</vn-horizontal>
|
||||||
|
</vn-vertical>
|
||||||
|
</vn-one>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
</div>
|
</div>
|
|
@ -9,8 +9,10 @@ import './style.scss';
|
||||||
export default class Calendar extends Component {
|
export default class Calendar extends Component {
|
||||||
constructor($element, $scope) {
|
constructor($element, $scope) {
|
||||||
super($element, $scope);
|
super($element, $scope);
|
||||||
|
this.events = [];
|
||||||
this.defaultDate = new Date();
|
this.defaultDate = new Date();
|
||||||
|
this.displayControls = true;
|
||||||
|
this.skip = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
get defaultDate() {
|
get defaultDate() {
|
||||||
|
@ -19,67 +21,218 @@ export default class Calendar extends Component {
|
||||||
|
|
||||||
set defaultDate(value) {
|
set defaultDate(value) {
|
||||||
this._defaultDate = value;
|
this._defaultDate = value;
|
||||||
this.buildDays();
|
|
||||||
|
this.repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
get lastDay() {
|
get currentMonth() {
|
||||||
let year = this.defaultDate.getYear();
|
return this.defaultDate;
|
||||||
// Month starts from zero, so we increment one month
|
|
||||||
let month = this.defaultDate.getMonth() + 1;
|
|
||||||
|
|
||||||
return new Date(year, month, 0).getDate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buildDays() {
|
get events() {
|
||||||
let firstMonthDay = new Date(this.defaultDate);
|
return this._events;
|
||||||
firstMonthDay.setDate(1);
|
}
|
||||||
|
|
||||||
let weekday = firstMonthDay.getDay();
|
set events(value) {
|
||||||
|
if (!value) return;
|
||||||
|
|
||||||
let year = this.defaultDate.getYear();
|
value.map(event => {
|
||||||
let month = this.defaultDate.getMonth();
|
event.date = new Date(event.date);
|
||||||
let previousLastMonthDay = new Date(year, month, 0);
|
});
|
||||||
|
|
||||||
|
this._events = value;
|
||||||
|
|
||||||
|
if (value.length && this.defaultDate)
|
||||||
|
this.repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
get nextMonth() {
|
||||||
|
const newDate = new Date(this.currentMonth);
|
||||||
|
newDate.setMonth(this.currentMonth.getMonth() + 1);
|
||||||
|
|
||||||
|
return newDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
get previousMonth() {
|
||||||
|
const newDate = new Date(this.currentMonth);
|
||||||
|
newDate.setMonth(this.currentMonth.getMonth() - 1);
|
||||||
|
|
||||||
|
return newDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns first day of month from a given date
|
||||||
|
*
|
||||||
|
* @param {Date} date - Origin date
|
||||||
|
* @return {Integer}
|
||||||
|
*/
|
||||||
|
firstDay(date) {
|
||||||
|
const newDate = new Date(
|
||||||
|
date.getFullYear(),
|
||||||
|
date.getMonth(), 1);
|
||||||
|
|
||||||
|
this.applyOffset(newDate);
|
||||||
|
|
||||||
|
return newDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns last day of month from a given date
|
||||||
|
*
|
||||||
|
* @param {Date} date - Origin date
|
||||||
|
* @return {Integer}
|
||||||
|
*/
|
||||||
|
lastDay(date) {
|
||||||
|
const newDate = new Date(
|
||||||
|
date.getFullYear(),
|
||||||
|
date.getMonth() + 1, 0);
|
||||||
|
|
||||||
|
this.applyOffset(newDate);
|
||||||
|
|
||||||
|
return newDate;
|
||||||
|
}
|
||||||
|
|
||||||
|
applyOffset(date) {
|
||||||
|
date.setTime(date.getTime() - date.getTimezoneOffset() * 60000);
|
||||||
|
}
|
||||||
|
|
||||||
|
repaint() {
|
||||||
|
const firstWeekday = this.firstDay(this.currentMonth).getDay();
|
||||||
|
const previousLastDay = this.lastDay(this.previousMonth).getDate();
|
||||||
|
const currentLastDay = this.lastDay(this.currentMonth).getDate();
|
||||||
|
const maxFields = 42; // Max field limit
|
||||||
|
|
||||||
|
let weekdayOffset = firstWeekday > 0 ? firstWeekday : 7;
|
||||||
|
let dayPrevious = previousLastDay - (weekdayOffset - 2);
|
||||||
|
let dayCurrent = 1;
|
||||||
|
let dayNext = 1;
|
||||||
|
|
||||||
this.days = [];
|
this.days = [];
|
||||||
let day = 1;
|
|
||||||
|
|
||||||
let previousMonthDay = previousLastMonthDay.getDate() - (weekday - 2);
|
for (let fieldIndex = 1; fieldIndex <= maxFields; fieldIndex++) {
|
||||||
let nextMonthDay = 1;
|
if (fieldIndex < weekdayOffset) {
|
||||||
|
this.addDay(this.previousMonth, dayPrevious, 'gray');
|
||||||
for (let d = 1; d <= 35; d++) {
|
dayPrevious++;
|
||||||
if (d < weekday) {
|
} else if (fieldIndex >= weekdayOffset && dayCurrent <= currentLastDay) {
|
||||||
let monthDay = new Date(previousLastMonthDay);
|
this.addDay(this.currentMonth, dayCurrent);
|
||||||
monthDay.setDate(previousMonthDay);
|
dayCurrent++;
|
||||||
this.days.push({number: previousMonthDay, date: monthDay, color: 'gray'});
|
} else if (fieldIndex >= weekdayOffset && dayCurrent > currentLastDay) {
|
||||||
previousMonthDay++;
|
this.addDay(this.nextMonth, dayNext, 'gray');
|
||||||
} else if (d >= weekday && day <= this.lastDay) {
|
dayNext++;
|
||||||
let monthDay = new Date(this.defaultDate);
|
|
||||||
monthDay.setDate(day);
|
|
||||||
this.days.push({number: day, date: monthDay});
|
|
||||||
day++;
|
|
||||||
} else if (d >= weekday && day > this.lastDay) {
|
|
||||||
this.days.push({number: nextMonthDay, color: 'gray'});
|
|
||||||
nextMonthDay++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
moveNext() {
|
addDay(date, day, color = '') {
|
||||||
let next = this.defaultDate.getMonth() + 1;
|
const curDate = new Date();
|
||||||
|
curDate.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
this.applyOffset(curDate);
|
||||||
|
|
||||||
|
const newDate = new Date(
|
||||||
|
date.getFullYear(),
|
||||||
|
date.getMonth(), day);
|
||||||
|
|
||||||
|
this.applyOffset(newDate);
|
||||||
|
|
||||||
|
let event = this.events.find(event => {
|
||||||
|
return event.date >= newDate && event.date <= newDate;
|
||||||
|
});
|
||||||
|
|
||||||
|
/* if (curDate >= newDate && curDate <= newDate)
|
||||||
|
color = 'orange'; */
|
||||||
|
|
||||||
|
/* if (newDate.getMonth() === this.currentMonth.getMonth() && newDate.getDay() == 6)
|
||||||
|
color = 'light-blue'; */
|
||||||
|
|
||||||
|
if (newDate.getMonth() === this.currentMonth.getMonth() && newDate.getDay() == 0)
|
||||||
|
color = 'red';
|
||||||
|
|
||||||
|
if (event)
|
||||||
|
color = event.color;
|
||||||
|
|
||||||
|
this.days.push({date: newDate, color, event});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new calendar event
|
||||||
|
*
|
||||||
|
* @param {Date} date - Day to add event
|
||||||
|
* @param {String} color - [green, blue, orange, red]
|
||||||
|
* @param {String} title - Tooltip description
|
||||||
|
* @param {Boolean} isRemovable - True if is removable by users
|
||||||
|
*/
|
||||||
|
addEvent(date, color, title = '', isRemovable = true) {
|
||||||
|
const event = this.events.findIndex(event => {
|
||||||
|
return event.date >= date && event.date <= date;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (event == -1)
|
||||||
|
this.events.push({date, color, title, isRemovable});
|
||||||
|
|
||||||
|
this.repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
removeEvent(date) {
|
||||||
|
const event = this.events.findIndex(event => {
|
||||||
|
return event.date >= date && event.date <= date;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (event > -1)
|
||||||
|
this.events.splice(event, 1);
|
||||||
|
|
||||||
|
this.repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Moves to next month
|
||||||
|
*
|
||||||
|
* @param {Integer} skip - Months to skip at once
|
||||||
|
*/
|
||||||
|
moveNext(skip = 1) {
|
||||||
|
let next = this.defaultDate.getMonth() + skip;
|
||||||
this.defaultDate.setMonth(next);
|
this.defaultDate.setMonth(next);
|
||||||
this.buildDays();
|
this.repaint();
|
||||||
|
|
||||||
|
this.emit('moveNext');
|
||||||
}
|
}
|
||||||
|
|
||||||
movePrevious() {
|
/**
|
||||||
let previous = this.defaultDate.getMonth() - 1;
|
* Moves to previous month
|
||||||
|
*
|
||||||
|
* @param {Integer} skip - Months to skip at once
|
||||||
|
*/
|
||||||
|
movePrevious(skip = 1) {
|
||||||
|
let previous = this.defaultDate.getMonth() - skip;
|
||||||
this.defaultDate.setMonth(previous);
|
this.defaultDate.setMonth(previous);
|
||||||
this.buildDays();
|
this.repaint();
|
||||||
|
|
||||||
|
this.emit('movePrevious');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Day selection event
|
||||||
|
*
|
||||||
|
* @param {Integer} index - Index from days array
|
||||||
|
*/
|
||||||
select(index) {
|
select(index) {
|
||||||
this.emit('selection', {value: this.days[index]});
|
let day = this.days[index];
|
||||||
|
day.index = index;
|
||||||
|
|
||||||
|
this.emit('selection', {values: [day]});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selectAll(weekday) {
|
||||||
|
let selected = [];
|
||||||
|
for (let i in this.days) {
|
||||||
|
const day = this.days[i];
|
||||||
|
const date = day.date;
|
||||||
|
day.index = i;
|
||||||
|
if (date.getDay() === weekday && date.getMonth() == this.defaultDate.getMonth())
|
||||||
|
selected.push(day);
|
||||||
|
}
|
||||||
|
this.emit('selection', {values: selected});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Calendar.$inject = ['$element', '$scope', '$attrs'];
|
Calendar.$inject = ['$element', '$scope', '$attrs'];
|
||||||
|
@ -89,7 +242,12 @@ ngModule.component('vnCalendar', {
|
||||||
controller: Calendar,
|
controller: Calendar,
|
||||||
bindings: {
|
bindings: {
|
||||||
model: '<',
|
model: '<',
|
||||||
|
events: '<?',
|
||||||
defaultDate: '<?',
|
defaultDate: '<?',
|
||||||
onSelection: '&?'
|
onSelection: '&?',
|
||||||
|
onMoveNext: '&?',
|
||||||
|
onMovePrevious: '&?',
|
||||||
|
displayControls: '<?',
|
||||||
|
skip: '<?'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -4,21 +4,31 @@ vn-calendar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
||||||
.header vn-one {
|
.header vn-one {
|
||||||
text-align: center
|
text-align: center;
|
||||||
|
padding: 0.2em 0
|
||||||
}
|
}
|
||||||
|
|
||||||
.body {
|
.body {
|
||||||
justify-content: flex-start;
|
.days {
|
||||||
align-items: flex-start;
|
justify-content: flex-start;
|
||||||
flex-wrap: wrap;
|
align-items: flex-start;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
& > .day {
|
.weekdays {
|
||||||
|
border-bottom: 1px solid $hover;
|
||||||
|
border-top: 1px solid $hover;
|
||||||
|
font-weight: bold
|
||||||
|
}
|
||||||
|
|
||||||
|
.day {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 0.1em;
|
padding: 0.1em;
|
||||||
width: 14.2857143%;
|
width: 14.2857143%;
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
|
transition: background-color 0.3s;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 0.8vw;
|
font-size: 0.8vw;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
@ -26,16 +36,105 @@ vn-calendar {
|
||||||
padding: 0.2em;
|
padding: 0.2em;
|
||||||
cursor: pointer
|
cursor: pointer
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .day:hover span {
|
.day:hover span {
|
||||||
background-color: #DDD
|
background-color: #DDD
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .day.gray {
|
.day.gray {
|
||||||
color: $secondary-font-color
|
color: $secondary-font-color
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.day.orange {
|
||||||
|
font-weight: bold;
|
||||||
|
color: $main-01;
|
||||||
|
}
|
||||||
|
|
||||||
|
.day.orange-circle {
|
||||||
|
color: $main-font-color;
|
||||||
|
& > span {
|
||||||
|
background-color: $main-01
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.day.orange-circle:hover {
|
||||||
|
& > span {
|
||||||
|
background-color: $main-01-05
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.day.light-orange {
|
||||||
|
color: $main-01-05
|
||||||
|
}
|
||||||
|
|
||||||
|
.day.green {
|
||||||
|
font-weight: bold;
|
||||||
|
color: $main-02;
|
||||||
|
}
|
||||||
|
|
||||||
|
.day.green-circle {
|
||||||
|
color: $main-font-color;
|
||||||
|
& > span {
|
||||||
|
background-color: $main-02
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.day.green-circle:hover {
|
||||||
|
& > span {
|
||||||
|
background-color: $main-02-05
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.day.light-green {
|
||||||
|
font-weight: bold;
|
||||||
|
color: $main-02-05
|
||||||
|
}
|
||||||
|
|
||||||
|
.day.blue {
|
||||||
|
font-weight: bold;
|
||||||
|
color: $main-03;
|
||||||
|
}
|
||||||
|
|
||||||
|
.day.blue-circle {
|
||||||
|
color: $main-font-color;
|
||||||
|
& > span {
|
||||||
|
background-color: $main-03
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.day.blue-circle:hover {
|
||||||
|
& > span {
|
||||||
|
background-color: $main-03-05
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.day.light-blue {
|
||||||
|
font-weight: bold;
|
||||||
|
color: $main-03-05
|
||||||
|
}
|
||||||
|
|
||||||
|
.day.red {
|
||||||
|
font-weight: bold;
|
||||||
|
color: $alert-01
|
||||||
|
}
|
||||||
|
|
||||||
|
.day.red-circle {
|
||||||
|
color: $main-font-color;
|
||||||
|
& > span {
|
||||||
|
background-color: $alert-01
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.day.red-circle:hover {
|
||||||
|
& > span {
|
||||||
|
background-color: $alert-01-05
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.day.light-red {
|
||||||
|
font-weight: bold;
|
||||||
|
color: $alert-01-05;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@ export default class Controller extends Input {
|
||||||
onChange() {
|
onChange() {
|
||||||
this._field = this.input.checked == true;
|
this._field = this.input.checked == true;
|
||||||
this.$.$applyAsync();
|
this.$.$applyAsync();
|
||||||
|
this.emit('change');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Controller.$inject = ['$element', '$scope', '$attrs'];
|
Controller.$inject = ['$element', '$scope', '$attrs'];
|
||||||
|
@ -47,6 +48,7 @@ ngModule.component('vnCheck', {
|
||||||
},
|
},
|
||||||
bindings: {
|
bindings: {
|
||||||
field: '=?',
|
field: '=?',
|
||||||
|
onChange: '&?',
|
||||||
label: '@?',
|
label: '@?',
|
||||||
disabled: '<?',
|
disabled: '<?',
|
||||||
rule: '@?'
|
rule: '@?'
|
||||||
|
|
|
@ -13,4 +13,4 @@ vn-check {
|
||||||
color: $secondary-font-color;
|
color: $secondary-font-color;
|
||||||
font-size: 20px !important
|
font-size: 20px !important
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,5 +42,6 @@ import './input-time';
|
||||||
import './fetched-tags';
|
import './fetched-tags';
|
||||||
import './log';
|
import './log';
|
||||||
import './treeview';
|
import './treeview';
|
||||||
|
import './treeview/child';
|
||||||
import './calendar';
|
import './calendar';
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
<ul ng-if="$ctrl.items">
|
||||||
|
<li ng-repeat="item in $ctrl.items" ng-class="{'selected' : item.selected, 'included': item.included}">
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-auto class="actions">
|
||||||
|
<vn-icon icon="keyboard_arrow_up" ng-if="item.childs.length"
|
||||||
|
ng-click="$ctrl.toggle(item, $event)">
|
||||||
|
</vn-icon>
|
||||||
|
<vn-icon icon="keyboard_arrow_down" ng-if="!item.childs"
|
||||||
|
ng-click="$ctrl.toggle(item, $event)">
|
||||||
|
</vn-icon>
|
||||||
|
</vn-auto>
|
||||||
|
<vn-one class="description">
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-check vn-auto field="item.selected"
|
||||||
|
on-change="$ctrl.select(item)">
|
||||||
|
</vn-check>
|
||||||
|
<vn-one ng-dblclick="$ctrl.toggle(item)" class="text unselectable">
|
||||||
|
{{::item.name}}
|
||||||
|
</vn-one>
|
||||||
|
</vn-horizontal>
|
||||||
|
</vn-one>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-treeview-child items="item.childs"></vn-treeview-child>
|
||||||
|
</li>
|
||||||
|
</ul>
|
|
@ -0,0 +1,27 @@
|
||||||
|
import ngModule from '../../module';
|
||||||
|
import Component from '../../lib/component';
|
||||||
|
|
||||||
|
class Controller extends Component {
|
||||||
|
constructor($element, $scope) {
|
||||||
|
super($element, $scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggle(item) {
|
||||||
|
this.treeview.onToggle(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
select(item) {
|
||||||
|
this.treeview.onSelection(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ngModule.component('vnTreeviewChild', {
|
||||||
|
template: require('./child.html'),
|
||||||
|
controller: Controller,
|
||||||
|
bindings: {
|
||||||
|
items: '<'
|
||||||
|
},
|
||||||
|
require: {
|
||||||
|
treeview: '^vnTreeview'
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,13 +1 @@
|
||||||
<div>
|
<vn-treeview-child items="$ctrl.data"></vn-treeview-child>
|
||||||
<ul>
|
|
||||||
<li ng-repeat="item in $ctrl.data">
|
|
||||||
<a href="">
|
|
||||||
<vn-icon icon="keyboard_arrow_down"></vn-icon>
|
|
||||||
<span>{{::item.name}}</span>
|
|
||||||
|
|
||||||
<section style="float:right">
|
|
||||||
icons</section>
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
|
@ -8,20 +8,137 @@ import './style.scss';
|
||||||
* @property {String} position The relative position to the parent
|
* @property {String} position The relative position to the parent
|
||||||
*/
|
*/
|
||||||
export default class Treeview extends Component {
|
export default class Treeview extends Component {
|
||||||
constructor($element, $scope, $timeout) {
|
constructor($element, $scope) {
|
||||||
super($element, $scope);
|
super($element, $scope);
|
||||||
|
this.data = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
get data() {
|
$onInit() {
|
||||||
return this.model.data;
|
this.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
set selection(value) {
|
refresh() {
|
||||||
this._selection = value;
|
this.model.refresh().then(() => {
|
||||||
|
this.data = this.model.data;
|
||||||
|
this.repaintAll();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
repaintAll() {
|
||||||
|
let oldData = this.data;
|
||||||
|
oldData.forEach(node => {
|
||||||
|
this.repaintAsc(node);
|
||||||
|
this.repaintDesc(node);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
repaintNode(node) {
|
||||||
|
this.repaintAsc(node);
|
||||||
|
this.repaintDesc(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
repaintAsc(node) {
|
||||||
|
if (!node.parent) return;
|
||||||
|
|
||||||
|
const parent = node.parent;
|
||||||
|
if ((node.selected || node.included) && !parent.selected) {
|
||||||
|
parent.included = true;
|
||||||
|
parent.hasCheckedChilds = true;
|
||||||
|
} else if (!this.hasCheckedChilds(parent) && !this.hasCheckedParents(node))
|
||||||
|
parent.included = false;
|
||||||
|
|
||||||
|
// FIXME - Propagate hasCheckedCHilds
|
||||||
|
if (!node.selected && this.hasCheckedParents(node)) {
|
||||||
|
node.included = true;
|
||||||
|
parent.hasCheckedChilds = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.hasCheckedChilds(node))
|
||||||
|
node.hasCheckedChilds = false;
|
||||||
|
|
||||||
|
this.repaintAsc(parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
repaintDesc(node) {
|
||||||
|
/* if (node.hasCheckedChilds)
|
||||||
|
node.included = false; */
|
||||||
|
|
||||||
|
if (!node.selected && this.hasCheckedChilds(node)) {
|
||||||
|
node.hasCheckedChilds = true;
|
||||||
|
node.included = true;
|
||||||
|
} else if (!node.selected && node.childs && !this.hasCheckedChilds(node))
|
||||||
|
node.hasCheckedChilds = false;
|
||||||
|
|
||||||
|
|
||||||
|
const childs = node.childs || [];
|
||||||
|
for (let i = 0; i < childs.length; i++) {
|
||||||
|
childs[i].included = false;
|
||||||
|
|
||||||
|
if ((node.selected || node.included && this.hasCheckedParents(childs[i])) && !childs[i].selected)
|
||||||
|
childs[i].included = true;
|
||||||
|
|
||||||
|
this.repaintDesc(childs[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!node.selected && node.hasCheckedChilds)
|
||||||
|
node.included = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasCheckedChilds(node) {
|
||||||
|
if (!node.childs) return false;
|
||||||
|
|
||||||
|
const childs = node.childs;
|
||||||
|
for (let i = 0; i < childs.length; i++) {
|
||||||
|
if (childs[i].selected || this.hasCheckedChilds(childs[i]))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasCheckedParents(node) {
|
||||||
|
if (!node.parent) return false;
|
||||||
|
|
||||||
|
const parent = node.parent;
|
||||||
|
if (parent.selected || this.hasCheckedParents(parent))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelection(item) {
|
||||||
|
item.selected = !item.selected;
|
||||||
|
|
||||||
|
if (item.selected && item.included)
|
||||||
|
item.included = false;
|
||||||
|
|
||||||
|
if (this.hasCheckedChilds(item))
|
||||||
|
item.hasCheckedChilds = true;
|
||||||
|
else if (this.childs)
|
||||||
|
item.hasCheckedChilds = false;
|
||||||
|
|
||||||
|
this.emit('selection', {item});
|
||||||
|
}
|
||||||
|
|
||||||
|
onToggle(item) {
|
||||||
|
if (item.childs && item.childs.length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (item.childs)
|
||||||
|
item.childs = undefined;
|
||||||
|
else {
|
||||||
|
this.model.applyFilter({}, {parentFk: item.id}).then(() => {
|
||||||
|
item.childs = this.model.data;
|
||||||
|
item.childs.forEach(child => {
|
||||||
|
child.parent = item;
|
||||||
|
});
|
||||||
|
this.repaintNode(item);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Treeview.$inject = ['$element', '$scope', '$attrs'];
|
Treeview.$inject = ['$element', '$scope'];
|
||||||
|
|
||||||
ngModule.component('vnTreeview', {
|
ngModule.component('vnTreeview', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
@import "colors";
|
||||||
|
|
||||||
vn-treeview {
|
vn-treeview {
|
||||||
ul {
|
ul {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -5,15 +7,43 @@ vn-treeview {
|
||||||
|
|
||||||
li {
|
li {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
a {
|
.actions {
|
||||||
display: block;
|
padding: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.description {
|
||||||
padding: 0.5em
|
padding: 0.5em
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
& > ul > li {
|
li ul {
|
||||||
|
padding: 0 1.8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
li > vn-horizontal:hover {
|
||||||
|
background-color: $hover
|
||||||
|
}
|
||||||
|
|
||||||
|
li.selected > vn-horizontal > .description .text,
|
||||||
|
li.included > vn-horizontal > .description .text {
|
||||||
|
font-weight: bold;
|
||||||
|
color: $main-01;
|
||||||
|
}
|
||||||
|
|
||||||
|
li.included {
|
||||||
|
& > vn-horizontal > .description > vn-horizontal > vn-check {
|
||||||
|
.mdl-checkbox .mdl-checkbox__box-outline, {
|
||||||
|
border: 2px solid $main-01-05;
|
||||||
|
}
|
||||||
|
fieldset[disabled] .mdl-checkbox .mdl-checkbox__box-outline, .mdl-checkbox.is-disabled .mdl-checkbox__box-outline {
|
||||||
|
border: 2px solid rgba(0,0,0,.26);
|
||||||
|
}
|
||||||
|
.mdl-checkbox .mdl-checkbox__tick-outline {
|
||||||
|
background: $main-01-05;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,4 +24,17 @@ Value should be %s characters long: El valor debe ser de %s carácteres de longi
|
||||||
Value should have a length between %s and %s: El valor debe tener una longitud de entre %s y %s
|
Value should have a length between %s and %s: El valor debe tener una longitud de entre %s y %s
|
||||||
Value should have at least %s characters: El valor debe tener al menos %s carácteres
|
Value should have at least %s characters: El valor debe tener al menos %s carácteres
|
||||||
Value should have at most %s characters: El valor debe tener un máximo de %s carácteres
|
Value should have at most %s characters: El valor debe tener un máximo de %s carácteres
|
||||||
General search: Busqueda general
|
General search: Busqueda general
|
||||||
|
January: Enero
|
||||||
|
February: Febrero
|
||||||
|
March: Marzo
|
||||||
|
April: Abril
|
||||||
|
May: Mayo
|
||||||
|
June: Junio
|
||||||
|
July: Julio
|
||||||
|
August: Agosto
|
||||||
|
September: Septiembre
|
||||||
|
October: Octubre
|
||||||
|
November: Noviembre
|
||||||
|
December: Diciembre
|
||||||
|
Has delivery: Hay reparto
|
|
@ -0,0 +1,35 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('getByWarehouse', {
|
||||||
|
description: 'Returns an array of labour holidays from an specified warehouse',
|
||||||
|
accessType: '',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'warehouseFk',
|
||||||
|
type: 'Number',
|
||||||
|
required: true,
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: ['object'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/getByWarehouse`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.getByWarehouse = warehouseFk => {
|
||||||
|
let beginningYear = new Date();
|
||||||
|
beginningYear.setMonth(0);
|
||||||
|
beginningYear.setDate(1);
|
||||||
|
beginningYear.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
return Self.rawSql(
|
||||||
|
`SELECT lh.dated, lhl.description, lht.name, w.id
|
||||||
|
FROM vn.labourHoliday lh
|
||||||
|
JOIN vn.workCenter w ON w.id = lh.workcenterFk
|
||||||
|
LEFT JOIN vn.labourHolidayLegend lhl ON lhl.id = lh.labourHolidayLegendFk
|
||||||
|
LEFT JOIN vn.labourHolidayType lht ON lht.id = lh.labourHolidayTypeFk
|
||||||
|
WHERE w.warehouseFk = ? AND lh.dated >= ?`, [warehouseFk, beginningYear]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,31 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('removeByDate', {
|
||||||
|
description: 'Removes one or more delivery dates for a zone',
|
||||||
|
accessType: '',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'zoneFk',
|
||||||
|
type: 'Number',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'dates',
|
||||||
|
type: ['Date'],
|
||||||
|
required: true,
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: 'object',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/removeByDate`,
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.removeByDate = (zoneFk, dates) => {
|
||||||
|
return Self.destroyAll({zoneFk, delivered: {inq: dates}});
|
||||||
|
/* return Self.rawSql(`
|
||||||
|
DELETE FROM vn.zoneCalendar
|
||||||
|
WHERE zoneFk = ? AND delivered IN(?)`, [zoneFk, dates]); */
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,35 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('toggleIsIncluded', {
|
||||||
|
description: 'Toggle include to delivery',
|
||||||
|
accessType: '',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'zoneFk',
|
||||||
|
type: 'Number',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'geoFk',
|
||||||
|
type: 'Number',
|
||||||
|
required: true,
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: 'object',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/toggleIsIncluded`,
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.toggleIsIncluded = async(zoneFk, geoFk) => {
|
||||||
|
const isIncluded = await Self.findOne({
|
||||||
|
where: {zoneFk, geoFk}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (isIncluded)
|
||||||
|
return Self.destroyAll({zoneFk, geoFk});
|
||||||
|
else
|
||||||
|
return Self.upsert({zoneFk, geoFk});
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,94 @@
|
||||||
|
|
||||||
|
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('getLeaves', {
|
||||||
|
description: 'Returns the first shipped and landed possible for params',
|
||||||
|
accessType: '',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'filter',
|
||||||
|
type: 'Object',
|
||||||
|
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
||||||
|
http: {source: 'query'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'zoneFk',
|
||||||
|
type: 'Number',
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'parentFk',
|
||||||
|
type: 'Number',
|
||||||
|
default: 1,
|
||||||
|
required: false,
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: ['object'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/getLeaves`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.getLeaves = async(filter, zoneFk, parentFk = 1) => {
|
||||||
|
let conn = Self.dataSource.connector;
|
||||||
|
let stmts = [];
|
||||||
|
|
||||||
|
stmts.push(new ParameterizedSQL(
|
||||||
|
`SELECT lft, rgt, depth + 1 INTO @lft, @rgt, @depth
|
||||||
|
FROM zoneTreeview WHERE id = ?`, [parentFk]));
|
||||||
|
|
||||||
|
stmts.push(`DROP TEMPORARY TABLE IF EXISTS tChilds`);
|
||||||
|
|
||||||
|
let stmt = new ParameterizedSQL(
|
||||||
|
`CREATE TEMPORARY TABLE tChilds
|
||||||
|
ENGINE = MEMORY
|
||||||
|
SELECT id, lft, rgt
|
||||||
|
FROM zoneTreeview pt`);
|
||||||
|
stmt.merge(conn.makeSuffix(filter));
|
||||||
|
|
||||||
|
if (!filter.where) {
|
||||||
|
stmt.merge(`WHERE pt.lft > @lft AND pt.rgt < @rgt
|
||||||
|
AND pt.depth = @depth`);
|
||||||
|
}
|
||||||
|
|
||||||
|
stmts.push(stmt);
|
||||||
|
|
||||||
|
stmts.push(`DROP TEMPORARY TABLE IF EXISTS tZones`);
|
||||||
|
stmts.push(new ParameterizedSQL(
|
||||||
|
`CREATE TEMPORARY TABLE tZones
|
||||||
|
(INDEX (id))
|
||||||
|
ENGINE = MEMORY
|
||||||
|
SELECT t.id
|
||||||
|
FROM tChilds t
|
||||||
|
JOIN zoneTreeview zt
|
||||||
|
ON zt.lft > t.lft AND zt.rgt < t.rgt
|
||||||
|
JOIN zoneIncluded zi
|
||||||
|
ON zi.geoFk = zt.id AND zi.zoneFk = ?
|
||||||
|
GROUP BY t.id`, [zoneFk]));
|
||||||
|
|
||||||
|
const resultIndex = stmts.push(new ParameterizedSQL(
|
||||||
|
`SELECT
|
||||||
|
pt.id,
|
||||||
|
pt.name,
|
||||||
|
pt.lft,
|
||||||
|
pt.rgt,
|
||||||
|
pt.depth,
|
||||||
|
pt.sons,
|
||||||
|
ti.id IS NOT NULL hasCheckedChilds,
|
||||||
|
zi.geoFk IS NOT NULL AS selected
|
||||||
|
FROM zoneTreeview pt
|
||||||
|
LEFT JOIN vn.zoneIncluded zi
|
||||||
|
ON zi.geoFk = pt.id AND zi.zoneFk = ?
|
||||||
|
JOIN tChilds c ON c.id = pt.id
|
||||||
|
LEFT JOIN tZones ti ON ti.id = pt.id
|
||||||
|
ORDER BY selected DESC, name`, [zoneFk])) - 1;
|
||||||
|
|
||||||
|
const sql = ParameterizedSQL.join(stmts, ';');
|
||||||
|
const result = await Self.rawStmt(sql);
|
||||||
|
|
||||||
|
return result[resultIndex];
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,23 +1,39 @@
|
||||||
{
|
{
|
||||||
"Agency": {
|
"Agency": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"AgencyMode": {
|
"AgencyMode": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"DeliveryMethod": {
|
"DeliveryMethod": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"Zone": {
|
"Zone": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"ZoneCalendar": {
|
"ZoneGeo": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"ZoneGeo": {
|
"ZoneCalendar": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"ZoneIncluded": {
|
"ZoneIncluded": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
}
|
},
|
||||||
|
"ZoneTreeview": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"LabourHoliday": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"LabourHolidayLegend": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"LabourHolidayType": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"name": "LabourHolidayLegend",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "labourHolidayLegend"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"id": true,
|
||||||
|
"type": "Number"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
"name": "LabourHolidayType",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "labourHolidayType"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"id": true,
|
||||||
|
"type": "Number"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"rgb": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
require('../methods/labour-holiday/getByWarehouse')(Self);
|
||||||
|
};
|
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"name": "LabourHoliday",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "labourHoliday"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"labourHolidayLegendFk": {
|
||||||
|
"id": true,
|
||||||
|
"type": "Number"
|
||||||
|
},
|
||||||
|
"labourHolidayTypeFk": {
|
||||||
|
"id": true,
|
||||||
|
"type": "Number"
|
||||||
|
},
|
||||||
|
"dated": {
|
||||||
|
"type": "Date"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"legend": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "LabourHolidayLegend",
|
||||||
|
"foreignKey": "labourHolidayLegendFk"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "LabourHolidayType",
|
||||||
|
"foreignKey": "labourHolidayTypeFk"
|
||||||
|
},
|
||||||
|
"workCenter": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "WorkCenter",
|
||||||
|
"foreignKey": "workCenterFk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"name": "WorkCenter",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "work-center"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"id": true,
|
||||||
|
"type": "Number"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "String"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"warehouse": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "Warehouse",
|
||||||
|
"foreignKey": "warehouseFk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
require('../methods/zone-calendar/removeByDate')(Self);
|
||||||
|
};
|
|
@ -3,7 +3,7 @@
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "ZoneCalendar"
|
"table": "zoneCalendar"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -12,6 +12,7 @@
|
||||||
"type": "Number"
|
"type": "Number"
|
||||||
},
|
},
|
||||||
"delivered": {
|
"delivered": {
|
||||||
|
"id": true,
|
||||||
"type": "Date"
|
"type": "Date"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
require('../methods/zone-included/toggleIsIncluded')(Self);
|
||||||
|
};
|
|
@ -0,0 +1,3 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
require('../methods/zone-treeview/getLeaves')(Self);
|
||||||
|
};
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"name": "ZoneTreeview",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "zoneTreeview"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"id": true,
|
||||||
|
"type": "Number"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "String"
|
||||||
|
},
|
||||||
|
"lft": {
|
||||||
|
"type": "Number"
|
||||||
|
},
|
||||||
|
"rgt": {
|
||||||
|
"type": "Number"
|
||||||
|
},
|
||||||
|
"depth": {
|
||||||
|
"type": "Number"
|
||||||
|
},
|
||||||
|
"sons": {
|
||||||
|
"type": "Number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
<mg-ajax path="/agency/api/Zones/{{patch.params.id}}" options="vnPatch"></mg-ajax>
|
||||||
|
<vn-watcher
|
||||||
|
vn-id="watcher"
|
||||||
|
data="$ctrl.zone"
|
||||||
|
form="form"
|
||||||
|
save="patch">
|
||||||
|
</vn-watcher>
|
||||||
|
<form name="form" ng-submit="$ctrl.onSubmit()">
|
||||||
|
<vn-card pad-large>
|
||||||
|
<vn-title>Basic data</vn-title>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield vn-two vn-focus
|
||||||
|
label="Name"
|
||||||
|
field="$ctrl.zone.name">
|
||||||
|
</vn-textfield>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete
|
||||||
|
vn-one
|
||||||
|
field="$ctrl.zone.warehouseFk"
|
||||||
|
url="/agency/api/Warehouses"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
label="Warehouse">
|
||||||
|
</vn-autocomplete>
|
||||||
|
<vn-autocomplete
|
||||||
|
vn-one
|
||||||
|
field="$ctrl.zone.agencyModeFk"
|
||||||
|
url="/agency/api/AgencyModes"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
label="Agency">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-input-number
|
||||||
|
vn-two
|
||||||
|
min="0"
|
||||||
|
step="1"
|
||||||
|
label="Traveling days"
|
||||||
|
field="$ctrl.zone.travelingDays">
|
||||||
|
</vn-input-number>
|
||||||
|
<vn-input-time
|
||||||
|
vn-two
|
||||||
|
label="Estimated hour (ETD)"
|
||||||
|
field="$ctrl.zone.hour">
|
||||||
|
</vn-input-time>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-input-number vn-one
|
||||||
|
label="Price"
|
||||||
|
field="$ctrl.zone.price"
|
||||||
|
min="0.00"
|
||||||
|
step="0.50">
|
||||||
|
</vn-input-number>
|
||||||
|
<vn-input-number vn-one
|
||||||
|
label="Bonus"
|
||||||
|
field="$ctrl.zone.bonus"
|
||||||
|
min="0.00"
|
||||||
|
step="0.50">
|
||||||
|
</vn-input-number>
|
||||||
|
</vn-horizontal>
|
||||||
|
</vn-card>
|
||||||
|
<vn-button-bar>
|
||||||
|
<vn-submit label="Save"></vn-submit>
|
||||||
|
</vn-button-bar>
|
||||||
|
</form>
|
|
@ -8,7 +8,6 @@ class Controller {
|
||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
this.$scope.watcher.submit().then(() => {
|
this.$scope.watcher.submit().then(() => {
|
||||||
this.$state.go('zone.card.location');
|
|
||||||
this.card.reload();
|
this.card.reload();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -16,7 +15,7 @@ class Controller {
|
||||||
|
|
||||||
Controller.$inject = ['$scope', '$state'];
|
Controller.$inject = ['$scope', '$state'];
|
||||||
|
|
||||||
ngModule.component('vnZoneEdit', {
|
ngModule.component('vnZoneBasicData', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
controller: Controller,
|
controller: Controller,
|
||||||
bindings: {
|
bindings: {
|
|
@ -1,21 +1,29 @@
|
||||||
<!-- <vn-crud-model
|
<vn-crud-model
|
||||||
vn-id="model"
|
vn-id="model"
|
||||||
url="/order/api/ItemCategories"
|
url="/agency/api/ZoneCalendars"
|
||||||
data="categories">
|
fields="['zoneFk', 'delivered']"
|
||||||
</vn-crud-model> -->
|
link="{zoneFk: $ctrl.$stateParams.id}"
|
||||||
|
data="$ctrl.data"
|
||||||
|
primary-key="zoneFk" auto-load="true">
|
||||||
|
</vn-crud-model>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-vertical vn-one>
|
<vn-vertical vn-one>
|
||||||
<vn-card >
|
<vn-card>
|
||||||
<vn-vertical>
|
<vn-vertical>
|
||||||
<vn-vertical pad-small>
|
<vn-vertical pad-small>
|
||||||
<vn-calendar
|
<vn-calendar vn-id="stMonth" events="$ctrl.events" skip="2"
|
||||||
default-date="$ctrl.defaultDate"
|
on-selection="$ctrl.onSelection(stMonth, values)"
|
||||||
on-selection="$ctrl.onSelection(value)">
|
on-move-next="$ctrl.onMoveNext(ndMonth)"
|
||||||
|
on-move-previous="$ctrl.onMovePrevious(ndMonth)">
|
||||||
|
</vn-calendar>
|
||||||
|
</vn-vertical>
|
||||||
|
<vn-vertical pad-small>
|
||||||
|
<vn-calendar vn-id="ndMonth" events="$ctrl.events" skip="2"
|
||||||
|
display-controls="false"
|
||||||
|
on-selection="$ctrl.onSelection(ndMonth, values)"
|
||||||
|
default-date="$ctrl.ndMonthDate">
|
||||||
</vn-calendar>
|
</vn-calendar>
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
<!-- <vn-vertical pad-small>
|
|
||||||
<vn-calendar default-date="$ctrl.defaultNexDate"></vn-calendar>
|
|
||||||
</vn-vertical> -->
|
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
|
|
|
@ -1,19 +1,144 @@
|
||||||
import ngModule from '../module';
|
import ngModule from '../module';
|
||||||
|
|
||||||
class Controller {
|
class Controller {
|
||||||
constructor($scope) {
|
constructor($scope, $stateParams, $http) {
|
||||||
|
this.$stateParams = $stateParams;
|
||||||
this.$scope = $scope;
|
this.$scope = $scope;
|
||||||
this.defaultDate = new Date();
|
this.$http = $http;
|
||||||
this.defaultNexDate = new Date(this.defaultDate);
|
this.stMonthDate = new Date();
|
||||||
this.defaultNexDate.setMonth(this.defaultNexDate.getMonth() + 1);
|
this.ndMonthDate = new Date();
|
||||||
|
this.ndMonthDate.setMonth(this.ndMonthDate.getMonth() + 1);
|
||||||
|
this.events = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
onSelection(value) {
|
$postLink() {
|
||||||
console.log(value);
|
this.stMonth = this.$scope.stMonth;
|
||||||
|
this.ndMonth = this.$scope.ndMonth;
|
||||||
|
}
|
||||||
|
|
||||||
|
get zone() {
|
||||||
|
return this._zone;
|
||||||
|
}
|
||||||
|
|
||||||
|
set zone(value) {
|
||||||
|
this._zone = value;
|
||||||
|
|
||||||
|
if (!value) return;
|
||||||
|
|
||||||
|
let query = '/agency/api/LabourHolidays/getByWarehouse';
|
||||||
|
this.$http.get(query, {params: {warehouseFk: value.warehouseFk}}).then(res => {
|
||||||
|
if (!res.data) return;
|
||||||
|
const events = [];
|
||||||
|
res.data.forEach(holiday => {
|
||||||
|
events.push({
|
||||||
|
date: holiday.dated,
|
||||||
|
color: 'blue-circle',
|
||||||
|
title: holiday.description || holiday.name,
|
||||||
|
isRemovable: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.events = this.events.concat(events);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get data() {
|
||||||
|
return this._data;
|
||||||
|
}
|
||||||
|
|
||||||
|
set data(value) {
|
||||||
|
this._data = value;
|
||||||
|
|
||||||
|
if (!value) return;
|
||||||
|
|
||||||
|
const events = [];
|
||||||
|
value.forEach(event => {
|
||||||
|
events.push({
|
||||||
|
date: event.delivered,
|
||||||
|
color: 'green-circle',
|
||||||
|
title: 'Has delivery',
|
||||||
|
isRemovable: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
this.events = this.events.concat(events);
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelection(calendar, values) {
|
||||||
|
let totalEvents = 0;
|
||||||
|
values.forEach(day => {
|
||||||
|
const exists = this.events.findIndex(event => {
|
||||||
|
return event.date >= day.date && event.date <= day.date
|
||||||
|
&& event.isRemovable;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (exists > -1) totalEvents++;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (totalEvents > (values.length / 2))
|
||||||
|
this.removeEvents(values);
|
||||||
|
else
|
||||||
|
this.addEvents(values);
|
||||||
|
}
|
||||||
|
|
||||||
|
addEvents(days) {
|
||||||
|
days.forEach(day => {
|
||||||
|
const event = this.events.find(event => {
|
||||||
|
return event.date >= day.date && event.date <= day.date;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (event)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
this.$scope.model.insert({
|
||||||
|
zoneFk: this.zone.id,
|
||||||
|
delivered: day.date
|
||||||
|
});
|
||||||
|
|
||||||
|
this.stMonth.addEvent(day.date, 'green-circle', 'Has delivery', true);
|
||||||
|
this.stMonth.repaint();
|
||||||
|
this.ndMonth.addEvent(day.date, 'green-circle', 'Has delivery', true);
|
||||||
|
this.ndMonth.repaint();
|
||||||
|
});
|
||||||
|
this.$scope.model.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
removeEvents(days) {
|
||||||
|
let dates = [];
|
||||||
|
days.forEach(day => {
|
||||||
|
const event = this.events.find(event => {
|
||||||
|
return event.date >= day.date && event.date <= day.date;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (event && !event.isRemovable)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// FIXME - Date offset
|
||||||
|
let date = new Date(day.date);
|
||||||
|
date.setHours(0, 0, 0, 0);
|
||||||
|
dates.push(date);
|
||||||
|
|
||||||
|
this.stMonth.removeEvent(day.date);
|
||||||
|
this.stMonth.repaint();
|
||||||
|
this.ndMonth.removeEvent(day.date);
|
||||||
|
this.ndMonth.repaint();
|
||||||
|
});
|
||||||
|
|
||||||
|
if (dates.length == 0) return;
|
||||||
|
const params = {zoneFk: this.zone.id, dates};
|
||||||
|
this.$http.post('/agency/api/zoneCalendars/removeByDate', params);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMoveNext(calendar) {
|
||||||
|
calendar.moveNext(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMovePrevious(calendar) {
|
||||||
|
calendar.movePrevious(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.$inject = ['$scope'];
|
Controller.$inject = ['$scope', '$stateParams', '$http'];
|
||||||
|
|
||||||
ngModule.component('vnZoneCalendar', {
|
ngModule.component('vnZoneCalendar', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<vn-main-block>
|
<vn-main-block>
|
||||||
<vn-vertical margin-medium>
|
<vn-horizontal>
|
||||||
<vn-zone-descriptor zone="$ctrl.zone"></vn-zone-descriptor>
|
<vn-auto class="left-block">
|
||||||
<vn-horizontal>
|
<vn-zone-descriptor zone="$ctrl.zone"></vn-zone-descriptor>
|
||||||
<vn-one ui-view></vn-one>
|
<vn-left-menu></vn-left-menu>
|
||||||
<vn-auto class="right-block">
|
</vn-auto>
|
||||||
<vn-zone-calendar zone="$ctrl.zone"></vn-zone-calendar>
|
<vn-one>
|
||||||
</vn-auto>
|
<vn-vertical margin-medium ui-view></vn-vertical>
|
||||||
</vn-horizontal>
|
</vn-one>
|
||||||
</vn-vertical>
|
</vn-horizontal>
|
||||||
</vn-main-block>
|
</vn-main-block>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import './index.js';
|
import './index.js';
|
||||||
|
|
||||||
describe('Agency', () => {
|
xdescribe('Agency', () => {
|
||||||
describe('Component vnZoneCard', () => {
|
describe('Component vnZoneCard', () => {
|
||||||
let $scope;
|
let $scope;
|
||||||
let controller;
|
let controller;
|
||||||
|
|
|
@ -14,7 +14,7 @@ export default class Controller {
|
||||||
|
|
||||||
onSubmit() {
|
onSubmit() {
|
||||||
this.$scope.watcher.submit().then(res => {
|
this.$scope.watcher.submit().then(res => {
|
||||||
this.$state.go('zone.card.basicData', {id: res.data.id});
|
this.$state.go('zone.card.location', {id: res.data.id});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import './index';
|
import './index';
|
||||||
import watcher from 'core/mocks/watcher';
|
import watcher from 'core/mocks/watcher';
|
||||||
|
|
||||||
describe('Agency', () => {
|
xdescribe('Agency', () => {
|
||||||
describe('Component vnZoneCreate', () => {
|
describe('Component vnZoneCreate', () => {
|
||||||
let $scope;
|
let $scope;
|
||||||
let $state;
|
let $state;
|
||||||
|
|
|
@ -14,36 +14,34 @@
|
||||||
on-change="$ctrl.onMoreChange(value)">
|
on-change="$ctrl.onMoreChange(value)">
|
||||||
</vn-icon-menu>
|
</vn-icon-menu>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal pad-medium>
|
<vn-vertical pad-medium>
|
||||||
<vn-one>
|
<vn-one>
|
||||||
<vn-label-value label="Id"
|
<vn-label-value label="Id"
|
||||||
value="{{::$ctrl.zone.id}}">
|
value="{{$ctrl.zone.id}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
<vn-label-value label="Name"
|
<vn-label-value label="Name"
|
||||||
value="{{::$ctrl.zone.name}}">
|
value="{{$ctrl.zone.name}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
<vn-label-value label="Warehouse"
|
<vn-label-value label="Warehouse"
|
||||||
value="{{::$ctrl.zone.warehouse.name}}">
|
value="{{$ctrl.zone.warehouse.name}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
<vn-label-value label="Agency"
|
<vn-label-value label="Agency"
|
||||||
value="{{::$ctrl.zone.agencyMode.name}}">
|
value="{{$ctrl.zone.agencyMode.name}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
</vn-one>
|
|
||||||
<vn-one>
|
|
||||||
<vn-label-value label="Estimated hour (ETD)"
|
<vn-label-value label="Estimated hour (ETD)"
|
||||||
value="{{::$ctrl.zone.hour | date: 'HH:mm'}}">
|
value="{{$ctrl.zone.hour | date: 'HH:mm'}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
<vn-label-value label="Traveling days"
|
<vn-label-value label="Traveling days"
|
||||||
value="{{::$ctrl.zone.travelingDays}}">
|
value="{{$ctrl.zone.travelingDays}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
<vn-label-value label="Price"
|
<vn-label-value label="Price"
|
||||||
value="{{::$ctrl.zone.price | currency: '€': 2}}">
|
value="{{$ctrl.zone.price | currency: '€': 2}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
<vn-label-value label="Bonus"
|
<vn-label-value label="Bonus"
|
||||||
value="{{::$ctrl.zone.price | currency: '€': 2}}">
|
value="{{$ctrl.zone.price | currency: '€': 2}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
</vn-one>
|
</vn-one>
|
||||||
</vn-horizontal>
|
</vn-vertical>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
|
|
||||||
<vn-confirm
|
<vn-confirm
|
||||||
|
|
|
@ -6,7 +6,6 @@ class Controller {
|
||||||
this.$state = $state;
|
this.$state = $state;
|
||||||
this.$http = $http;
|
this.$http = $http;
|
||||||
this.moreOptions = [
|
this.moreOptions = [
|
||||||
{callback: this.editZone, name: 'Settings'},
|
|
||||||
{callback: this.deleteZone, name: 'Delete'}
|
{callback: this.deleteZone, name: 'Delete'}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -19,10 +18,6 @@ class Controller {
|
||||||
this.$scope.deleteZone.show();
|
this.$scope.deleteZone.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
editZone() {
|
|
||||||
this.$state.go('zone.card.edit', {zone: this.zone});
|
|
||||||
}
|
|
||||||
|
|
||||||
returnDialog(response) {
|
returnDialog(response) {
|
||||||
if (response === 'ACCEPT') {
|
if (response === 'ACCEPT') {
|
||||||
this.$http.delete(`/agency/api/Zones/${this.zone.id}`).then(() => {
|
this.$http.delete(`/agency/api/Zones/${this.zone.id}`).then(() => {
|
||||||
|
|
|
@ -6,6 +6,6 @@ import './card';
|
||||||
import './descriptor';
|
import './descriptor';
|
||||||
import './search-panel';
|
import './search-panel';
|
||||||
import './create';
|
import './create';
|
||||||
import './edit';
|
import './basic-data';
|
||||||
import './location';
|
import './location';
|
||||||
import './calendar';
|
import './calendar';
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
<vn-td number>{{::zone.price | currency:'€':2}}</vn-td>
|
<vn-td number>{{::zone.price | currency:'€':2}}</vn-td>
|
||||||
<vn-td>
|
<vn-td>
|
||||||
<vn-icon-button
|
<vn-icon-button
|
||||||
ng-click="$ctrl.preview(zone)"
|
ng-click="$ctrl.preview($event, zone)"
|
||||||
vn-tooltip="Preview"
|
vn-tooltip="Preview"
|
||||||
icon="desktop_windows">
|
icon="desktop_windows">
|
||||||
</vn-icon-button>
|
</vn-icon-button>
|
||||||
|
@ -54,6 +54,13 @@
|
||||||
</vn-card>
|
</vn-card>
|
||||||
<vn-pagination model="model"></vn-pagination>
|
<vn-pagination model="model"></vn-pagination>
|
||||||
</div>
|
</div>
|
||||||
|
<vn-dialog
|
||||||
|
vn-id="summary"
|
||||||
|
class="dialog-summary">
|
||||||
|
<tpl-body>
|
||||||
|
<vn-zone-summary zone="$ctrl.zoneSelected"></vn-zone-summary>
|
||||||
|
</tpl-body>
|
||||||
|
</vn-dialog>
|
||||||
|
|
||||||
<a ui-sref="zone.create" vn-tooltip="New zone" vn-bind="+" fixed-bottom-right>
|
<a ui-sref="zone.create" vn-tooltip="New zone" vn-bind="+" fixed-bottom-right>
|
||||||
<vn-float-button icon="add"></vn-float-button>
|
<vn-float-button icon="add"></vn-float-button>
|
||||||
|
|
|
@ -26,8 +26,8 @@ export default class Controller {
|
||||||
preview(event, zone) {
|
preview(event, zone) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopImmediatePropagation();
|
event.stopImmediatePropagation();
|
||||||
this.$scope.summary.zone = zone;
|
this.zoneSelected = zone;
|
||||||
this.$scope.dialog.show();
|
this.$scope.summary.show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import './index.js';
|
import './index.js';
|
||||||
|
|
||||||
describe('Agency', () => {
|
xdescribe('Agency', () => {
|
||||||
describe('Component vnZoneIndex', () => {
|
describe('Component vnZoneIndex', () => {
|
||||||
let $componentController;
|
let $componentController;
|
||||||
let controller;
|
let controller;
|
||||||
|
|
|
@ -6,7 +6,7 @@ Price: Precio
|
||||||
Create: Crear
|
Create: Crear
|
||||||
Delete: Eliminar
|
Delete: Eliminar
|
||||||
Settings: Ajustes
|
Settings: Ajustes
|
||||||
Delivery days: Días de envío
|
Locations: Localizaciones
|
||||||
Enter a new search: Introduce una nueva búsqueda
|
Enter a new search: Introduce una nueva búsqueda
|
||||||
Delete zone: Eliminar zona
|
Delete zone: Eliminar zona
|
||||||
Are you sure you want to delete this zone?: ¿Estás seguro de querer eliminar esta zona?
|
Are you sure you want to delete this zone?: ¿Estás seguro de querer eliminar esta zona?
|
||||||
|
@ -15,4 +15,4 @@ Zones: Zonas
|
||||||
List: Listado
|
List: Listado
|
||||||
Summary: Vista previa
|
Summary: Vista previa
|
||||||
New zone: Nueva zona
|
New zone: Nueva zona
|
||||||
Edit zone: Editar zona
|
Basic data: Datos básicos
|
|
@ -1,18 +1,26 @@
|
||||||
<vn-crud-model
|
<vn-crud-model
|
||||||
vn-id="model"
|
vn-id="model"
|
||||||
url="/agency/api/ZoneGeos"
|
url="/agency/api/ZoneTreeviews/getLeaves"
|
||||||
data="geos">
|
filter="::$ctrl.filter"
|
||||||
|
params="{zoneFk: $ctrl.$stateParams.id, parentFk: 1}">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
|
|
||||||
<vn-vertical vn-one>
|
<vn-horizontal>
|
||||||
<vn-card pad-large>
|
<vn-vertical vn-one>
|
||||||
<vn-title>Delivery days</vn-title>
|
<vn-card pad-large>
|
||||||
<vn-searchbar
|
<vn-title>Locations</vn-title>
|
||||||
panel="vn-calendar-search-panel"
|
<vn-searchbar
|
||||||
model="model"
|
model="model"
|
||||||
expr-builder="$ctrl.exprBuilder(param, value)"
|
expr-builder="$ctrl.exprBuilder(param, value)"
|
||||||
vn-focus>
|
on-search="$ctrl.onSearch()"
|
||||||
</vn-searchbar>
|
vn-focus>
|
||||||
<vn-treeview model="model"></vn-treeview>
|
</vn-searchbar>
|
||||||
</vn-card>
|
<vn-treeview vn-id="treeview" model="model"
|
||||||
</vn-vertical>
|
on-selection="$ctrl.onSelection(item)">
|
||||||
|
</vn-treeview>
|
||||||
|
</vn-card>
|
||||||
|
</vn-vertical>
|
||||||
|
<vn-auto class="right-block">
|
||||||
|
<vn-zone-calendar zone="::$ctrl.zone"></vn-zone-calendar>
|
||||||
|
</vn-auto>
|
||||||
|
</vn-horizontal>
|
|
@ -1,12 +1,37 @@
|
||||||
import ngModule from '../module';
|
import ngModule from '../module';
|
||||||
|
|
||||||
class Controller {
|
class Controller {
|
||||||
constructor($scope) {
|
constructor($scope, $http, $stateParams) {
|
||||||
|
this.$stateParams = $stateParams;
|
||||||
this.$scope = $scope;
|
this.$scope = $scope;
|
||||||
|
this.$http = $http;
|
||||||
|
this.searchValue = '';
|
||||||
|
this.filter = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
onSearch() {
|
||||||
|
this.$scope.$$postDigest(() => {
|
||||||
|
this.$scope.treeview.refresh();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
exprBuilder(param, value) {
|
||||||
|
switch (param) {
|
||||||
|
case 'search':
|
||||||
|
return {name: {like: `%${value}%`}};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onSelection(item) {
|
||||||
|
const path = '/agency/api/ZoneIncludeds/toggleIsIncluded';
|
||||||
|
const params = {geoFk: item.id, zoneFk: this.zone.id};
|
||||||
|
this.$http.post(path, params).then(() => {
|
||||||
|
this.$scope.treeview.repaintNode(item);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.$inject = ['$scope'];
|
Controller.$inject = ['$scope', '$http', '$stateParams'];
|
||||||
|
|
||||||
ngModule.component('vnZoneLocation', {
|
ngModule.component('vnZoneLocation', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
|
|
|
@ -32,23 +32,26 @@
|
||||||
"description": "Detail"
|
"description": "Detail"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"url": "/location",
|
"url": "/location?q",
|
||||||
"state": "zone.card.location",
|
"state": "zone.card.location",
|
||||||
"component": "vn-zone-location",
|
"component": "vn-zone-location",
|
||||||
"description": "Location",
|
"description": "Locations",
|
||||||
"params": {
|
"params": {
|
||||||
"zone": "$ctrl.zone"
|
"zone": "$ctrl.zone"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"url": "/edit",
|
"url": "/basic-data",
|
||||||
"state": "zone.card.edit",
|
"state": "zone.card.basicData",
|
||||||
"component": "vn-zone-edit",
|
"component": "vn-zone-basic-data",
|
||||||
"description": "Edit zone",
|
"description": "Basic data",
|
||||||
"params": {
|
"params": {
|
||||||
"zone": "$ctrl.zone"
|
"zone": "$ctrl.zone"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"menu": []
|
"menu": [
|
||||||
|
{"state": "zone.card.basicData", "icon": "settings"},
|
||||||
|
{"state": "zone.card.location", "icon": "my_location"}
|
||||||
|
]
|
||||||
}
|
}
|
|
@ -1,30 +1,37 @@
|
||||||
<vn-card class="summary">
|
<vn-card class="summary">
|
||||||
<vn-vertical pad-medium>
|
<vn-vertical pad-medium>
|
||||||
<vn-horizontal>
|
<vn-auto>
|
||||||
<vn-one margin-medium>
|
<h5 text-center pad-small-v class="title">{{$ctrl.summary.name}}</h5>
|
||||||
<vn-vertical name="basicData">
|
</vn-auto>
|
||||||
<h5 translate>Basic data</h5>
|
<vn-horizontal pad-medium>
|
||||||
<vn-label-value label="Name"
|
<vn-one>
|
||||||
value="{{$ctrl.zone.name}}">
|
<vn-label-value label="Id"
|
||||||
</vn-label-value>
|
value="{{::$ctrl.summary.id}}">
|
||||||
<vn-label-value label="Warehouse"
|
</vn-label-value>
|
||||||
value="{{$ctrl.zone.warehouse.name}}">
|
<vn-label-value label="Name"
|
||||||
</vn-label-value>
|
value="{{::$ctrl.summary.name}}">
|
||||||
<vn-label-value label="Agency"
|
</vn-label-value>
|
||||||
value="{{$ctrl.zone.agencyMode.name}}">
|
<vn-label-value label="Warehouse"
|
||||||
</vn-label-value>
|
value="{{::$ctrl.summary.warehouse.name}}">
|
||||||
<vn-label-value label="Estimated hour (ETD)"
|
</vn-label-value>
|
||||||
value="{{$ctrl.zone.hour | date: 'HH:mm'}}">
|
<vn-label-value label="Agency"
|
||||||
</vn-label-value>
|
value="{{::$ctrl.summary.agencyMode.name}}">
|
||||||
<vn-label-value label="Price"
|
</vn-label-value>
|
||||||
value="{{$ctrl.zone.price | currency: '€': 2}}">
|
</vn-one>
|
||||||
</vn-label-value>
|
<vn-one>
|
||||||
<vn-label-value label="Bonus"
|
<vn-label-value label="Estimated hour (ETD)"
|
||||||
value="{{$ctrl.zone.price | currency: '€': 2}}">
|
value="{{::$ctrl.summary.hour | date: 'HH:mm'}}">
|
||||||
</vn-label-value>
|
</vn-label-value>
|
||||||
</vn-vertical>
|
<vn-label-value label="Traveling days"
|
||||||
|
value="{{::$ctrl.summary.travelingDays}}">
|
||||||
|
</vn-label-value>
|
||||||
|
<vn-label-value label="Price"
|
||||||
|
value="{{::$ctrl.summary.price | currency: '€': 2}}">
|
||||||
|
</vn-label-value>
|
||||||
|
<vn-label-value label="Bonus"
|
||||||
|
value="{{::$ctrl.summary.price | currency: '€': 2}}">
|
||||||
|
</vn-label-value>
|
||||||
</vn-one>
|
</vn-one>
|
||||||
<vn-one margin-medium></vn-one>
|
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
</vn-vertical>
|
</vn-vertical>
|
||||||
</vn-card>
|
</vn-card>
|
|
@ -18,8 +18,17 @@ class Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
getSummary() {
|
getSummary() {
|
||||||
this.$http.get(`/agency/api/Zones/${this.zone.id}`).then(response => {
|
let filter = {
|
||||||
this.summary = response.data;
|
include: [
|
||||||
|
{relation: 'warehouse', fields: ['name']},
|
||||||
|
{relation: 'agencyMode', fields: ['name']}
|
||||||
|
],
|
||||||
|
where: {id: this.zone.id}
|
||||||
|
};
|
||||||
|
filter = encodeURIComponent(JSON.stringify((filter)));
|
||||||
|
this.$http.get(`/agency/api/Zones/findOne?filter=${filter}`).then(res => {
|
||||||
|
if (res && res.data)
|
||||||
|
this.summary = res.data;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,9 +36,9 @@ export default class Controller {
|
||||||
case 'search':
|
case 'search':
|
||||||
return /^\d+$/.test(value)
|
return /^\d+$/.test(value)
|
||||||
? {id: value}
|
? {id: value}
|
||||||
: {client: {regexp: value}};
|
: {client: {like: `%${value}%`}};
|
||||||
case 'client':
|
case 'client':
|
||||||
return {[param]: {regexp: value}};
|
return {[param]: {like: `%${value}%`}};
|
||||||
case 'created':
|
case 'created':
|
||||||
return {created: {between: [value, value]}};
|
return {created: {between: [value, value]}};
|
||||||
case 'id':
|
case 'id':
|
||||||
|
|
|
@ -23,7 +23,7 @@ export default class Controller {
|
||||||
case 'name':
|
case 'name':
|
||||||
case 'socialName':
|
case 'socialName':
|
||||||
case 'city':
|
case 'city':
|
||||||
return {[param]: {regexp: `%${value}%`}};
|
return {[param]: {like: `%${value}%`}};
|
||||||
case 'id':
|
case 'id':
|
||||||
case 'fi':
|
case 'fi':
|
||||||
case 'postcode':
|
case 'postcode':
|
||||||
|
|
|
@ -26,6 +26,9 @@
|
||||||
},
|
},
|
||||||
"ref": {
|
"ref": {
|
||||||
"type": "String"
|
"type": "String"
|
||||||
|
},
|
||||||
|
"totalEntries": {
|
||||||
|
"type": "Number"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"relations": {
|
"relations": {
|
||||||
|
|
|
@ -35,10 +35,15 @@ export default class Controller {
|
||||||
return {id: value};
|
return {id: value};
|
||||||
case 'ref':
|
case 'ref':
|
||||||
return {[param]: {regexp: value}};
|
return {[param]: {regexp: value}};
|
||||||
|
case 'shipped':
|
||||||
|
return {shipped: {lte: value}};
|
||||||
|
case 'landed':
|
||||||
|
return {landed: {gte: value}};
|
||||||
case 'id':
|
case 'id':
|
||||||
case 'agencyFk':
|
case 'agencyFk':
|
||||||
case 'warehouseOutFk':
|
case 'warehouseOutFk':
|
||||||
case 'warehouseInFk':
|
case 'warehouseInFk':
|
||||||
|
case 'totalEntries':
|
||||||
return {[param]: value};
|
return {[param]: value};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,11 @@
|
||||||
label="Reference"
|
label="Reference"
|
||||||
model="filter.ref">
|
model="filter.ref">
|
||||||
</vn-textfield>
|
</vn-textfield>
|
||||||
|
<vn-textfield
|
||||||
|
vn-one
|
||||||
|
label="Total entries"
|
||||||
|
model="filter.totalEntries">
|
||||||
|
</vn-textfield>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-textfield
|
<vn-textfield
|
||||||
|
@ -29,6 +34,18 @@
|
||||||
value-field="id">
|
value-field="id">
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-date-picker
|
||||||
|
vn-one
|
||||||
|
label="Shipped"
|
||||||
|
model="filter.shipped">
|
||||||
|
</vn-date-picker>
|
||||||
|
<vn-date-picker
|
||||||
|
vn-one
|
||||||
|
label="Landed"
|
||||||
|
model="filter.landed">
|
||||||
|
</vn-date-picker>
|
||||||
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-autocomplete vn-one
|
<vn-autocomplete vn-one
|
||||||
label="Warehouse Out"
|
label="Warehouse Out"
|
||||||
|
|
Loading…
Reference in New Issue