Merge
This commit is contained in:
commit
43fd8fe75e
|
@ -351,16 +351,6 @@ INSERT INTO `vn`.`creditInsurance`(`id`, `creditClassification`, `credit`, `crea
|
|||
(2, 2, 6000, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), NULL),
|
||||
(3, 3, 10000, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), NULL);
|
||||
|
||||
INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agencyModeFk`, `description`, `m3`, `cost`, `started`, `finished`)
|
||||
VALUES
|
||||
(1, '1899-12-30 12:15:00', 56, CURDATE(), 1, 7, 'first route', 2.7, 10, CURDATE(), CURDATE()),
|
||||
(2, '1899-12-30 13:20:00', 56, CURDATE(), 1, 7, 'second route', 0.9, 20, CURDATE(), CURDATE()),
|
||||
(3, '1899-12-30 14:30:00', 56, CURDATE(), 2, 7, 'third route', 1.1, 30, CURDATE(), CURDATE()),
|
||||
(4, '1899-12-30 15:45:00', 56, CURDATE(), 3, 7, 'fourth route', 0.1, 40, CURDATE(), CURDATE()),
|
||||
(5, '1899-12-30 16:00:00', 56, CURDATE(), 4, 8, 'fifth route', NULL, 50, CURDATE(), CURDATE()),
|
||||
(6, NULL, 57, CURDATE(), 5, 8, 'sixth route', NULL, 60, CURDATE(), CURDATE()),
|
||||
(7, NULL, 57, CURDATE(), 6, NULL, 'seventh route', NULL, 70, CURDATE(), CURDATE());
|
||||
|
||||
INSERT INTO `vn2008`.`empresa_grupo`(`empresa_grupo_id`, `grupo`)
|
||||
VALUES
|
||||
(1, 'Wayne Industries');
|
||||
|
@ -456,32 +446,42 @@ INSERT INTO `vn`.`zone` (`id`, `name`, `hour`, `warehouseFk`, `agencyModeFk`, `t
|
|||
(12, 'Zone entanglement', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 4, 4, 0, 0, 0),
|
||||
(13, 'Zone quantum break', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 5, 5, 0, 0, 0);
|
||||
|
||||
INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agencyModeFk`, `description`, `m3`, `cost`, `started`, `finished`, `zoneFk`)
|
||||
VALUES
|
||||
(1, '1899-12-30 12:15:00', 56, CURDATE(), 1, 1, 'first route', 1.8, 10, CURDATE(), CURDATE(), 1),
|
||||
(2, '1899-12-30 13:20:00', 56, CURDATE(), 1, 2, 'second route', 0.2, 20, CURDATE(), CURDATE(), 9),
|
||||
(3, '1899-12-30 14:30:00', 56, CURDATE(), 2, 3, 'third route', 0.5, 30, CURDATE(), CURDATE(), 10),
|
||||
(4, '1899-12-30 15:45:00', 56, CURDATE(), 3, 4, 'fourth route', 0, 40, CURDATE(), CURDATE(), 12),
|
||||
(5, '1899-12-30 16:00:00', 56, CURDATE(), 4, 5, 'fifth route', 0.1, 50, CURDATE(), CURDATE(), 13),
|
||||
(6, NULL, 57, CURDATE(), 5, 7, 'sixth route', 1.7, 60, CURDATE(), CURDATE(), 3),
|
||||
(7, NULL, 57, CURDATE(), 6, 8, 'seventh route', 0, 70, CURDATE(), CURDATE(), 5);
|
||||
|
||||
INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `zoneFk`, `created`)
|
||||
VALUES
|
||||
(1 , 3, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 101, 'Bat cave', 121, 'T1111111', 0, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||
(2 , 1, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T1111111', 0, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||
(3 , 1, 7, 1, 1, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -2 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T2222222', 0, 3, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
|
||||
(4 , 3, 2, 1, 1, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -3 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T3333333', 0, 9, DATE_ADD(CURDATE(), INTERVAL -3 MONTH)),
|
||||
(5 , 3, 3, 3, 1, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -4 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T4444444', 0, 10, DATE_ADD(CURDATE(), INTERVAL -4 MONTH)),
|
||||
(6 , 1, 3, 3, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 101, 'Mountain Drive Gotham', 1, 'A1111111', 0, 10, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||
(7 , NULL, 7, 1, 2, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'Mountain Drive Gotham', 1, NULL, 0, 3, CURDATE()),
|
||||
(8 , NULL, 7, 1, 2, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'Bat cave', 121, NULL, 0, 3, CURDATE()),
|
||||
(9 , NULL, 7, 1, 2, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 104, 'Stark tower', 124, NULL, 0, 3, CURDATE()),
|
||||
(10, 1, 1, 5, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 102, 'Ingram Street', 2, NULL, 0, 11, CURDATE()),
|
||||
(11, 1, 7, 1, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 102, 'NY roofs', 122, NULL, 0, 3, CURDATE()),
|
||||
(12, 1, 1, 1, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 103, 'Phone Box', 123, NULL, 0, 1, CURDATE()),
|
||||
(13, 1, 7, 1, 2, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 103, 'Phone Box', 123, NULL, 0, 1, CURDATE()),
|
||||
(14, 1, 2, 1, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 104, 'Malibu Point', 4, NULL, 0, 9, CURDATE()),
|
||||
(15, 1, 7, 1, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 105, 'Plastic Cell', 125, NULL, 0, 3, CURDATE()),
|
||||
(16, 1, 7, 1, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 106, 'Many Places', 126, NULL, 0, 3, CURDATE()),
|
||||
(17, 1, 7, 2, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 106, 'Many Places', 126, NULL, 0, 3, CURDATE()),
|
||||
(18, 1, 4, 4, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 108, 'Cerebro', 128, NULL, 0, 12, CURDATE()),
|
||||
(19, 1, 5, 5, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 109, 'Somewhere in Thailand', 129, NULL, 1, 13, CURDATE()),
|
||||
(20, 1, 5, 5, 3, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Thailand', 129, NULL, 0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||
(21, NULL, 5, 5, NULL, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Holland', 102, NULL, 0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||
(22, NULL, 5, 5, NULL, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Japan', 103, NULL, 0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||
(23, NULL, 10, 1, NULL, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'address 21', 121, NULL, 0, 8, CURDATE()),
|
||||
(24 ,NULL, 10, 1, NULL, CURDATE(), CURDATE(), 101, 'Bruce Wayne', 1, NULL, 0, 8, CURDATE());
|
||||
(1 , 3, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 101, 'Bat cave', 121, 'T1111111', 0, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||
(2 , 1, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T1111111', 0, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||
(3 , 1, 7, 1, 6, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -2 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T2222222', 0, 3, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
|
||||
(4 , 3, 2, 1, 2, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -3 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T3333333', 0, 9, DATE_ADD(CURDATE(), INTERVAL -3 MONTH)),
|
||||
(5 , 3, 3, 3, 3, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -4 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T4444444', 0, 10, DATE_ADD(CURDATE(), INTERVAL -4 MONTH)),
|
||||
(6 , 1, 3, 3, 3, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 101, 'Mountain Drive Gotham', 1, 'A1111111', 0, 10, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||
(7 , NULL, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'Mountain Drive Gotham', 1, NULL, 0, 3, CURDATE()),
|
||||
(8 , NULL, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'Bat cave', 121, NULL, 0, 3, CURDATE()),
|
||||
(9 , NULL, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 104, 'Stark tower', 124, NULL, 0, 3, CURDATE()),
|
||||
(10, 1, 1, 5, 1, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 102, 'Ingram Street', 2, NULL, 0, 1, CURDATE()),
|
||||
(11, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 102, 'NY roofs', 122, NULL, 0, 3, CURDATE()),
|
||||
(12, 1, 1, 1, 1, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 103, 'Phone Box', 123, NULL, 0, 1, CURDATE()),
|
||||
(13, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 103, 'Phone Box', 123, NULL, 0, 3, CURDATE()),
|
||||
(14, 1, 2, 1, NULL, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 104, 'Malibu Point', 4, NULL, 0, 9, CURDATE()),
|
||||
(15, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 105, 'Plastic Cell', 125, NULL, 0, 3, CURDATE()),
|
||||
(16, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 106, 'Many Places', 126, NULL, 0, 3, CURDATE()),
|
||||
(17, 1, 7, 2, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 106, 'Many Places', 126, NULL, 0, 3, CURDATE()),
|
||||
(18, 1, 4, 4, 4, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 108, 'Cerebro', 128, NULL, 0, 12, CURDATE()),
|
||||
(19, 1, 5, 5, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 109, 'Somewhere in Thailand', 129, NULL, 1, 13, CURDATE()),
|
||||
(20, 1, 5, 5, 3, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Thailand', 129, NULL, 0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||
(21, NULL, 5, 5, 5, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Holland', 102, NULL, 0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||
(22, NULL, 5, 5, 5, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Japan', 103, NULL, 0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||
(23, NULL, 8, 1, 7, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'address 21', 121, NULL, 0, 5, CURDATE()),
|
||||
(24 ,NULL, 8, 1, 7, CURDATE(), CURDATE(), 101, 'Bruce Wayne', 1, NULL, 0, 5, CURDATE());
|
||||
|
||||
INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `description`)
|
||||
VALUES
|
||||
|
|
|
@ -529,13 +529,13 @@ export default {
|
|||
header: 'vn-claim-summary > vn-card > div > h5',
|
||||
state: 'vn-claim-summary vn-label-value[label="State"] > section > span',
|
||||
observation: 'vn-claim-summary vn-textarea[ng-model="$ctrl.summary.claim.observation"] textarea',
|
||||
firstSaleItemId: 'vn-claim-summary vn-horizontal > vn-auto:nth-child(4) > vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(1) > span',
|
||||
firstSaleItemId: 'vn-claim-summary vn-horizontal > vn-auto:nth-child(4) vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(1) > span',
|
||||
firstSaleDescriptorImage: '.vn-popover.shown vn-item-descriptor img',
|
||||
itemDescriptorPopover: '.vn-popover.shown vn-item-descriptor',
|
||||
itemDescriptorPopoverItemDiaryButton: '.vn-popover.shown vn-item-descriptor a[href="#!/item/2/diary"]',
|
||||
firstDevelopmentWorker: 'vn-claim-summary vn-horizontal > vn-auto:nth-child(5) > vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > span',
|
||||
firstDevelopmentWorker: 'vn-claim-summary vn-horizontal > vn-auto:nth-child(5) vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > span',
|
||||
firstDevelopmentWorkerGoToClientButton: '.vn-popover.shown vn-worker-descriptor div.quicklinks > a[href="#!/client/21/summary"]',
|
||||
firstActionTicketId: 'vn-claim-summary > vn-card > div > vn-horizontal > vn-auto:nth-child(6) > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > span',
|
||||
firstActionTicketId: 'vn-claim-summary > vn-card > div > vn-horizontal > vn-auto:nth-child(6) vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > span',
|
||||
firstActionTicketDescriptor: '.vn-popover.shown vn-ticket-descriptor'
|
||||
},
|
||||
claimBasicData: {
|
||||
|
|
|
@ -358,7 +358,7 @@ describe('Worker time control path', () => {
|
|||
it(`should check Hank Pym doesn't have hours set on the next months first week`, async() => {
|
||||
const wholeWeekHours = await nightmare
|
||||
.waitToClick(selectors.workerTimeControl.nextMonthButton)
|
||||
.waitToClick(selectors.workerTimeControl.nextMonthButton)
|
||||
.waitForTextInElement(selectors.workerTimeControl.weekWorkedHours, '00:00 Hours')
|
||||
.waitToGetProperty(selectors.workerTimeControl.weekWorkedHours, 'innerText');
|
||||
|
||||
expect(wholeWeekHours).toEqual('00:00 Hours');
|
||||
|
|
|
@ -30,6 +30,7 @@ describe('Ticket Edit basic data path', () => {
|
|||
|
||||
it(`should confirm the zone autocomplete is enabled for the role productionBoss`, async() => {
|
||||
const disabled = await nightmare
|
||||
.waitForSpinnerLoad()
|
||||
.wait(selectors.ticketBasicData.zoneAutocomplete)
|
||||
.evaluate(selector => {
|
||||
return document.querySelector(selector).disabled;
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<div class="node clickable">
|
||||
<vn-icon
|
||||
class="arrow"
|
||||
ng-class="{invisible: !$ctrl.item.sons}"
|
||||
icon="keyboard_arrow_down"
|
||||
translate-attr="::{title: 'Toggle'}">
|
||||
</vn-icon>
|
||||
<section class="content"></section>
|
||||
<section class="buttons" ng-if="::!$ctrl.treeview.readOnly">
|
||||
<vn-icon-button translate-attr="::{title: 'Remove'}"
|
||||
icon="delete"
|
||||
ng-click="$ctrl.treeview.onRemove($ctrl.item)"
|
||||
ng-if="$ctrl.item.parent">
|
||||
</vn-icon-button>
|
||||
<vn-icon-button translate-attr="::{title: 'Create'}"
|
||||
icon="add_circle"
|
||||
ng-click="$ctrl.treeview.onCreate($ctrl.item)">
|
||||
</vn-icon-button>
|
||||
</section>
|
||||
</div>
|
|
@ -2,22 +2,33 @@ import ngModule from '../../module';
|
|||
|
||||
class Controller {
|
||||
constructor($element, $scope, $compile) {
|
||||
this.$element = $element;
|
||||
this.$scope = $scope;
|
||||
this.$compile = $compile;
|
||||
this.element = $element[0];
|
||||
|
||||
this.element.$ctrl = this;
|
||||
this.element.droppable = true;
|
||||
this.dropCount = 0;
|
||||
this.element.classList.add('vn-droppable');
|
||||
}
|
||||
|
||||
$onInit() {
|
||||
const transcludeElement = this.element.querySelector('.content');
|
||||
const content = angular.element(transcludeElement);
|
||||
|
||||
if (this.item.parent) {
|
||||
this.treeview.$transclude(($clone, $scope) => {
|
||||
this.$contentScope = $scope;
|
||||
$scope.item = this.item;
|
||||
this.$element.append($clone);
|
||||
content.append($clone);
|
||||
});
|
||||
|
||||
this.element.draggable = true;
|
||||
this.element.classList.add('vn-draggable');
|
||||
} else {
|
||||
let template = `<span translate>{{$ctrl.treeview.rootLabel}}</span>`;
|
||||
let $clone = this.$compile(template)(this.$scope);
|
||||
this.$element.append($clone);
|
||||
content.append($clone);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,10 +36,21 @@ class Controller {
|
|||
if (this.$contentScope)
|
||||
this.$contentScope.$destroy();
|
||||
}
|
||||
|
||||
dragEnter() {
|
||||
this.dropCount++;
|
||||
|
||||
if (element != this.dropping) {
|
||||
this.undrop();
|
||||
if (element) element.classList.add('dropping');
|
||||
this.dropping = element;
|
||||
}
|
||||
}
|
||||
}
|
||||
Controller.$inject = ['$element', '$scope', '$compile'];
|
||||
|
||||
ngModule.component('vnTreeviewContent', {
|
||||
ngModule.component('vnTreeviewChild', {
|
||||
template: require('./child.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
item: '<'
|
|
@ -1,34 +1,11 @@
|
|||
|
||||
<ul ng-if="$ctrl.items">
|
||||
<li ng-repeat="item in $ctrl.items" >
|
||||
<div
|
||||
ng-class="{expanded: item.active}"
|
||||
ng-click="$ctrl.onClick($event, item)"
|
||||
class="node clickable">
|
||||
<vn-icon
|
||||
class="arrow"
|
||||
ng-class="{invisible: !item.sons}"
|
||||
icon="keyboard_arrow_down"
|
||||
translate-attr="::{title: 'Toggle'}">
|
||||
</vn-icon>
|
||||
<vn-treeview-content
|
||||
item="::item">
|
||||
</vn-treeview-content>
|
||||
<section class="buttons" ng-if="::!$ctrl.treeview.readOnly">
|
||||
<vn-icon-button translate-attr="::{title: 'Remove'}"
|
||||
icon="delete"
|
||||
ng-click="$ctrl.treeview.onRemove(item)"
|
||||
ng-if="item.parent">
|
||||
</vn-icon-button>
|
||||
<vn-icon-button translate-attr="::{title: 'Create'}"
|
||||
icon="add_circle"
|
||||
ng-click="$ctrl.treeview.onCreate(item)">
|
||||
</vn-icon-button>
|
||||
</section>
|
||||
</div>
|
||||
<li ng-repeat="item in $ctrl.items">
|
||||
<vn-treeview-child item="item" ng-class="{expanded: item.active}"
|
||||
ng-click="$ctrl.onClick($event, item)">
|
||||
</vn-treeview-child>
|
||||
<vn-treeview-childs
|
||||
items="item.childs"
|
||||
parent="::item">
|
||||
items="item.childs">
|
||||
</vn-treeview-childs>
|
||||
</li>
|
||||
</ul>
|
|
@ -7,10 +7,6 @@ class Controller extends Component {
|
|||
event.preventDefault();
|
||||
this.treeview.onToggle(item);
|
||||
}
|
||||
|
||||
onDrop(item, dragged, dropped) {
|
||||
this.treeview.onDrop(item, dragged, dropped);
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnTreeviewChilds', {
|
||||
|
|
|
@ -1,18 +1,110 @@
|
|||
import ngModule from '../../module';
|
||||
import Component from '../../lib/component';
|
||||
import './style.scss';
|
||||
|
||||
import './childs';
|
||||
import './content';
|
||||
import './child';
|
||||
|
||||
/**
|
||||
* Treeview
|
||||
*/
|
||||
export default class Treeview extends Component {
|
||||
constructor($element, $scope, $transclude) {
|
||||
constructor($element, $scope, $transclude, $window) {
|
||||
super($element, $scope);
|
||||
this.$transclude = $transclude;
|
||||
this.$window = $window;
|
||||
this.readOnly = true;
|
||||
|
||||
this.element.addEventListener('dragstart',
|
||||
event => this.dragStart(event));
|
||||
this.element.addEventListener('dragend',
|
||||
event => this.dragEnd(event));
|
||||
|
||||
this.element.addEventListener('dragover',
|
||||
event => this.dragOver(event));
|
||||
this.element.addEventListener('drop',
|
||||
event => this.drop(event));
|
||||
this.element.addEventListener('dragenter',
|
||||
event => this.dragEnter(event));
|
||||
this.element.addEventListener('dragleave',
|
||||
event => this.dragLeave(event));
|
||||
|
||||
this.dropCount = 0;
|
||||
}
|
||||
|
||||
undrop() {
|
||||
if (!this.dropping) return;
|
||||
this.dropping.classList.remove('dropping');
|
||||
this.dropping = null;
|
||||
}
|
||||
|
||||
findDroppable(event) {
|
||||
let element = event.target;
|
||||
while (element != this.element && !element.droppable)
|
||||
element = element.parentNode;
|
||||
if (element == this.element)
|
||||
return null;
|
||||
return element;
|
||||
}
|
||||
|
||||
dragOver(event) {
|
||||
this.dragClientY = event.clientY;
|
||||
|
||||
// Prevents page reload
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
onDragInterval() {
|
||||
if (this.dragClientY > 0 && this.dragClientY < 75)
|
||||
this.$window.scrollTo(0, this.$window.scrollY - 25);
|
||||
}
|
||||
|
||||
dragStart(event) {
|
||||
event.target.classList.add('dragging');
|
||||
event.dataTransfer.setData('text', event.target.id);
|
||||
|
||||
const element = this.findDroppable(event);
|
||||
this.dragging = element;
|
||||
|
||||
this.interval = setInterval(() => this.onDragInterval(), 100);
|
||||
}
|
||||
|
||||
dragEnd(event) {
|
||||
event.target.classList.remove('dragging');
|
||||
this.undrop();
|
||||
this.dropCount = 0;
|
||||
this.dragging = null;
|
||||
clearInterval(this.interval);
|
||||
}
|
||||
|
||||
dragEnter(event) {
|
||||
let element = this.findDroppable(event);
|
||||
if (element) this.dropCount++;
|
||||
|
||||
if (element != this.dropping) {
|
||||
this.undrop();
|
||||
if (element) element.classList.add('dropping');
|
||||
this.dropping = element;
|
||||
}
|
||||
}
|
||||
|
||||
dragLeave(event) {
|
||||
let element = this.findDroppable(event);
|
||||
|
||||
if (element) {
|
||||
this.dropCount--;
|
||||
if (this.dropCount == 0) this.undrop();
|
||||
}
|
||||
}
|
||||
|
||||
drop(event) {
|
||||
event.preventDefault();
|
||||
this.element.classList.remove('dropping');
|
||||
|
||||
const $dropped = this.dropping.$ctrl.item;
|
||||
const $dragged = this.dragging.$ctrl.item;
|
||||
|
||||
if ($dropped != $dragged.parent)
|
||||
this.emit('drop', {$dropped, $dragged});
|
||||
}
|
||||
|
||||
get data() {
|
||||
|
@ -109,7 +201,10 @@ export default class Treeview extends Component {
|
|||
let childs = parent.childs;
|
||||
if (!childs) childs = [];
|
||||
|
||||
childs.push(item);
|
||||
if (!parent.active)
|
||||
this.unfold(parent);
|
||||
else
|
||||
childs.push(item);
|
||||
|
||||
if (this.sortFunc) {
|
||||
childs = childs.sort((a, b) =>
|
||||
|
@ -120,12 +215,30 @@ export default class Treeview extends Component {
|
|||
if (parent) parent.sons++;
|
||||
}
|
||||
|
||||
onDrop(item, dragged, dropped) {
|
||||
this.emit('drop', {item, dragged, dropped});
|
||||
move(item, newParent) {
|
||||
if (newParent == item) return;
|
||||
|
||||
if (item.parent) {
|
||||
const parent = item.parent;
|
||||
const childs = parent.childs;
|
||||
const index = childs.indexOf(item);
|
||||
parent.sons--;
|
||||
|
||||
childs.splice(index, 1);
|
||||
}
|
||||
|
||||
item.parent = newParent;
|
||||
|
||||
if (!newParent.active) {
|
||||
this.unfold(newParent).then(() => {
|
||||
item.parent.sons++;
|
||||
});
|
||||
} else
|
||||
this.create(item);
|
||||
}
|
||||
}
|
||||
|
||||
Treeview.$inject = ['$element', '$scope', '$transclude'];
|
||||
Treeview.$inject = ['$element', '$scope', '$transclude', '$window'];
|
||||
|
||||
ngModule.component('vnTreeview', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -0,0 +1,260 @@
|
|||
describe('Component vnTreeview', () => {
|
||||
let controller;
|
||||
let $element;
|
||||
|
||||
beforeEach(angular.mock.module('vnCore', $translateProvider => {
|
||||
$translateProvider.translations('en', {});
|
||||
}));
|
||||
|
||||
beforeEach(inject(($compile, $rootScope) => {
|
||||
$element = $compile(`<vn-treeview></vn-treeview>`)($rootScope);
|
||||
controller = $element.controller('vnTreeview');
|
||||
|
||||
const promise = new Promise(() => {
|
||||
return {name: 'My item'};
|
||||
});
|
||||
|
||||
controller.fetchFunc = () => {
|
||||
return promise;
|
||||
};
|
||||
|
||||
controller.createFunc = () => {
|
||||
return promise;
|
||||
};
|
||||
|
||||
controller.removeFunc = () => {
|
||||
return promise;
|
||||
};
|
||||
|
||||
controller.sortFunc = () => {
|
||||
return promise;
|
||||
};
|
||||
}));
|
||||
|
||||
afterEach(() => {
|
||||
$element.remove();
|
||||
});
|
||||
|
||||
// See how to test DOM element in Jest
|
||||
xdescribe('undrop()', () => {
|
||||
it(`should reset all drop events and properties`, () => {
|
||||
controller.dropping = angular.element(`<vn-treeview-child class="dropping"></vn-treeview-child>`);
|
||||
spyOn(controller.dropping.classList, 'remove');
|
||||
|
||||
controller.undrop();
|
||||
|
||||
expect(controller.dropping).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('dragOver()', () => {
|
||||
it(`should set the dragClientY property`, () => {
|
||||
const event = new Event('dragover');
|
||||
event.clientY = 100;
|
||||
|
||||
controller.dragOver(event);
|
||||
|
||||
expect(controller.dragClientY).toEqual(100);
|
||||
});
|
||||
});
|
||||
|
||||
describe('data() setter', () => {
|
||||
it(`should set the items property nested into a root element`, () => {
|
||||
const items = [{name: 'Item1'}, {name: 'Item2'}];
|
||||
controller.data = items;
|
||||
|
||||
const rootItem = controller.items[0];
|
||||
|
||||
expect(rootItem.childs).toEqual(items);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fetch()', () => {
|
||||
it(`should call the fetchFunc() method`, () => {
|
||||
spyOn(controller, 'fetchFunc').and.returnValue(
|
||||
new Promise(resolve => resolve([{name: 'My item'}]))
|
||||
);
|
||||
controller.fetch().then(() => {
|
||||
expect(controller.data).toBeDefined();
|
||||
});
|
||||
|
||||
expect(controller.fetchFunc).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('setParent()', () => {
|
||||
it(`should set the parent property recursively to each element of an item list`, () => {
|
||||
spyOn(controller, 'setParent').and.callThrough();
|
||||
const items = [{name: 'Item1'}, {name: 'Item2', childs: [
|
||||
{name: 'Item3'}
|
||||
]}];
|
||||
const rootItem = {name: 'Nested tree', sons: items};
|
||||
controller.setParent(rootItem, items);
|
||||
|
||||
expect(items[0].parent).toEqual(rootItem);
|
||||
expect(items[1].parent).toEqual(rootItem);
|
||||
expect(controller.setParent).toHaveBeenCalledWith(rootItem, items[1].childs);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onToggle()', () => {
|
||||
it(`should call the fold() or unfold() methods`, () => {
|
||||
spyOn(controller, 'fold');
|
||||
spyOn(controller, 'unfold');
|
||||
|
||||
const item = {name: 'My item'};
|
||||
|
||||
controller.onToggle(item);
|
||||
item.active = true;
|
||||
controller.onToggle(item);
|
||||
|
||||
expect(controller.unfold).toHaveBeenCalledWith(item);
|
||||
expect(controller.fold).toHaveBeenCalledWith(item);
|
||||
});
|
||||
});
|
||||
|
||||
describe('fold()', () => {
|
||||
it(`should remove the childs and set the active property to false`, () => {
|
||||
const item = {name: 'My item', childs: [{name: 'Item 1'}], active: true};
|
||||
|
||||
controller.fold(item);
|
||||
|
||||
expect(item.childs).toBeUndefined();
|
||||
expect(item.active).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('unfold()', () => {
|
||||
it(`should unfold a parent item`, () => {
|
||||
const expectedResponse = [{name: 'Item 1'}, {name: 'Item 2'}];
|
||||
spyOn(controller, 'fetchFunc').and.returnValue(
|
||||
new Promise(resolve => resolve(expectedResponse))
|
||||
);
|
||||
spyOn(controller, 'setParent');
|
||||
spyOn(controller, 'sortFunc');
|
||||
const parent = {name: 'My item', sons: 1};
|
||||
const child = {name: 'Item 1'};
|
||||
child.parent = parent;
|
||||
parent.childs = [child];
|
||||
|
||||
controller.unfold(parent).then(() => {
|
||||
expect(controller.fetchFunc).toHaveBeenCalledWith({$item: parent});
|
||||
expect(controller.setParent).toHaveBeenCalledWith(parent, expectedResponse);
|
||||
expect(controller.sortFunc).toHaveBeenCalledWith(jasmine.any(Object));
|
||||
expect(parent.active).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('onRemove()', () => {
|
||||
it(`should call the removeFunc() method`, () => {
|
||||
spyOn(controller, 'removeFunc');
|
||||
const item = {name: 'My item'};
|
||||
controller.onRemove(item);
|
||||
|
||||
expect(controller.removeFunc).toHaveBeenCalledWith({$item: item});
|
||||
});
|
||||
});
|
||||
|
||||
describe('remove()', () => {
|
||||
it(`should remove a child element`, () => {
|
||||
const parent = {name: 'My item', sons: 1};
|
||||
const child = {name: 'Item 1'};
|
||||
child.parent = parent;
|
||||
parent.childs = [child];
|
||||
|
||||
controller.remove(child);
|
||||
|
||||
expect(parent.childs).toEqual([]);
|
||||
expect(parent.sons).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onCreate()', () => {
|
||||
it(`should call the createFunc() method`, () => {
|
||||
spyOn(controller, 'createFunc');
|
||||
const parent = {name: 'My item'};
|
||||
controller.onCreate(parent);
|
||||
|
||||
expect(controller.createFunc).toHaveBeenCalledWith({$parent: parent});
|
||||
});
|
||||
});
|
||||
|
||||
describe('create()', () => {
|
||||
it(`should unfold an inactive parent and then create a child`, () => {
|
||||
spyOn(controller, 'unfold');
|
||||
spyOn(controller, 'sortFunc');
|
||||
const parent = {name: 'My item', sons: 2, childs: [
|
||||
{name: 'Item 1'},
|
||||
{name: 'Item 2'}
|
||||
]};
|
||||
const child = {name: 'Item 3'};
|
||||
child.parent = parent;
|
||||
parent.childs.push(child);
|
||||
|
||||
controller.create(child);
|
||||
|
||||
expect(parent.sons).toEqual(3);
|
||||
expect(controller.unfold).toHaveBeenCalledWith(parent);
|
||||
expect(controller.sortFunc).toHaveBeenCalledWith(jasmine.any(Object));
|
||||
expect(controller.sortFunc).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it(`should create a child on an active parent`, () => {
|
||||
spyOn(controller, 'unfold');
|
||||
spyOn(controller, 'sortFunc');
|
||||
const parent = {name: 'My item', sons: 2, childs: [
|
||||
{name: 'Item 1'},
|
||||
{name: 'Item 2'}
|
||||
], active: true};
|
||||
const child = {name: 'Item 3'};
|
||||
child.parent = parent;
|
||||
|
||||
controller.create(child);
|
||||
|
||||
expect(parent.sons).toEqual(3);
|
||||
expect(controller.unfold).not.toHaveBeenCalledWith(parent);
|
||||
expect(controller.sortFunc).toHaveBeenCalledWith(jasmine.any(Object));
|
||||
expect(controller.sortFunc).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('move()', () => {
|
||||
it(`should move an item to anocher parent and then unfold the parent`, () => {
|
||||
spyOn(controller, 'unfold').and.returnValue(
|
||||
new Promise(resolve => resolve())
|
||||
);
|
||||
const newParent = {name: 'My item 2', sons: 0};
|
||||
const parent = {name: 'My item', sons: 3, childs: [
|
||||
{name: 'Item 1'},
|
||||
{name: 'Item 2'}
|
||||
]};
|
||||
const child = {name: 'Item 3'};
|
||||
child.parent = parent;
|
||||
parent.childs.push(child);
|
||||
|
||||
controller.move(child, newParent);
|
||||
|
||||
expect(parent.sons).toEqual(2);
|
||||
expect(controller.unfold).toHaveBeenCalledWith(newParent);
|
||||
});
|
||||
|
||||
it(`should move an item to anocher parent`, () => {
|
||||
spyOn(controller, 'unfold');
|
||||
spyOn(controller, 'create');
|
||||
const newParent = {name: 'My item 2', sons: 0, active: true};
|
||||
const parent = {name: 'My item', sons: 3, childs: [
|
||||
{name: 'Item 1'},
|
||||
{name: 'Item 2'}
|
||||
]};
|
||||
const child = {name: 'Item 3'};
|
||||
child.parent = parent;
|
||||
parent.childs.push(child);
|
||||
|
||||
controller.move(child, newParent);
|
||||
|
||||
expect(parent.sons).toEqual(2);
|
||||
expect(controller.unfold).not.toHaveBeenCalledWith(newParent);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -10,22 +10,6 @@ vn-treeview-childs {
|
|||
li {
|
||||
list-style: none;
|
||||
|
||||
& > .node {
|
||||
@extend %clickable;
|
||||
display: flex;
|
||||
padding: 5px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
& > div > .arrow {
|
||||
min-width: 24px;
|
||||
margin-right: 10px;
|
||||
transition: transform 200ms;
|
||||
}
|
||||
|
||||
& > div.expanded > .arrow {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
ul {
|
||||
padding-left: 2.2em;
|
||||
}
|
||||
|
@ -45,8 +29,28 @@ vn-treeview-childs {
|
|||
.node:hover > .buttons {
|
||||
display: block
|
||||
}
|
||||
|
||||
.content {
|
||||
flex-grow: 1
|
||||
}
|
||||
}
|
||||
|
||||
vn-treeview-content {
|
||||
flex-grow: 1
|
||||
}
|
||||
vn-treeview-child {
|
||||
font-size: 16px;
|
||||
display: block;
|
||||
|
||||
.node {
|
||||
@extend %clickable;
|
||||
display: flex;
|
||||
padding: 5px;
|
||||
align-items: center;
|
||||
}
|
||||
& > div > .arrow {
|
||||
min-width: 24px;
|
||||
margin-right: 10px;
|
||||
transition: transform 200ms;
|
||||
}
|
||||
&.expanded > div > .arrow {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
/**
|
||||
* Enables a draggable element and his drag events
|
||||
*
|
||||
* @return {Object} The directive
|
||||
*/
|
||||
export function directive() {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function($scope, $element, $attrs) {
|
||||
const element = $element[0];
|
||||
const isDraggable = $attrs.vnDraggable === 'true';
|
||||
|
||||
if (!isDraggable) return;
|
||||
|
||||
// Set draggable style properties
|
||||
element.style.cursor = 'move';
|
||||
|
||||
|
||||
// Enable as draggable element
|
||||
element.setAttribute('draggable', true);
|
||||
|
||||
/**
|
||||
* Fires when a drag event starts
|
||||
*/
|
||||
element.addEventListener('dragstart', event => {
|
||||
element.style.opacity = 0.5;
|
||||
event.stopPropagation();
|
||||
});
|
||||
|
||||
/**
|
||||
* Fires when a drag event ends
|
||||
*/
|
||||
element.addEventListener('dragend', event => {
|
||||
element.style.opacity = 1;
|
||||
event.stopPropagation();
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
ngModule.directive('vnDraggable', directive);
|
|
@ -1,68 +1,43 @@
|
|||
import ngModule from '../module';
|
||||
import './droppable.scss';
|
||||
|
||||
export function directive($parse) {
|
||||
return {
|
||||
restrict: 'A',
|
||||
link: function($scope, $element, $attrs) {
|
||||
const element = $element[0];
|
||||
const onDropEvent = $parse($attrs.onDrop);
|
||||
const isDroppable = $attrs.vnDroppable === 'true';
|
||||
class Controller {
|
||||
constructor($element, $, $attrs) {
|
||||
this.element = $element[0];
|
||||
this.$ = $;
|
||||
this.$attrs = $attrs;
|
||||
|
||||
if (!isDroppable) return;
|
||||
this.element.addEventListener('dragover',
|
||||
event => event.preventDefault()); // Prevents page reload
|
||||
this.element.addEventListener('drop',
|
||||
event => this.drop(event));
|
||||
this.element.addEventListener('dragenter',
|
||||
event => this.dragEnter(event));
|
||||
this.element.addEventListener('dragleave',
|
||||
event => this.dragLeave(event));
|
||||
}
|
||||
|
||||
/**
|
||||
* Captures current dragging element
|
||||
*/
|
||||
element.addEventListener('dragstart', () => {
|
||||
this.dragged = element;
|
||||
});
|
||||
dragEnter(event) {
|
||||
this.droppedElement = event.target;
|
||||
this.element.classList.add('dropping');
|
||||
}
|
||||
|
||||
/**
|
||||
* Enter droppable area event
|
||||
*/
|
||||
element.addEventListener('dragenter', event => {
|
||||
element.classList.add('active');
|
||||
dragLeave(event) {
|
||||
if (this.droppedElement === event.target)
|
||||
this.element.classList.remove('dropping');
|
||||
}
|
||||
|
||||
event.stopImmediatePropagation();
|
||||
event.preventDefault();
|
||||
}, false);
|
||||
|
||||
|
||||
/**
|
||||
* Exit droppable area event
|
||||
*/
|
||||
element.addEventListener('dragleave', event => {
|
||||
element.classList.remove('active');
|
||||
|
||||
event.stopImmediatePropagation();
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
/**
|
||||
* Prevent dragover for allowing
|
||||
* dispatch drop event
|
||||
*/
|
||||
element.addEventListener('dragover', event => {
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
/**
|
||||
* Fires when a drop events
|
||||
*/
|
||||
element.addEventListener('drop', event => {
|
||||
element.classList.remove('active');
|
||||
|
||||
onDropEvent($scope, {event});
|
||||
|
||||
event.stopPropagation();
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
};
|
||||
drop(event) {
|
||||
if (event.defaultPrevented) return;
|
||||
event.preventDefault();
|
||||
this.element.classList.remove('dropping');
|
||||
this.$.$eval(this.$attrs.vnDroppable, {$event: event});
|
||||
}
|
||||
}
|
||||
Controller.$inject = ['$element', '$scope', '$attrs'];
|
||||
|
||||
directive.$inject = ['$parse'];
|
||||
|
||||
ngModule.directive('vnDroppable', directive);
|
||||
ngModule.directive('vnDroppable', () => {
|
||||
return {
|
||||
controller: Controller
|
||||
};
|
||||
});
|
||||
|
|
|
@ -1,11 +1,25 @@
|
|||
@import "./variables";
|
||||
|
||||
|
||||
.vn-droppable,
|
||||
.vn-draggable,
|
||||
[vn-droppable] {
|
||||
border: 2px dashed transparent;
|
||||
border-radius: 0.5em;
|
||||
transition: all 0.5s;
|
||||
}
|
||||
|
||||
&.active {
|
||||
.vn-droppable,
|
||||
[vn-droppable] {
|
||||
display: block;
|
||||
|
||||
&.dropping {
|
||||
background-color: $color-hover-cd;
|
||||
border: 2px dashed $color-bg-dark;
|
||||
border-color: $color-bg-dark;
|
||||
}
|
||||
}
|
||||
|
||||
.vn-draggable.dragging {
|
||||
background-color: $color-main-light;
|
||||
border-color: $color-main;
|
||||
}
|
|
@ -11,7 +11,6 @@ import './bind';
|
|||
import './repeat-last';
|
||||
import './title';
|
||||
import './uvc';
|
||||
import './draggable';
|
||||
import './droppable';
|
||||
import './http-click';
|
||||
import './http-submit';
|
||||
|
|
|
@ -24,10 +24,12 @@ export default class EventEmitter {
|
|||
*/
|
||||
off(callback) {
|
||||
if (!this.$events) return;
|
||||
for (let event in this.$events)
|
||||
for (let i = 0; i < event.length; i++)
|
||||
for (let event in this.$events) {
|
||||
for (let i = 0; i < event.length; i++) {
|
||||
if (event[i].callback === callback)
|
||||
event.splice(i--, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -37,10 +39,12 @@ export default class EventEmitter {
|
|||
*/
|
||||
disconnect(thisArg) {
|
||||
if (!this.$events) return;
|
||||
for (let event in this.$events)
|
||||
for (let i = 0; i < event.length; i++)
|
||||
for (let event in this.$events) {
|
||||
for (let i = 0; i < event.length; i++) {
|
||||
if (event[i].thisArg === thisArg)
|
||||
event.splice(i--, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -72,9 +76,10 @@ export default class EventEmitter {
|
|||
if (this[prop])
|
||||
this[prop].disconnect(this);
|
||||
this[prop] = value;
|
||||
if (value)
|
||||
if (value) {
|
||||
for (let event in handlers)
|
||||
value.on(event, handlers[event], this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -109,5 +109,7 @@
|
|||
"is invalid": "is invalid",
|
||||
"The postcode doesn't exists. Ensure you put the correct format": "El código postal no existe. Asegúrate de ponerlo con el formato correcto",
|
||||
"The department name can't be repeated": "El nombre del departamento no puede repetirse",
|
||||
"You cannot move a parent to any of its sons": "You cannot move a parent to any of its sons",
|
||||
"You cannot move a parent to its own sons": "You cannot move a parent to its own sons",
|
||||
"You can't create a claim for a removed ticket": "No puedes crear una reclamación para un ticket eliminado"
|
||||
}
|
|
@ -1,14 +1,14 @@
|
|||
@import "variables";
|
||||
|
||||
vn-treeview-content {
|
||||
& > vn-check:not(.indeterminate) {
|
||||
vn-treeview-child {
|
||||
.content > vn-check:not(.indeterminate) {
|
||||
color: $color-main;
|
||||
|
||||
& > .btn {
|
||||
border-color: $color-main;
|
||||
}
|
||||
}
|
||||
& > vn-check.checked {
|
||||
.content > vn-check.checked {
|
||||
color: $color-main;
|
||||
}
|
||||
}
|
|
@ -1,123 +1,119 @@
|
|||
<vn-crud-model auto-load="false"
|
||||
<vn-crud-model auto-load="true"
|
||||
vn-id="model"
|
||||
url="claim/api/ClaimEnds"
|
||||
filter="$ctrl.filter"
|
||||
data="$ctrl.salesClaimed">
|
||||
</vn-crud-model>
|
||||
<vn-vertical compact>
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-vertical>
|
||||
<vn-horizontal>
|
||||
<div class="totalBox" ng-show="$ctrl.salesClaimed.length > 0">
|
||||
<vn-label-value label="Total claimed"
|
||||
value="{{$ctrl.claimedTotal | currency: 'EUR':2}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-tool-bar class="vn-mb-md">
|
||||
<vn-button
|
||||
label="Import claim"
|
||||
disabled="$ctrl.claim.claimStateFk == $ctrl.resolvedState"
|
||||
vn-http-click="$ctrl.importToNewRefundTicket()"p
|
||||
vn-tooltip="Imports claim details">
|
||||
</vn-button>
|
||||
<vn-button
|
||||
label="Import ticket"
|
||||
disabled="$ctrl.claim.claimStateFk == $ctrl.resolvedState"
|
||||
ng-click="$ctrl.showLastTickets($event)"
|
||||
vn-tooltip="Imports ticket lines">
|
||||
</vn-button>
|
||||
<vn-range
|
||||
vn-one
|
||||
label="Responsability"
|
||||
min-label="Company"
|
||||
max-label="Sales/Client"
|
||||
ng-model="$ctrl.claim.responsibility"
|
||||
max="$ctrl.maxResponsibility"
|
||||
min="1"
|
||||
step="1"
|
||||
vn-acl="salesAssistant"
|
||||
on-change="$ctrl.saveResponsibility(value)">
|
||||
</vn-range>
|
||||
</vn-tool-bar>
|
||||
<vn-one
|
||||
style = "text-align:right">
|
||||
<vn-check
|
||||
vn-one
|
||||
label="Is paid with mana"
|
||||
ng-model="$ctrl.claim.isChargedToMana"
|
||||
vn-acl="salesAssistant"
|
||||
on-change="$ctrl.saveMana(value)">
|
||||
</vn-check>
|
||||
</vn-one>
|
||||
</vn-horizontal>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th number>Id</vn-th>
|
||||
<vn-th number>Ticket</vn-th>
|
||||
<vn-th>Destination</vn-th>
|
||||
<vn-th>Landed</vn-th>
|
||||
<vn-th number>Quantity</vn-th>
|
||||
<vn-th>Description</vn-th>
|
||||
<vn-th number>Price</vn-th>
|
||||
<vn-th number>Disc.</vn-th>
|
||||
<vn-th number>Total</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr
|
||||
ng-repeat="saleClaimed in $ctrl.salesClaimed"
|
||||
vn-repeat-last on-last="$ctrl.focusLastInput()">
|
||||
<vn-td number>
|
||||
<span
|
||||
ng-click="$ctrl.showDescriptor($event, saleClaimed.sale.itemFk)"
|
||||
class="link">
|
||||
{{saleClaimed.sale.itemFk | zeroFill:6}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td number>
|
||||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showTicketDescriptor($event, saleClaimed.sale.ticketFk)">
|
||||
{{::saleClaimed.sale.ticketFk}}
|
||||
|
||||
<vn-card class="vn-mb-md vn-pa-lg vn-w-lg" style="text-align: right"
|
||||
ng-if="$ctrl.salesClaimed.length > 0">
|
||||
<vn-label-value label="Total claimed"
|
||||
value="{{$ctrl.claimedTotal | currency: 'EUR':2}}">
|
||||
</vn-label-value>
|
||||
</vn-card>
|
||||
|
||||
<vn-card class="vn-pa-lg vn-w-lg">
|
||||
<section class="header">
|
||||
<vn-tool-bar class="vn-mb-md">
|
||||
<vn-button
|
||||
label="Import claim"
|
||||
disabled="$ctrl.claim.claimStateFk == $ctrl.resolvedState"
|
||||
vn-http-click="$ctrl.importToNewRefundTicket()"p
|
||||
translate-attr="{title: 'Imports claim details'}">
|
||||
</vn-button>
|
||||
<vn-button
|
||||
label="Import ticket"
|
||||
disabled="$ctrl.claim.claimStateFk == $ctrl.resolvedState"
|
||||
ng-click="$ctrl.showLastTickets($event)"
|
||||
translate-attr="{title: 'Imports ticket lines'}">
|
||||
</vn-button>
|
||||
<vn-range
|
||||
vn-one
|
||||
label="Responsability"
|
||||
min-label="Company"
|
||||
max-label="Sales/Client"
|
||||
ng-model="$ctrl.claim.responsibility"
|
||||
max="$ctrl.maxResponsibility"
|
||||
min="1"
|
||||
step="1"
|
||||
vn-acl="salesAssistant"
|
||||
on-change="$ctrl.saveResponsibility(value)">
|
||||
</vn-range>
|
||||
</vn-tool-bar>
|
||||
<vn-check vn-one
|
||||
label="Is paid with mana"
|
||||
ng-model="$ctrl.claim.isChargedToMana"
|
||||
vn-acl="salesAssistant"
|
||||
on-change="$ctrl.saveMana(value)">
|
||||
</vn-check>
|
||||
</section>
|
||||
|
||||
<vn-data-viewer model="model">
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th number>Id</vn-th>
|
||||
<vn-th number>Ticket</vn-th>
|
||||
<vn-th>Destination</vn-th>
|
||||
<vn-th>Landed</vn-th>
|
||||
<vn-th number>Quantity</vn-th>
|
||||
<vn-th>Description</vn-th>
|
||||
<vn-th number>Price</vn-th>
|
||||
<vn-th number>Disc.</vn-th>
|
||||
<vn-th number>Total</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr
|
||||
ng-repeat="saleClaimed in $ctrl.salesClaimed"
|
||||
vn-repeat-last on-last="$ctrl.focusLastInput()">
|
||||
<vn-td number>
|
||||
<span
|
||||
ng-click="$ctrl.showDescriptor($event, saleClaimed.sale.itemFk)"
|
||||
class="link">
|
||||
{{::saleClaimed.sale.itemFk | zeroFill:6}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
id="claimDestinationFk"
|
||||
ng-model="saleClaimed.claimDestinationFk"
|
||||
url="/claim/api/ClaimDestinations"
|
||||
fields="['id','description']"
|
||||
value-field="id"
|
||||
show-field="description"
|
||||
on-change="$ctrl.setClaimDestination(saleClaimed.id, value)">
|
||||
</vn-autocomplete>
|
||||
</vn-td>
|
||||
<vn-td>{{saleClaimed.sale.ticket.landed | dateTime: 'dd/MM/yyyy'}}</vn-td>
|
||||
<vn-td number>{{saleClaimed.sale.quantity}}</vn-td>
|
||||
<vn-td expand>{{saleClaimed.sale.concept}}</vn-td>
|
||||
<vn-td number>{{saleClaimed.sale.price | currency: 'EUR':2}}</vn-td>
|
||||
<vn-td number>{{saleClaimed.sale.discount}} %</vn-td>
|
||||
<vn-td number>
|
||||
{{saleClaimed.sale.quantity * saleClaimed.sale.price *
|
||||
((100 - saleClaimed.sale.discount) / 100) | currency: 'EUR':2}}
|
||||
</vn-td>
|
||||
<vn-td shrink>
|
||||
<vn-icon-button
|
||||
vn-tooltip="Remove line"
|
||||
icon="delete"
|
||||
ng-click="$ctrl.deleteClaimedSale(saleClaimed.id)"
|
||||
tabindex="-1">
|
||||
</vn-icon-button>
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
</vn-td>
|
||||
<vn-td number>
|
||||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showTicketDescriptor($event, saleClaimed.sale.ticketFk)">
|
||||
{{::saleClaimed.sale.ticketFk}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>
|
||||
<vn-autocomplete vn-one
|
||||
id="claimDestinationFk"
|
||||
ng-model="saleClaimed.claimDestinationFk"
|
||||
url="/claim/api/ClaimDestinations"
|
||||
fields="['id','description']"
|
||||
value-field="id"
|
||||
show-field="description"
|
||||
on-change="$ctrl.setClaimDestination(saleClaimed.id, value)">
|
||||
</vn-autocomplete>
|
||||
</vn-td>
|
||||
<vn-td>{{::saleClaimed.sale.ticket.landed | dateTime: 'dd/MM/yyyy'}}</vn-td>
|
||||
<vn-td number>{{::saleClaimed.sale.quantity}}</vn-td>
|
||||
<vn-td expand>{{::saleClaimed.sale.concept}}</vn-td>
|
||||
<vn-td number>{{::saleClaimed.sale.price | currency: 'EUR':2}}</vn-td>
|
||||
<vn-td number>{{::saleClaimed.sale.discount}} %</vn-td>
|
||||
<vn-td number>
|
||||
{{saleClaimed.sale.quantity * saleClaimed.sale.price *
|
||||
((100 - saleClaimed.sale.discount) / 100) | currency: 'EUR':2}}
|
||||
</vn-td>
|
||||
<vn-td shrink>
|
||||
<vn-icon-button
|
||||
vn-tooltip="Remove line"
|
||||
icon="delete"
|
||||
ng-click="$ctrl.deleteClaimedSale(saleClaimed.id)"
|
||||
tabindex="-1">
|
||||
</vn-icon-button>
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</vn-data-viewer>
|
||||
|
||||
<vn-button-bar>
|
||||
<vn-button
|
||||
label="Regularize"
|
||||
|
@ -125,11 +121,7 @@
|
|||
vn-http-click="$ctrl.regularize()">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
<!-- WIP
|
||||
<a ng-click="$ctrl.openAddSalesDialog()" vn-tooltip="New item" vn-bind="+" fixed-bottom-right>
|
||||
<vn-float-button icon="add"></vn-float-button>
|
||||
</a>
|
||||
-->
|
||||
</vn-card>
|
||||
|
||||
<!-- Add Lines Dialog -->
|
||||
<vn-dialog vn-id="addSales">
|
||||
|
|
|
@ -1,4 +1,19 @@
|
|||
vn-claim-action {
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
|
||||
vn-tool-bar {
|
||||
flex: 1
|
||||
}
|
||||
|
||||
vn-check {
|
||||
flex: none;
|
||||
}
|
||||
}
|
||||
|
||||
vn-dialog[vn-id=addSales] {
|
||||
tpl-body {
|
||||
width: 950px;
|
||||
|
|
|
@ -1,84 +1,84 @@
|
|||
<vn-crud-model
|
||||
auto-load="false"
|
||||
vn-id="model"
|
||||
<vn-crud-model vn-id="model"
|
||||
auto-load="true"
|
||||
url="claim/api/ClaimBeginnings"
|
||||
filter="$ctrl.filter"
|
||||
data="$ctrl.salesClaimed"
|
||||
on-data-change="$ctrl.calculateTotals()">
|
||||
</vn-crud-model>
|
||||
<vn-vertical>
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-vertical>
|
||||
<vn-horizontal>
|
||||
<div class="totalBox">
|
||||
<vn-label-value label="Total"
|
||||
value="{{$ctrl.paidTotal | currency: 'EUR':2}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Total claimed"
|
||||
value="{{$ctrl.claimedTotal | currency: 'EUR':2}}">
|
||||
</vn-label-value>
|
||||
</div>
|
||||
</vn-horizontal>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th center>Landed</vn-th>
|
||||
<vn-th number>Quantity</vn-th>
|
||||
<vn-th>Claimed</vn-th>
|
||||
<vn-th>Description</vn-th>
|
||||
<vn-th number>Price</vn-th>
|
||||
<vn-th number>Disc.</vn-th>
|
||||
<vn-th number>Total</vn-th>
|
||||
<vn-th></vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="saleClaimed in $ctrl.salesClaimed" vn-repeat-last>
|
||||
<vn-td center>{{::saleClaimed.sale.ticket.landed | dateTime:'dd/MM/yyyy'}}</vn-td>
|
||||
<vn-td number>{{::saleClaimed.sale.quantity}}</vn-td>
|
||||
<vn-td>
|
||||
<vn-input-number
|
||||
vn-focus min="0"
|
||||
step="1"
|
||||
ng-model="saleClaimed.quantity"
|
||||
on-change="$ctrl.setClaimedQuantity(saleClaimed.id, saleClaimed.quantity)">
|
||||
</vn-input-number>
|
||||
</vn-td>
|
||||
<vn-td expand title="{{::saleClaimed.sale.concept}}">
|
||||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showItemDescriptor($event, saleClaimed.sale.itemFk)">
|
||||
{{::saleClaimed.sale.concept}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td number>{{::saleClaimed.sale.price | currency: 'EUR':2}}</vn-td>
|
||||
<vn-td number>
|
||||
<span class="link"
|
||||
vn-tooltip="Edit discount"
|
||||
ng-click="$ctrl.showEditPopover($event, saleClaimed)">
|
||||
{{::saleClaimed.sale.discount}} %
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td number>
|
||||
{{::$ctrl.getSaleTotal(saleClaimed.sale) | currency: 'EUR':2}}
|
||||
</vn-td>
|
||||
<vn-td shrink>
|
||||
<vn-icon-button
|
||||
vn-tooltip="Remove sale"
|
||||
icon="delete"
|
||||
ng-click="$ctrl.deleteClaimedSale($index)"
|
||||
tabindex="-1">
|
||||
</vn-icon-button>
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
<a ng-click="$ctrl.openAddSalesDialog()" vn-tooltip="Add sale item" vn-bind="+" fixed-bottom-right>
|
||||
<vn-float-button icon="add"></vn-float-button>
|
||||
</a>
|
||||
</vn-vertical>
|
||||
|
||||
<vn-card class="vn-mb-md vn-pa-lg vn-w-lg" style="text-align: right"
|
||||
ng-if="$ctrl.salesClaimed.length > 0">
|
||||
<vn-label-value label="Total"
|
||||
value="{{$ctrl.paidTotal | currency: 'EUR':2}}">
|
||||
</vn-label-value>
|
||||
<vn-label-value label="Total claimed"
|
||||
value="{{$ctrl.claimedTotal | currency: 'EUR':2}}">
|
||||
</vn-label-value>
|
||||
</vn-card>
|
||||
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-data-viewer model="model">
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th center>Landed</vn-th>
|
||||
<vn-th number>Quantity</vn-th>
|
||||
<vn-th>Claimed</vn-th>
|
||||
<vn-th>Description</vn-th>
|
||||
<vn-th number>Price</vn-th>
|
||||
<vn-th number>Disc.</vn-th>
|
||||
<vn-th number>Total</vn-th>
|
||||
<vn-th></vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="saleClaimed in $ctrl.salesClaimed" vn-repeat-last>
|
||||
<vn-td center>{{::saleClaimed.sale.ticket.landed | dateTime:'dd/MM/yyyy'}}</vn-td>
|
||||
<vn-td number>{{::saleClaimed.sale.quantity}}</vn-td>
|
||||
<vn-td>
|
||||
<vn-input-number
|
||||
vn-focus min="0"
|
||||
step="1"
|
||||
ng-model="saleClaimed.quantity"
|
||||
on-change="$ctrl.setClaimedQuantity(saleClaimed.id, saleClaimed.quantity)">
|
||||
</vn-input-number>
|
||||
</vn-td>
|
||||
<vn-td expand title="{{::saleClaimed.sale.concept}}">
|
||||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showItemDescriptor($event, saleClaimed.sale.itemFk)">
|
||||
{{::saleClaimed.sale.concept}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td number>{{::saleClaimed.sale.price | currency: 'EUR':2}}</vn-td>
|
||||
<vn-td number>
|
||||
<span class="link"
|
||||
vn-tooltip="Edit discount"
|
||||
ng-click="$ctrl.showEditPopover($event, saleClaimed)">
|
||||
{{::saleClaimed.sale.discount}} %
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td number>
|
||||
{{::$ctrl.getSaleTotal(saleClaimed.sale) | currency: 'EUR':2}}
|
||||
</vn-td>
|
||||
<vn-td shrink>
|
||||
<vn-icon-button
|
||||
vn-tooltip="Remove sale"
|
||||
icon="delete"
|
||||
ng-click="$ctrl.deleteClaimedSale($index)"
|
||||
tabindex="-1">
|
||||
</vn-icon-button>
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</vn-data-viewer>
|
||||
</vn-card>
|
||||
|
||||
<a ng-click="$ctrl.openAddSalesDialog()" vn-tooltip="Add sale item" vn-bind="+" fixed-bottom-right>
|
||||
<vn-float-button icon="add"></vn-float-button>
|
||||
</a>
|
||||
|
||||
<!-- Add Lines Dialog -->
|
||||
<vn-dialog vn-id="add-sales" class="modal-form">
|
||||
<tpl-body>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
data="$ctrl.photos">
|
||||
</vn-crud-model>
|
||||
|
||||
<section class="drop-zone" vn-droppable="true" on-drop="$ctrl.onDrop(event)">
|
||||
<section class="drop-zone" vn-droppable="$ctrl.onDrop($event)">
|
||||
<section><vn-icon icon="add_circle"></vn-icon></section>
|
||||
<section translate>Drag & Drop files here...</section>
|
||||
</section>
|
||||
|
|
|
@ -36,8 +36,9 @@ class Controller {
|
|||
}
|
||||
}
|
||||
|
||||
onDrop(event) {
|
||||
const files = event.dataTransfer.files;
|
||||
onDrop($event) {
|
||||
console.log($event);
|
||||
const files = $event.dataTransfer.files;
|
||||
this.setDefaultParams().then(() => {
|
||||
this.dms.files = files;
|
||||
this.create();
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
<vn-crud-model
|
||||
<vn-crud-model vn-id="model"
|
||||
url="/api/ClaimDms"
|
||||
where="{claimFk: $ctrl.$stateParams.id}"
|
||||
data="photos"
|
||||
auto-load="true">
|
||||
data="photos">
|
||||
</vn-crud-model>
|
||||
<vn-card class="summary">
|
||||
<h5>{{$ctrl.summary.claim.id}} - {{$ctrl.summary.claim.client.name}}</h5>
|
||||
<h5>{{::$ctrl.summary.claim.id}} - {{::$ctrl.summary.claim.client.name}}</h5>
|
||||
<vn-horizontal>
|
||||
<vn-one>
|
||||
<vn-label-value label="Created"
|
||||
|
@ -45,41 +43,43 @@
|
|||
</vn-one>
|
||||
<vn-auto>
|
||||
<h4 translate>Detail</h4>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th number>Item</vn-th>
|
||||
<vn-th>Landed</vn-th>
|
||||
<vn-th number>Quantity</vn-th>
|
||||
<vn-th number>Claimed</vn-th>
|
||||
<vn-th>Description</vn-th>
|
||||
<vn-th number>Price</vn-th>
|
||||
<vn-th number>Disc.</vn-th>
|
||||
<vn-th number>Total</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="saleClaimed in $ctrl.summary.salesClaimed">
|
||||
<vn-td number>
|
||||
<span
|
||||
ng-click="$ctrl.showItemDescriptor($event, saleClaimed.sale.itemFk)"
|
||||
class="link">
|
||||
{{saleClaimed.sale.itemFk | zeroFill:6}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>{{saleClaimed.sale.ticket.landed | dateTime: 'dd/MM/yyyy'}}</vn-td>
|
||||
<vn-td number>{{saleClaimed.sale.quantity}}</vn-td>
|
||||
<vn-td number>{{saleClaimed.quantity}}</vn-td>
|
||||
<vn-td expand>{{saleClaimed.sale.concept}}</vn-td>
|
||||
<vn-td number>{{saleClaimed.sale.price | currency: 'EUR':2}}</vn-td>
|
||||
<vn-td number>{{saleClaimed.sale.discount}} %</vn-td>
|
||||
<vn-td number>
|
||||
{{saleClaimed.sale.quantity * saleClaimed.sale.price *
|
||||
((100 - saleClaimed.sale.discount) / 100) | currency: 'EUR':2}}
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
<vn-data-viewer data="::$ctrl.summary.salesClaimed">
|
||||
<vn-table>
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th number>Item</vn-th>
|
||||
<vn-th>Landed</vn-th>
|
||||
<vn-th number>Quantity</vn-th>
|
||||
<vn-th number>Claimed</vn-th>
|
||||
<vn-th>Description</vn-th>
|
||||
<vn-th number>Price</vn-th>
|
||||
<vn-th number>Disc.</vn-th>
|
||||
<vn-th number>Total</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="saleClaimed in $ctrl.summary.salesClaimed">
|
||||
<vn-td number>
|
||||
<span
|
||||
ng-click="$ctrl.showItemDescriptor($event, saleClaimed.sale.itemFk)"
|
||||
class="link">
|
||||
{{::saleClaimed.sale.itemFk | zeroFill:6}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>{{::saleClaimed.sale.ticket.landed | dateTime: 'dd/MM/yyyy'}}</vn-td>
|
||||
<vn-td number>{{::saleClaimed.sale.quantity}}</vn-td>
|
||||
<vn-td number>{{::saleClaimed.quantity}}</vn-td>
|
||||
<vn-td expand>{{::saleClaimed.sale.concept}}</vn-td>
|
||||
<vn-td number>{{::saleClaimed.sale.price | currency: 'EUR':2}}</vn-td>
|
||||
<vn-td number>{{::saleClaimed.sale.discount}} %</vn-td>
|
||||
<vn-td number>
|
||||
{{saleClaimed.sale.quantity * saleClaimed.sale.price *
|
||||
((100 - saleClaimed.sale.discount) / 100) | currency: 'EUR':2}}
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</vn-data-viewer>
|
||||
</vn-auto>
|
||||
<vn-auto ng-if="photos.length > 0">
|
||||
<h4 translate>Photos</h4>
|
||||
|
@ -94,78 +94,82 @@
|
|||
</vn-auto>
|
||||
<vn-auto>
|
||||
<h4 translate>Development</h4>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th>Reason</vn-th>
|
||||
<vn-th>Result</vn-th>
|
||||
<vn-th>Responsible</vn-th>
|
||||
<vn-th>Worker</vn-th>
|
||||
<vn-th>Redelivery</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="development in $ctrl.summary.developments">
|
||||
<vn-td>{{development.claimReason.description}}</vn-td>
|
||||
<vn-td>{{development.claimResult.description}}</vn-td>
|
||||
<vn-td>{{development.claimResponsible.description}}</vn-td>
|
||||
<vn-td expand>
|
||||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showWorkerDescriptor($event, development.workerFk)">
|
||||
{{::development.worker.user.nickname}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>{{development.claimRedelivery.description}}</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
<vn-data-viewer data="::$ctrl.summary.developments">
|
||||
<vn-table>
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th>Reason</vn-th>
|
||||
<vn-th>Result</vn-th>
|
||||
<vn-th>Responsible</vn-th>
|
||||
<vn-th>Worker</vn-th>
|
||||
<vn-th>Redelivery</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="development in $ctrl.summary.developments">
|
||||
<vn-td>{{::development.claimReason.description}}</vn-td>
|
||||
<vn-td>{{::development.claimResult.description}}</vn-td>
|
||||
<vn-td>{{::development.claimResponsible.description}}</vn-td>
|
||||
<vn-td expand>
|
||||
<span
|
||||
class="link"
|
||||
ng-click="$ctrl.showWorkerDescriptor($event, development.workerFk)">
|
||||
{{::development.worker.user.nickname}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>{{::development.claimRedelivery.description}}</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</vn-data-viewer>
|
||||
</vn-auto>
|
||||
<vn-auto>
|
||||
<h4 translate>Action</h4>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th number>Item</vn-th>
|
||||
<vn-th number>Ticket</vn-th>
|
||||
<vn-th>Destination</vn-th>
|
||||
<vn-th number>Landed</vn-th>
|
||||
<vn-th number>Quantity</vn-th>
|
||||
<vn-th>Description</vn-th>
|
||||
<vn-th number>Price</vn-th>
|
||||
<vn-th number>Disc.</vn-th>
|
||||
<vn-th number>Total</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="action in $ctrl.summary.actions">
|
||||
<vn-td number>
|
||||
<span
|
||||
ng-click="$ctrl.showItemDescriptor($event, action.sale.itemFk)"
|
||||
class="link">
|
||||
{{action.sale.itemFk | zeroFill:6}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td number>
|
||||
<span
|
||||
ng-click="$ctrl.showTicketDescriptor($event, action.sale.ticket.id)"
|
||||
class="link">
|
||||
{{action.sale.ticket.id | zeroFill:6}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td expand>{{action.claimBeggining.description}}</vn-td>
|
||||
<vn-td number>{{action.sale.ticket.landed | dateTime: 'dd/MM/yyyy'}}</vn-td>
|
||||
<vn-td number>{{action.sale.quantity}}</vn-td>
|
||||
<vn-td expand>{{action.sale.concept}}</vn-td>
|
||||
<vn-td number>{{action.sale.price}}</vn-td>
|
||||
<vn-td number>{{action.sale.discount}} %</vn-td>
|
||||
<vn-td number>
|
||||
{{action.sale.quantity * action.sale.price *
|
||||
((100 - action.sale.discount) / 100) | currency: 'EUR':2}}
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
<vn-data-viewer data="::$ctrl.summary.actions">
|
||||
<vn-table>
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th number>Item</vn-th>
|
||||
<vn-th number>Ticket</vn-th>
|
||||
<vn-th>Destination</vn-th>
|
||||
<vn-th number>Landed</vn-th>
|
||||
<vn-th number>Quantity</vn-th>
|
||||
<vn-th>Description</vn-th>
|
||||
<vn-th number>Price</vn-th>
|
||||
<vn-th number>Disc.</vn-th>
|
||||
<vn-th number>Total</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="action in $ctrl.summary.actions">
|
||||
<vn-td number>
|
||||
<span
|
||||
ng-click="$ctrl.showItemDescriptor($event, action.sale.itemFk)"
|
||||
class="link">
|
||||
{{::action.sale.itemFk | zeroFill:6}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td number>
|
||||
<span
|
||||
ng-click="$ctrl.showTicketDescriptor($event, action.sale.ticket.id)"
|
||||
class="link">
|
||||
{{::action.sale.ticket.id | zeroFill:6}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td expand>{{::action.claimBeggining.description}}</vn-td>
|
||||
<vn-td number>{{::action.sale.ticket.landed | dateTime: 'dd/MM/yyyy'}}</vn-td>
|
||||
<vn-td number>{{::action.sale.quantity}}</vn-td>
|
||||
<vn-td expand>{{::action.sale.concept}}</vn-td>
|
||||
<vn-td number>{{::action.sale.price}}</vn-td>
|
||||
<vn-td number>{{::action.sale.discount}} %</vn-td>
|
||||
<vn-td number>
|
||||
{{action.sale.quantity * action.sale.price *
|
||||
((100 - action.sale.discount) / 100) | currency: 'EUR':2}}
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</vn-data-viewer>
|
||||
</vn-auto>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
|
|
|
@ -9,6 +9,26 @@ class Controller {
|
|||
this.accessToken = vnToken.token;
|
||||
}
|
||||
|
||||
get claim() {
|
||||
return this._claim;
|
||||
}
|
||||
|
||||
|
||||
set claim(value) {
|
||||
this._claim = value;
|
||||
|
||||
// Get DMS on summary load
|
||||
/* if (value)
|
||||
this.$.$applyAsync(() => this.loadDms()); */
|
||||
}
|
||||
|
||||
loadDms() {
|
||||
this.$.model.where = {
|
||||
claimFk: this.claim.id
|
||||
};
|
||||
this.$.model.refresh();
|
||||
}
|
||||
|
||||
getSummary() {
|
||||
this.$http.get(`/claim/api/Claims/${this.claim.id}/getSummary`).then(response => {
|
||||
this.summary = response.data;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import './index.js';
|
||||
import crudModel from 'core/mocks/crud-model';
|
||||
|
||||
describe('Claim', () => {
|
||||
describe('Component summary', () => {
|
||||
|
@ -13,6 +14,7 @@ describe('Claim', () => {
|
|||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnClaimSummary');
|
||||
controller.claim = {id: 1};
|
||||
controller.$.model = crudModel;
|
||||
}));
|
||||
|
||||
describe('getSummary()', () => {
|
||||
|
|
|
@ -117,6 +117,6 @@ describe('Route filter()', () => {
|
|||
|
||||
let result = await app.models.Route.filter(ctx);
|
||||
|
||||
expect(result.length).toEqual(4);
|
||||
expect(result.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,6 +4,6 @@ describe('route getTickets()', () => {
|
|||
it('should return the tickets for a given route', async() => {
|
||||
let result = await app.models.Route.getTickets(2);
|
||||
|
||||
expect(result.length).toEqual(4);
|
||||
expect(result.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('route guessPriority()', () => {
|
||||
const targetRouteId = 2;
|
||||
const targetRouteId = 7;
|
||||
let routeTicketsToRestore;
|
||||
|
||||
afterAll(async done => {
|
||||
|
@ -17,25 +17,23 @@ describe('route guessPriority()', () => {
|
|||
it('should confirm the tickets in the target route have no priority yet', async() => {
|
||||
routeTicketsToRestore = await app.models.Ticket.find({where: {routeFk: targetRouteId}});
|
||||
|
||||
expect(routeTicketsToRestore.length).toEqual(4);
|
||||
expect(routeTicketsToRestore.length).toEqual(2);
|
||||
|
||||
expect(routeTicketsToRestore[0].id).toEqual(23);
|
||||
expect(routeTicketsToRestore[0].priority).toBeNull();
|
||||
expect(routeTicketsToRestore[0].id).toEqual(7);
|
||||
expect(routeTicketsToRestore[1].id).toEqual(24);
|
||||
expect(routeTicketsToRestore[1].priority).toBeNull();
|
||||
expect(routeTicketsToRestore[1].id).toEqual(8);
|
||||
expect(routeTicketsToRestore[2].priority).toBeNull();
|
||||
expect(routeTicketsToRestore[2].id).toEqual(9);
|
||||
});
|
||||
|
||||
it('should call guessPriority() and then check the tickets in the target route now have their priorities defined', async() => {
|
||||
await app.models.Route.guessPriority(targetRouteId);
|
||||
let routeTickets = await app.models.Ticket.find({where: {routeFk: targetRouteId}, fields: ['id', 'priority']});
|
||||
|
||||
expect(routeTickets.length).toEqual(4);
|
||||
expect(routeTickets[0].priority).toEqual(1);
|
||||
expect(routeTickets[0].id).toEqual(7);
|
||||
expect(routeTickets[1].priority).toEqual(3);
|
||||
expect(routeTickets[1].id).toEqual(8);
|
||||
expect(routeTickets[2].priority).toEqual(2);
|
||||
expect(routeTickets[2].id).toEqual(9);
|
||||
expect(routeTickets.length).toEqual(2);
|
||||
|
||||
expect(routeTickets[0].id).toEqual(23);
|
||||
expect(routeTickets[0].priority).toEqual(3);
|
||||
expect(routeTickets[1].id).toEqual(24);
|
||||
expect(routeTickets[1].priority).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -11,7 +11,7 @@ describe('route summary()', () => {
|
|||
const result = await app.models.Route.summary(1);
|
||||
const agency = result.route.agencyMode();
|
||||
|
||||
expect(agency.name).toEqual('Silla247');
|
||||
expect(agency.name).toEqual('inhouse pickup');
|
||||
});
|
||||
|
||||
it(`should return a summary object containing it's vehicle`, async() => {
|
||||
|
@ -31,6 +31,6 @@ describe('route summary()', () => {
|
|||
it(`should return a summary object containing data from the tickets`, async() => {
|
||||
const result = await app.models.Route.summary(2);
|
||||
|
||||
expect(result.tickets.length).toEqual(4);
|
||||
expect(result.tickets.length).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -10,8 +10,8 @@ describe('route updateVolume()', () => {
|
|||
|
||||
|
||||
afterAll(async done => {
|
||||
await originalRoute.updateAttributes({m3: 2.7});
|
||||
await ticketToRestore.updateAttributes({routeFk: 2});
|
||||
await originalRoute.updateAttributes({m3: 1.8});
|
||||
await ticketToRestore.updateAttributes({routeFk: null});
|
||||
await app.models.RouteLog.destroyById(logIdToDestroy);
|
||||
done();
|
||||
});
|
||||
|
@ -19,12 +19,12 @@ describe('route updateVolume()', () => {
|
|||
it('should confirm the original volume of the route is the expected', async() => {
|
||||
originalRoute = await app.models.Route.findById(routeId);
|
||||
|
||||
expect(originalRoute.m3).toEqual(2.7);
|
||||
expect(originalRoute.m3).toEqual(1.8);
|
||||
});
|
||||
|
||||
it('should confirm the route volume is updated when a ticket is added', async() => {
|
||||
ticketToRestore = await app.models.Ticket.findById(8);
|
||||
let updatedTicket = await app.models.Ticket.findById(8);
|
||||
ticketToRestore = await app.models.Ticket.findById(14);
|
||||
let updatedTicket = await app.models.Ticket.findById(14);
|
||||
|
||||
await updatedTicket.updateAttributes({routeFk: routeId});
|
||||
await app.models.Route.updateVolume(ctx, routeId);
|
||||
|
@ -36,8 +36,9 @@ describe('route updateVolume()', () => {
|
|||
|
||||
it('should confirm the change is logged', async() => {
|
||||
let logs = await app.models.RouteLog.find({fields: ['id', 'newInstance']});
|
||||
|
||||
let m3Log = logs.filter(log => {
|
||||
return log.newInstance.m3 === 3.1;
|
||||
return log.newInstance.m3 === 1.9;
|
||||
});
|
||||
logIdToDestroy = m3Log[0].id;
|
||||
|
||||
|
|
|
@ -216,7 +216,7 @@
|
|||
"url" : "/create",
|
||||
"state": "ticket.card.request.create",
|
||||
"component": "vn-ticket-request-create",
|
||||
"description": "Purchase request",
|
||||
"description": "New purchase request",
|
||||
"acl": ["salesPerson"]
|
||||
}, {
|
||||
"url": "/create?clientFk",
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('moveChild', {
|
||||
description: 'Changes the parent of a child department',
|
||||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
arg: 'id',
|
||||
type: 'Number',
|
||||
description: 'The department id',
|
||||
http: {source: 'path'}
|
||||
}, {
|
||||
arg: 'parentId',
|
||||
type: 'Number',
|
||||
description: 'New parent id',
|
||||
}],
|
||||
returns: {
|
||||
type: 'Object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/:id/moveChild`,
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.moveChild = async(id, parentId = null) => {
|
||||
const models = Self.app.models;
|
||||
const child = await models.Department.findById(id);
|
||||
|
||||
if (id == parentId) return;
|
||||
|
||||
if (parentId) {
|
||||
const parent = await models.Department.findById(parentId);
|
||||
|
||||
if (child.lft < parent.lft && child.rgt > parent.rgt)
|
||||
throw new UserError('You cannot move a parent to its own sons');
|
||||
}
|
||||
|
||||
return child.updateAttribute('parentFk', parentId);
|
||||
};
|
||||
};
|
|
@ -0,0 +1,18 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('department createChild()', () => {
|
||||
let createdChild;
|
||||
|
||||
afterAll(async done => {
|
||||
await createdChild.destroy();
|
||||
done();
|
||||
});
|
||||
|
||||
it('should create a new child', async() => {
|
||||
const parentId = null;
|
||||
createdChild = await app.models.Department.createChild(parentId, 'My new department');
|
||||
|
||||
expect(createdChild.name).toEqual('My new department');
|
||||
expect(createdChild.parentFk).toBeNull();
|
||||
});
|
||||
});
|
|
@ -0,0 +1,23 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('department moveChild()', () => {
|
||||
let updatedChild;
|
||||
|
||||
afterAll(async done => {
|
||||
const child = await app.models.Department.findById(updatedChild.id);
|
||||
await child.updateAttribute('parentFk', null);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should move a child department to a new parent', async() => {
|
||||
const childId = 22;
|
||||
const parentId = 1;
|
||||
|
||||
const child = await app.models.Department.findById(childId);
|
||||
|
||||
expect(child.parentFk).toBeNull();
|
||||
updatedChild = await app.models.Department.moveChild(childId, parentId);
|
||||
|
||||
expect(updatedChild.parentFk).toEqual(1);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,21 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('department removeChild()', () => {
|
||||
let removedChild;
|
||||
|
||||
afterAll(async done => {
|
||||
await app.models.Department.create(removedChild);
|
||||
done();
|
||||
});
|
||||
|
||||
it('should remove a child department', async() => {
|
||||
const childId = 1;
|
||||
|
||||
removedChild = await app.models.Department.findById(childId);
|
||||
const result = await app.models.Department.removeChild(childId);
|
||||
const existsChild = await app.models.Department.findById(childId);
|
||||
|
||||
expect(result.count).toEqual(1);
|
||||
expect(existsChild).toBeNull();
|
||||
});
|
||||
});
|
|
@ -32,14 +32,12 @@ module.exports = Self => {
|
|||
throw new UserError(`You don't have enough privileges`);
|
||||
|
||||
const subordinate = await Worker.findById(data.workerFk);
|
||||
const timed = new Date(data.timed);
|
||||
|
||||
return Self.create({
|
||||
userFk: subordinate.userFk,
|
||||
timed: data.timed,
|
||||
manual: 1
|
||||
});
|
||||
let offset = timed.getTimezoneOffset() * 60000;
|
||||
timed.setTime(timed.getTime() - offset);
|
||||
|
||||
/* return Self.rawSql('CALL vn.workerTimeControl_add(?, ?, ?, ?)', [
|
||||
subordinate.userFk, null, data.timed, true]); */
|
||||
return Self.rawSql('CALL vn.workerTimeControl_add(?, ?, ?, ?)', [
|
||||
subordinate.userFk, null, timed, true]);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -2,4 +2,5 @@ module.exports = Self => {
|
|||
require('../methods/department/getLeaves')(Self);
|
||||
require('../methods/department/createChild')(Self);
|
||||
require('../methods/department/removeChild')(Self);
|
||||
require('../methods/department/moveChild')(Self);
|
||||
};
|
||||
|
|
|
@ -16,6 +16,15 @@
|
|||
},
|
||||
"parentFk": {
|
||||
"type": "Number"
|
||||
},
|
||||
"lft": {
|
||||
"type": "Number"
|
||||
},
|
||||
"rgt": {
|
||||
"type": "Number"
|
||||
},
|
||||
"sons": {
|
||||
"type": "Number"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,10 @@
|
|||
fetch-func="$ctrl.onFetch($item)"
|
||||
remove-func="$ctrl.onRemove($item)"
|
||||
create-func="$ctrl.onCreate($parent)"
|
||||
sort-func="$ctrl.onSort($a, $b)">
|
||||
sort-func="$ctrl.onSort($a, $b)"
|
||||
on-drop="$ctrl.onDrop($dropped, $dragged)"
|
||||
on-drag-start="$ctrl.onDragStart(item)"
|
||||
on-drag-end="$ctrl.onDragEnd(item)">
|
||||
{{::item.name}}
|
||||
</vn-treeview>
|
||||
</vn-card>
|
||||
|
|
|
@ -23,19 +23,13 @@ class Controller {
|
|||
return a.name.localeCompare(b.name);
|
||||
}
|
||||
|
||||
/* onDrop(item, dragged, dropped) {
|
||||
if (dropped.scope.item) {
|
||||
const droppedItem = dropped.scope.item;
|
||||
const draggedItem = dragged.scope.item;
|
||||
|
||||
if (droppedItem.childs)
|
||||
droppedItem.childs.push(Object.assign({}, draggedItem));
|
||||
|
||||
dragged.element.remove();
|
||||
|
||||
this.$scope.$apply();
|
||||
}
|
||||
} */
|
||||
onDrop(dropped, dragged) {
|
||||
const params = dropped ? {parentId: dropped.id} : null;
|
||||
const query = `/api/departments/${dragged.id}/moveChild`;
|
||||
this.$http.post(query, params).then(() => {
|
||||
this.$.treeview.move(dragged, dropped);
|
||||
});
|
||||
}
|
||||
|
||||
onCreate(parent) {
|
||||
this.newChild = {
|
||||
|
@ -62,12 +56,8 @@ class Controller {
|
|||
if (parent && parent.id)
|
||||
params.parentId = parent.id;
|
||||
|
||||
if (!parent.active)
|
||||
this.$.treeview.unfold(parent);
|
||||
|
||||
const query = `/api/departments/createChild`;
|
||||
this.$http.post(query, params).then(res => {
|
||||
const parent = this.newChild.parent;
|
||||
const item = res.data;
|
||||
item.parent = parent;
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
ng-if="!log.newProperties"
|
||||
id="description">
|
||||
<div>
|
||||
<span>{{log.description}}</span>
|
||||
<span>{{::log.description}}</span>
|
||||
</div>
|
||||
</vn-one>
|
||||
</vn-td>
|
||||
|
|
Loading…
Reference in New Issue