diff --git a/db/changes/10003-easter/00-nodeAdd.sql b/db/changes/10003-easter/00-nodeAdd.sql new file mode 100644 index 000000000..80c716b45 --- /dev/null +++ b/db/changes/10003-easter/00-nodeAdd.sql @@ -0,0 +1,71 @@ +DROP procedure IF EXISTS `nst`.`nodeAdd`; + +DELIMITER $$ +CREATE DEFINER=`root`@`%` PROCEDURE `nst`.`nodeAdd`(IN `vScheme` VARCHAR(45), IN `vTable` VARCHAR(45), IN `vParentFk` INT, IN `vChild` VARCHAR(100)) +BEGIN + DECLARE vSql TEXT; + DECLARE vTableClone VARCHAR(45); + + SET vTableClone = CONCAT(vTable, 'Clone'); + + CALL util.exec(CONCAT('DROP TEMPORARY TABLE IF EXISTS tmp.', vTableClone)); + CALL util.exec(CONCAT( + 'CREATE TEMPORARY TABLE tmp.', vTableClone, + ' ENGINE = MEMORY', + ' SELECT * FROM ', vScheme, '.', vTable + )); + + CALL util.exec(CONCAT( + 'SELECT COUNT(c.id) INTO @childs', + ' FROM ', vScheme, '.', vTable, ' p', + ' LEFT JOIN tmp.', vTableClone, ' c ON c.lft', + ' BETWEEN p.lft AND p.rgt AND c.id != ', vParentFk, + ' WHERE p.id = ', vParentFk + )); + + IF @childs = 0 THEN + CALL util.exec(CONCAT( + 'SELECT lft INTO @vLeft', + ' FROM ', vScheme, '.', vTable, + ' WHERE id = ', vParentFk + )); + ELSE + CALL util.exec(CONCAT( + 'SELECT c.rgt INTO @vLeft', + ' FROM ', vScheme, '.', vTable, ' p', + ' JOIN tmp.', vTableClone, ' c ON c.lft BETWEEN p.lft AND p.rgt', + ' WHERE p.id = ', vParentFk, + ' ORDER BY c.lft', + ' DESC LIMIT 1' + )); + END IF; + + CALL util.exec(CONCAT( + 'UPDATE ', vScheme, '.', vTable, ' SET rgt = rgt + 2', + ' WHERE rgt > @vLeft', + ' ORDER BY rgt DESC' + )); + CALL util.exec(CONCAT( + 'UPDATE ', vScheme, '.', vTable, ' SET lft = lft + 2', + ' WHERE lft > @vLeft', + ' ORDER BY lft DESC' + )); + + SET vChild = REPLACE(vChild, "'", "\\'"); + + CALL util.exec(CONCAT( + 'INSERT INTO ', vScheme, '.', vTable, ' (name, lft, rgt)', + ' VALUES ("', vChild, '", @vLeft + 1, @vLeft + 2)' + )); + + CALL util.exec(CONCAT( + 'SELECT id, name, lft, rgt, depth, sons', + ' FROM ', vScheme, '.', vTable, + ' WHERE id = LAST_INSERT_ID()' + )); + + CALL util.exec(CONCAT('DROP TEMPORARY TABLE tmp.', vTableClone)); +END$$ + +DELIMITER ; + diff --git a/db/changes/10003-easter/00-nodeDelete.sql b/db/changes/10003-easter/00-nodeDelete.sql new file mode 100644 index 000000000..906428c88 --- /dev/null +++ b/db/changes/10003-easter/00-nodeDelete.sql @@ -0,0 +1,34 @@ +DROP procedure IF EXISTS `nst`.`nodeDelete`; + +DELIMITER $$ +CREATE DEFINER=`root`@`%` PROCEDURE `nst`.`nodeDelete`(IN `vScheme` VARCHAR(45), IN `vTable` VARCHAR(45), IN `vNodeId` INT) +BEGIN + DECLARE vMyRight INT; + DECLARE vMyLeft INT; + DECLARE vMyWidth INT; + + CALL util.exec(CONCAT( + 'SELECT t.rgt, t.lft, t.rgt - t.lft + 1', + ' INTO @vMyRight, @vMyLeft, @vMyWidth', + ' FROM ', vScheme, '.', vTable, ' t', + ' WHERE t.id = ', vNodeId + )); + + CALL util.exec(CONCAT( + 'DELETE FROM ', vScheme, '.', vTable, + ' WHERE lft BETWEEN @vMyLeft AND @vMyRight' + )); + + CALL util.exec(CONCAT( + 'UPDATE ', vScheme, '.', vTable, ' SET rgt = rgt - @vMyWidth' + ' WHERE rgt > @vMyRight ORDER BY rgt' + )); + + CALL util.exec(CONCAT( + 'UPDATE ', vScheme, '.', vTable, ' SET lft = lft - @vMyWidth' + ' WHERE lft > @vMyRight ORDER BY lft' + )); +END$$ + +DELIMITER ; + diff --git a/db/changes/10003-easter/00-nodeRecalc.sql b/db/changes/10003-easter/00-nodeRecalc.sql new file mode 100644 index 000000000..ff103bda7 --- /dev/null +++ b/db/changes/10003-easter/00-nodeRecalc.sql @@ -0,0 +1,23 @@ +DROP procedure IF EXISTS `nst`.`nodeRecalc`; + +DELIMITER $$ +CREATE DEFINER=`root`@`%` PROCEDURE `nst`.`nodeRecalc`(IN `vScheme` VARCHAR(45), IN `vTable` VARCHAR(45)) +BEGIN + CALL util.exec(CONCAT ( + 'UPDATE ', vScheme, '.', vTable, ' d', + ' JOIN (SELECT', + ' node.id,', + ' COUNT(parent.id) - 1 as depth,', + ' cast((node.rgt - node.lft - 1) / 2 as DECIMAL) as sons', + ' FROM ', + ' ', vScheme, '.', vTable, ' AS node,', + ' ', vScheme, '.', vTable, ' AS parent', + ' WHERE node.lft BETWEEN parent.lft AND parent.rgt', + ' GROUP BY node.id', + ' ORDER BY node.lft) n ON n.id = d.id ', + ' SET d.`depth` = n.depth, d.sons = n.sons' + )); +END$$ + +DELIMITER ; + diff --git a/front/core/components/calendar/index.js b/front/core/components/calendar/index.js index 8948b5d65..bc356053b 100644 --- a/front/core/components/calendar/index.js +++ b/front/core/components/calendar/index.js @@ -3,7 +3,7 @@ import Component from '../../lib/component'; import './style.scss'; /** - * Calendar. + * Flat calendar. * */ export default class Calendar extends Component { diff --git a/front/core/components/treeview/child.html b/front/core/components/treeview/child.html index c1f20bcff..eedd63b19 100644 --- a/front/core/components/treeview/child.html +++ b/front/core/components/treeview/child.html @@ -1,18 +1,17 @@ \ No newline at end of file + {{::item.name}} + + + + + + + + +
  • + + + + +
    + Create new one +
    +
    +
  • + \ No newline at end of file diff --git a/front/core/components/treeview/child.js b/front/core/components/treeview/child.js index a26c47b5d..8fecbd89b 100644 --- a/front/core/components/treeview/child.js +++ b/front/core/components/treeview/child.js @@ -16,8 +16,7 @@ class Controller extends Component { } onIconClick(icon, item, parent, index) { - let parentScope = this.$scope.$parent.$parent; - let parentController = parentScope.$ctrl; + let parentController = this.parentScope.$ctrl; icon.callback.call(parentController, item, parent, index); } @@ -44,7 +43,10 @@ ngModule.component('vnTreeviewChild', { disabled: ' + parent-scope="$ctrl.$scope.$parent" + draggable="$ctrl.draggable" + droppable="$ctrl.droppable" + vn-droppable="{{$ctrl.droppable}}"> diff --git a/front/core/components/treeview/index.js b/front/core/components/treeview/index.js index c34ba2039..ac4186c58 100644 --- a/front/core/components/treeview/index.js +++ b/front/core/components/treeview/index.js @@ -3,13 +3,14 @@ import Component from '../../lib/component'; import './style.scss'; /** - * A simple tooltip. + * Treeview * * @property {String} position The relative position to the parent */ export default class Treeview extends Component { constructor($element, $scope) { super($element, $scope); + this.$scope = $scope; this.data = []; } @@ -86,6 +87,8 @@ ngModule.component('vnTreeview', { disabled: ' vn-horizontal > .description { color: $color-notice; font-weight: bold; - - & > vn-check .md-icon { - background-color: $color-notice - } } + & > vn-horizontal > vn-check .md-icon { + background-color: $color-notice + } } li.excluded { & > vn-horizontal > .description { color: $color-alert; font-weight: bold; - + } + + & > vn-horizontal > vn-check .md-icon { + background-color: $color-alert; + border-color: transparent } } } diff --git a/front/core/directives/draggable.js b/front/core/directives/draggable.js index 588b97adf..3b68a6cb6 100644 --- a/front/core/directives/draggable.js +++ b/front/core/directives/draggable.js @@ -8,8 +8,15 @@ import ngModule from '../module'; export function directive() { return { restrict: 'A', - link: function($scope, $element) { + 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); diff --git a/front/core/directives/droppable.js b/front/core/directives/droppable.js index 73f0db093..b99f397c7 100644 --- a/front/core/directives/droppable.js +++ b/front/core/directives/droppable.js @@ -7,6 +7,9 @@ export function directive($parse) { link: function($scope, $element, $attrs) { const element = $element[0]; const onDropEvent = $parse($attrs.onDrop); + const isDroppable = $attrs.vnDroppable === 'true'; + + if (!isDroppable) return; /** * Captures current dragging element diff --git a/modules/agency/front/location/index.html b/modules/agency/front/location/index.html index c33a71e3c..42662ef2b 100644 --- a/modules/agency/front/location/index.html +++ b/modules/agency/front/location/index.html @@ -12,8 +12,9 @@ on-search="$ctrl.onSearch()" vn-focus> - + diff --git a/modules/worker/back/methods/department/nodeAdd.js b/modules/worker/back/methods/department/nodeAdd.js index bbbcd82ef..58c50f0bd 100644 --- a/modules/worker/back/methods/department/nodeAdd.js +++ b/modules/worker/back/methods/department/nodeAdd.js @@ -29,7 +29,7 @@ module.exports = Self => { let stmts = []; let conn = Self.dataSource.connector; let nodeIndex = stmts.push(new ParameterizedSQL( - `CALL nst.NodeAdd('vn', 'department', ?, ?)`, [parentFk, name])) - 1; + `CALL nst.nodeAdd('vn', 'department', ?, ?)`, [parentFk, name])) - 1; stmts.push(`CALL nst.nodeRecalc('vn', 'department')`); diff --git a/modules/worker/back/models/department.js b/modules/worker/back/models/department.js index 99b470dbb..085c2bf9b 100644 --- a/modules/worker/back/models/department.js +++ b/modules/worker/back/models/department.js @@ -8,10 +8,6 @@ module.exports = Self => { Self.rewriteDbError(function(err) { if (err.code === 'ER_ROW_IS_REFERENCED_2') return new UserError(`You cannot remove this department`); - return err; - }); - - Self.rewriteDbError(function(err) { if (err.code === 'ER_DUP_ENTRY') return new UserError(`The department name can't be repeated`); return err; diff --git a/modules/worker/front/department/index.html b/modules/worker/front/department/index.html index 5dac26eca..6cf2cd063 100644 --- a/modules/worker/front/department/index.html +++ b/modules/worker/front/department/index.html @@ -12,7 +12,9 @@ on-selection="$ctrl.onSelection(item, value)" on-create="$ctrl.onCreate(parent)" on-drop="$ctrl.onDrop(item, dragged, dropped)" - icons="$ctrl.icons" editable="true" acl-role="hr"> + icons="$ctrl.icons" + draggable="true" droppable="true" + acl-role="hr" editable="true">