parent
a8a5193a86
commit
69403223d8
|
@ -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 ;
|
||||
|
|
@ -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 ;
|
||||
|
|
@ -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 ;
|
||||
|
|
@ -3,7 +3,7 @@ import Component from '../../lib/component';
|
|||
import './style.scss';
|
||||
|
||||
/**
|
||||
* Calendar.
|
||||
* Flat calendar.
|
||||
*
|
||||
*/
|
||||
export default class Calendar extends Component {
|
||||
|
|
|
@ -5,14 +5,13 @@
|
|||
'collapsed': !item.active,
|
||||
'included': item.selected == 1,
|
||||
'excluded': item.selected == 0
|
||||
}" vn-draggable vn-droppable on-drop="$ctrl.onDrop(item, dragged, dropped)">
|
||||
}" vn-draggable="{{::$ctrl.draggable}}" vn-droppable="{{::$ctrl.droppable}}" on-drop="$ctrl.onDrop(item, dragged, dropped)">
|
||||
<vn-horizontal>
|
||||
<vn-auto class="actions">
|
||||
<vn-icon icon="keyboard_arrow_down" title="{{'Toggle' | translate}}"
|
||||
ng-click="$ctrl.toggle(item, $event)">
|
||||
</vn-icon>
|
||||
</vn-auto>
|
||||
<vn-one class="description">
|
||||
<vn-check vn-auto vn-acl="{{$ctrl.aclRole}}"
|
||||
ng-if="$ctrl.selectable"
|
||||
field="item.selected"
|
||||
|
@ -20,8 +19,7 @@
|
|||
on-change="$ctrl.select(item, value)"
|
||||
triple-state="true">
|
||||
</vn-check>
|
||||
{{::item.name}}
|
||||
</vn-one>
|
||||
<vn-one class="description">{{::item.name}}</vn-one>
|
||||
<vn-auto>
|
||||
<vn-icon-button icon="{{icon.icon}}"
|
||||
ng-repeat="icon in $ctrl.icons"
|
||||
|
@ -34,7 +32,10 @@
|
|||
selectable="$ctrl.selectable"
|
||||
disabled="$ctrl.disabled"
|
||||
editable="$ctrl.editable"
|
||||
icons="$ctrl.icons"
|
||||
draggable="::$ctrl.draggable"
|
||||
droppable="::$ctrl.droppable"
|
||||
icons="::$ctrl.icons"
|
||||
parent-scope="::$ctrl.parentScope"
|
||||
acl-role="$ctrl.aclRole">
|
||||
</vn-treeview-child>
|
||||
</li>
|
||||
|
|
|
@ -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: '<?',
|
||||
selectable: '<?',
|
||||
editable: '<?',
|
||||
draggable: '<?',
|
||||
droppable: '<?',
|
||||
aclRole: '<?',
|
||||
parentScope: '<'
|
||||
},
|
||||
require: {
|
||||
treeview: '^vnTreeview'
|
||||
|
|
|
@ -1,10 +1,12 @@
|
|||
<vn-treeview-child
|
||||
<vn-treeview-child acl-role="$ctrl.aclRole"
|
||||
items="$ctrl.data"
|
||||
parent="$ctrl.data"
|
||||
selectable="$ctrl.selectable"
|
||||
editable="$ctrl.editable"
|
||||
disabled="$ctrl.disabled"
|
||||
icons="$ctrl.icons"
|
||||
acl-role="$ctrl.aclRole"
|
||||
vn-droppable>
|
||||
parent-scope="$ctrl.$scope.$parent"
|
||||
draggable="$ctrl.draggable"
|
||||
droppable="$ctrl.droppable"
|
||||
vn-droppable="{{$ctrl.droppable}}">
|
||||
</vn-treeview-child>
|
||||
|
|
|
@ -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: '<?',
|
||||
selectable: '<?',
|
||||
editable: '<?',
|
||||
draggable: '<?',
|
||||
droppable: '<?',
|
||||
aclRole: '@?'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -24,10 +24,6 @@ vn-treeview {
|
|||
}
|
||||
}
|
||||
|
||||
li[vn-draggable] {
|
||||
cursor: move
|
||||
}
|
||||
|
||||
li vn-icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -58,19 +54,22 @@ vn-treeview {
|
|||
& > vn-horizontal > .description {
|
||||
color: $color-notice;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
& > vn-check .md-icon {
|
||||
& > 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -12,8 +12,9 @@
|
|||
on-search="$ctrl.onSearch()"
|
||||
vn-focus>
|
||||
</vn-searchbar>
|
||||
<vn-treeview vn-id="treeview" model="model" selectable="true" acl-role="deliveryBoss"
|
||||
on-selection="$ctrl.onSelection(item, value)">
|
||||
<vn-treeview vn-id="treeview" model="model" acl-role="deliveryBoss"
|
||||
on-selection="$ctrl.onSelection(item, value)"
|
||||
selectable="true">
|
||||
</vn-treeview>
|
||||
</vn-card>
|
||||
<vn-side-menu side="right">
|
||||
|
|
|
@ -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')`);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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">
|
||||
</vn-treeview>
|
||||
</vn-card>
|
||||
</div>
|
||||
|
|
Loading…
Reference in New Issue