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';
|
import './style.scss';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calendar.
|
* Flat calendar.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export default class Calendar extends Component {
|
export default class Calendar extends Component {
|
||||||
|
|
|
@ -1,18 +1,17 @@
|
||||||
<ul ng-if="::$ctrl.items">
|
<ul ng-if="::$ctrl.items">
|
||||||
<li ng-repeat="item in $ctrl.items"
|
<li ng-repeat="item in $ctrl.items"
|
||||||
ng-class="{
|
ng-class="{
|
||||||
'expanded': item.active,
|
'expanded': item.active,
|
||||||
'collapsed': !item.active,
|
'collapsed': !item.active,
|
||||||
'included': item.selected == 1,
|
'included': item.selected == 1,
|
||||||
'excluded': item.selected == 0
|
'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-horizontal>
|
||||||
<vn-auto class="actions">
|
<vn-auto class="actions">
|
||||||
<vn-icon icon="keyboard_arrow_down" title="{{'Toggle' | translate}}"
|
<vn-icon icon="keyboard_arrow_down" title="{{'Toggle' | translate}}"
|
||||||
ng-click="$ctrl.toggle(item, $event)">
|
ng-click="$ctrl.toggle(item, $event)">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
</vn-auto>
|
</vn-auto>
|
||||||
<vn-one class="description">
|
|
||||||
<vn-check vn-auto vn-acl="{{$ctrl.aclRole}}"
|
<vn-check vn-auto vn-acl="{{$ctrl.aclRole}}"
|
||||||
ng-if="$ctrl.selectable"
|
ng-if="$ctrl.selectable"
|
||||||
field="item.selected"
|
field="item.selected"
|
||||||
|
@ -20,35 +19,37 @@
|
||||||
on-change="$ctrl.select(item, value)"
|
on-change="$ctrl.select(item, value)"
|
||||||
triple-state="true">
|
triple-state="true">
|
||||||
</vn-check>
|
</vn-check>
|
||||||
{{::item.name}}
|
<vn-one class="description">{{::item.name}}</vn-one>
|
||||||
</vn-one>
|
<vn-auto>
|
||||||
<vn-auto>
|
<vn-icon-button icon="{{icon.icon}}"
|
||||||
<vn-icon-button icon="{{icon.icon}}"
|
ng-repeat="icon in $ctrl.icons"
|
||||||
ng-repeat="icon in $ctrl.icons"
|
ng-click="$ctrl.onIconClick(icon, item, $ctrl.parent, $parent.$index)"
|
||||||
ng-click="$ctrl.onIconClick(icon, item, $ctrl.parent, $parent.$index)"
|
vn-acl="{{$ctrl.aclRole}}" vn-acl-action="remove">
|
||||||
vn-acl="{{$ctrl.aclRole}}" vn-acl-action="remove">
|
</vn-icon-button>
|
||||||
</vn-icon-button>
|
</vn-auto>
|
||||||
</vn-auto>
|
</vn-horizontal>
|
||||||
</vn-horizontal>
|
<vn-treeview-child items="item.childs" parent="item"
|
||||||
<vn-treeview-child items="item.childs" parent="item"
|
selectable="$ctrl.selectable"
|
||||||
selectable="$ctrl.selectable"
|
disabled="$ctrl.disabled"
|
||||||
disabled="$ctrl.disabled"
|
editable="$ctrl.editable"
|
||||||
editable="$ctrl.editable"
|
draggable="::$ctrl.draggable"
|
||||||
icons="$ctrl.icons"
|
droppable="::$ctrl.droppable"
|
||||||
acl-role="$ctrl.aclRole">
|
icons="::$ctrl.icons"
|
||||||
</vn-treeview-child>
|
parent-scope="::$ctrl.parentScope"
|
||||||
</li>
|
acl-role="$ctrl.aclRole">
|
||||||
<li ng-if="$ctrl.isInsertable && $ctrl.editable"
|
</vn-treeview-child>
|
||||||
ng-click="$ctrl.onCreate($ctrl.parent)"
|
</li>
|
||||||
vn-acl="{{$ctrl.aclRole}}"
|
<li ng-if="$ctrl.isInsertable && $ctrl.editable"
|
||||||
vn-acl-action="remove">
|
ng-click="$ctrl.onCreate($ctrl.parent)"
|
||||||
<vn-horizontal>
|
vn-acl="{{$ctrl.aclRole}}"
|
||||||
<vn-auto>
|
vn-acl-action="remove">
|
||||||
<vn-icon-button icon="add_circle"></vn-icon-button>
|
<vn-horizontal>
|
||||||
</vn-auto>
|
<vn-auto>
|
||||||
<div class="description" translate>
|
<vn-icon-button icon="add_circle"></vn-icon-button>
|
||||||
Create new one
|
</vn-auto>
|
||||||
</div>
|
<div class="description" translate>
|
||||||
</vn-horizontal>
|
Create new one
|
||||||
</li>
|
</div>
|
||||||
</ul>
|
</vn-horizontal>
|
||||||
|
</li>
|
||||||
|
</ul>
|
|
@ -16,8 +16,7 @@ class Controller extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
onIconClick(icon, item, parent, index) {
|
onIconClick(icon, item, parent, index) {
|
||||||
let parentScope = this.$scope.$parent.$parent;
|
let parentController = this.parentScope.$ctrl;
|
||||||
let parentController = parentScope.$ctrl;
|
|
||||||
icon.callback.call(parentController, item, parent, index);
|
icon.callback.call(parentController, item, parent, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +43,10 @@ ngModule.component('vnTreeviewChild', {
|
||||||
disabled: '<?',
|
disabled: '<?',
|
||||||
selectable: '<?',
|
selectable: '<?',
|
||||||
editable: '<?',
|
editable: '<?',
|
||||||
|
draggable: '<?',
|
||||||
|
droppable: '<?',
|
||||||
aclRole: '<?',
|
aclRole: '<?',
|
||||||
|
parentScope: '<'
|
||||||
},
|
},
|
||||||
require: {
|
require: {
|
||||||
treeview: '^vnTreeview'
|
treeview: '^vnTreeview'
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
<vn-treeview-child
|
<vn-treeview-child acl-role="$ctrl.aclRole"
|
||||||
items="$ctrl.data"
|
items="$ctrl.data"
|
||||||
parent="$ctrl.data"
|
parent="$ctrl.data"
|
||||||
selectable="$ctrl.selectable"
|
selectable="$ctrl.selectable"
|
||||||
editable="$ctrl.editable"
|
editable="$ctrl.editable"
|
||||||
disabled="$ctrl.disabled"
|
disabled="$ctrl.disabled"
|
||||||
icons="$ctrl.icons"
|
icons="$ctrl.icons"
|
||||||
acl-role="$ctrl.aclRole"
|
parent-scope="$ctrl.$scope.$parent"
|
||||||
vn-droppable>
|
draggable="$ctrl.draggable"
|
||||||
|
droppable="$ctrl.droppable"
|
||||||
|
vn-droppable="{{$ctrl.droppable}}">
|
||||||
</vn-treeview-child>
|
</vn-treeview-child>
|
||||||
|
|
|
@ -3,13 +3,14 @@ import Component from '../../lib/component';
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A simple tooltip.
|
* Treeview
|
||||||
*
|
*
|
||||||
* @property {String} position The relative position to the parent
|
* @property {String} position The relative position to the parent
|
||||||
*/
|
*/
|
||||||
export default class Treeview extends Component {
|
export default class Treeview extends Component {
|
||||||
constructor($element, $scope) {
|
constructor($element, $scope) {
|
||||||
super($element, $scope);
|
super($element, $scope);
|
||||||
|
this.$scope = $scope;
|
||||||
this.data = [];
|
this.data = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +87,8 @@ ngModule.component('vnTreeview', {
|
||||||
disabled: '<?',
|
disabled: '<?',
|
||||||
selectable: '<?',
|
selectable: '<?',
|
||||||
editable: '<?',
|
editable: '<?',
|
||||||
|
draggable: '<?',
|
||||||
|
droppable: '<?',
|
||||||
aclRole: '@?'
|
aclRole: '@?'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -24,10 +24,6 @@ vn-treeview {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
li[vn-draggable] {
|
|
||||||
cursor: move
|
|
||||||
}
|
|
||||||
|
|
||||||
li vn-icon {
|
li vn-icon {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
@ -58,19 +54,22 @@ vn-treeview {
|
||||||
& > vn-horizontal > .description {
|
& > vn-horizontal > .description {
|
||||||
color: $color-notice;
|
color: $color-notice;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
||||||
& > vn-check .md-icon {
|
|
||||||
background-color: $color-notice
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& > vn-horizontal > vn-check .md-icon {
|
||||||
|
background-color: $color-notice
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
li.excluded {
|
li.excluded {
|
||||||
& > vn-horizontal > .description {
|
& > vn-horizontal > .description {
|
||||||
color: $color-alert;
|
color: $color-alert;
|
||||||
font-weight: bold;
|
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() {
|
export function directive() {
|
||||||
return {
|
return {
|
||||||
restrict: 'A',
|
restrict: 'A',
|
||||||
link: function($scope, $element) {
|
link: function($scope, $element, $attrs) {
|
||||||
const element = $element[0];
|
const element = $element[0];
|
||||||
|
const isDraggable = $attrs.vnDraggable === 'true';
|
||||||
|
|
||||||
|
if (!isDraggable) return;
|
||||||
|
|
||||||
|
// Set draggable style properties
|
||||||
|
element.style.cursor = 'move';
|
||||||
|
|
||||||
|
|
||||||
// Enable as draggable element
|
// Enable as draggable element
|
||||||
element.setAttribute('draggable', true);
|
element.setAttribute('draggable', true);
|
||||||
|
|
|
@ -7,6 +7,9 @@ export function directive($parse) {
|
||||||
link: function($scope, $element, $attrs) {
|
link: function($scope, $element, $attrs) {
|
||||||
const element = $element[0];
|
const element = $element[0];
|
||||||
const onDropEvent = $parse($attrs.onDrop);
|
const onDropEvent = $parse($attrs.onDrop);
|
||||||
|
const isDroppable = $attrs.vnDroppable === 'true';
|
||||||
|
|
||||||
|
if (!isDroppable) return;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Captures current dragging element
|
* Captures current dragging element
|
||||||
|
|
|
@ -12,8 +12,9 @@
|
||||||
on-search="$ctrl.onSearch()"
|
on-search="$ctrl.onSearch()"
|
||||||
vn-focus>
|
vn-focus>
|
||||||
</vn-searchbar>
|
</vn-searchbar>
|
||||||
<vn-treeview vn-id="treeview" model="model" selectable="true" acl-role="deliveryBoss"
|
<vn-treeview vn-id="treeview" model="model" acl-role="deliveryBoss"
|
||||||
on-selection="$ctrl.onSelection(item, value)">
|
on-selection="$ctrl.onSelection(item, value)"
|
||||||
|
selectable="true">
|
||||||
</vn-treeview>
|
</vn-treeview>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
<vn-side-menu side="right">
|
<vn-side-menu side="right">
|
||||||
|
|
|
@ -29,7 +29,7 @@ module.exports = Self => {
|
||||||
let stmts = [];
|
let stmts = [];
|
||||||
let conn = Self.dataSource.connector;
|
let conn = Self.dataSource.connector;
|
||||||
let nodeIndex = stmts.push(new ParameterizedSQL(
|
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')`);
|
stmts.push(`CALL nst.nodeRecalc('vn', 'department')`);
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,6 @@ module.exports = Self => {
|
||||||
Self.rewriteDbError(function(err) {
|
Self.rewriteDbError(function(err) {
|
||||||
if (err.code === 'ER_ROW_IS_REFERENCED_2')
|
if (err.code === 'ER_ROW_IS_REFERENCED_2')
|
||||||
return new UserError(`You cannot remove this department`);
|
return new UserError(`You cannot remove this department`);
|
||||||
return err;
|
|
||||||
});
|
|
||||||
|
|
||||||
Self.rewriteDbError(function(err) {
|
|
||||||
if (err.code === 'ER_DUP_ENTRY')
|
if (err.code === 'ER_DUP_ENTRY')
|
||||||
return new UserError(`The department name can't be repeated`);
|
return new UserError(`The department name can't be repeated`);
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -12,7 +12,9 @@
|
||||||
on-selection="$ctrl.onSelection(item, value)"
|
on-selection="$ctrl.onSelection(item, value)"
|
||||||
on-create="$ctrl.onCreate(parent)"
|
on-create="$ctrl.onCreate(parent)"
|
||||||
on-drop="$ctrl.onDrop(item, dragged, dropped)"
|
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-treeview>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue