first changes
gitea/salix/1625-worker_department_treeview This commit looks good
Details
gitea/salix/1625-worker_department_treeview This commit looks good
Details
This commit is contained in:
parent
daeb4bed09
commit
183d770483
|
@ -0,0 +1,73 @@
|
||||||
|
ALTER TABLE `vn2008`.`department`
|
||||||
|
ADD COLUMN `parentFk` INT UNSIGNED NULL AFTER `sons`,
|
||||||
|
ADD COLUMN `path` VARCHAR(255) NULL AFTER `parentFk`,
|
||||||
|
CHANGE COLUMN `sons` `sons` DECIMAL(10,0) NOT NULL DEFAULT '0' ;
|
||||||
|
|
||||||
|
USE `vn`;
|
||||||
|
CREATE
|
||||||
|
OR REPLACE ALGORITHM = UNDEFINED
|
||||||
|
DEFINER = `root`@`%`
|
||||||
|
SQL SECURITY DEFINER
|
||||||
|
VIEW `department` AS
|
||||||
|
SELECT
|
||||||
|
`b`.`department_id` AS `id`,
|
||||||
|
`b`.`name` AS `name`,
|
||||||
|
`b`.`production` AS `isProduction`,
|
||||||
|
`b`.`parentFk` AS `parentFk`,
|
||||||
|
`b`.`path` AS `path`,
|
||||||
|
`b`.`lft` AS `lft`,
|
||||||
|
`b`.`rgt` AS `rgt`,
|
||||||
|
`b`.`isSelected` AS `isSelected`,
|
||||||
|
`b`.`depth` AS `depth`,
|
||||||
|
`b`.`sons` AS `sons`
|
||||||
|
FROM
|
||||||
|
`vn2008`.`department` `b`;
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS `vn2008`.`department_AFTER_DELETE`;
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
USE `vn2008`$$
|
||||||
|
CREATE DEFINER = CURRENT_USER TRIGGER `vn2008`.`department_AFTER_DELETE`
|
||||||
|
AFTER DELETE ON `department` FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
UPDATE vn.department_recalc SET isChanged = TRUE;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS `vn2008`.`department_BEFORE_INSERT`;
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
USE `vn2008`$$
|
||||||
|
CREATE DEFINER = CURRENT_USER TRIGGER `vn2008`.`department_BEFORE_INSERT`
|
||||||
|
BEFORE INSERT ON `department` FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
UPDATE vn.department_recalc SET isChanged = TRUE;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
DROP TRIGGER IF EXISTS `vn2008`.`department_AFTER_UPDATE`;
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
USE `vn2008`$$
|
||||||
|
CREATE DEFINER = CURRENT_USER TRIGGER `vn2008`.`department_AFTER_UPDATE`
|
||||||
|
AFTER UPDATE ON `department` FOR EACH ROW
|
||||||
|
BEGIN
|
||||||
|
IF !(OLD.parentFk <=> NEW.parentFk) THEN
|
||||||
|
UPDATE vn.department_recalc SET isChanged = TRUE;
|
||||||
|
END IF;
|
||||||
|
END$$
|
||||||
|
DELIMITER ;
|
||||||
|
|
||||||
|
CREATE TABLE `vn`.`department_recalc` (
|
||||||
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||||
|
`isChanged` TINYINT(4) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`));
|
||||||
|
|
||||||
|
INSERT INTO `vn`.`department_recalc` (`id`, `isChanged`) VALUES ('1', '0');
|
||||||
|
|
||||||
|
|
||||||
|
ALTER TABLE `vn2008`.`department`
|
||||||
|
CHANGE COLUMN `lft` `lft` INT(11) NULL ,
|
||||||
|
CHANGE COLUMN `rgt` `rgt` INT(11) NULL ;
|
||||||
|
|
||||||
|
UPDATE vn.department SET lft = NULL, rgt = NULL;
|
|
@ -0,0 +1,37 @@
|
||||||
|
USE `vn`;
|
||||||
|
DROP procedure IF EXISTS `department_calcTree`;
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
USE `vn`$$
|
||||||
|
CREATE DEFINER=`root`@`%` PROCEDURE `department_calcTree`()
|
||||||
|
BEGIN
|
||||||
|
/**
|
||||||
|
* Calculates the #path, #lft, #rgt, #sons and #depth columns of
|
||||||
|
* the #department table. To build the tree, it uses the #parentFk
|
||||||
|
* column.
|
||||||
|
*/
|
||||||
|
DECLARE vIndex INT DEFAULT 0;
|
||||||
|
DECLARE vSons INT;
|
||||||
|
|
||||||
|
DROP TEMPORARY TABLE IF EXISTS tNestedTree;
|
||||||
|
CREATE TEMPORARY TABLE tNestedTree
|
||||||
|
SELECT id, path, lft, rgt, depth, sons
|
||||||
|
FROM department LIMIT 0;
|
||||||
|
|
||||||
|
SET max_sp_recursion_depth = 5;
|
||||||
|
CALL department_calcTreeRec(NULL, '/', 0, vIndex, vSons);
|
||||||
|
SET max_sp_recursion_depth = 0;
|
||||||
|
|
||||||
|
UPDATE department z
|
||||||
|
JOIN tNestedTree t ON t.id = z.id
|
||||||
|
SET z.path = t.path,
|
||||||
|
z.lft = t.lft,
|
||||||
|
z.rgt = t.rgt,
|
||||||
|
z.depth = t.depth,
|
||||||
|
z.sons = t.sons;
|
||||||
|
|
||||||
|
DROP TEMPORARY TABLE tNestedTree;
|
||||||
|
END$$
|
||||||
|
|
||||||
|
DELIMITER ;
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
USE `vn`;
|
||||||
|
DROP procedure IF EXISTS `department_calcTreeRec`;
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
USE `vn`$$
|
||||||
|
CREATE DEFINER=`root`@`%` PROCEDURE `department_calcTreeRec`(
|
||||||
|
vSelf INT,
|
||||||
|
vPath VARCHAR(255),
|
||||||
|
vDepth INT,
|
||||||
|
INOUT vIndex INT,
|
||||||
|
OUT vSons INT
|
||||||
|
)
|
||||||
|
BEGIN
|
||||||
|
/**
|
||||||
|
* Calculates and sets the #path, #lft, #rgt, #sons and #depth
|
||||||
|
* columns for all children of the passed node. Once calculated
|
||||||
|
* the last node rgt index and the number of sons are returned.
|
||||||
|
* To update it's children, this procedure calls itself recursively
|
||||||
|
* for each one.
|
||||||
|
*
|
||||||
|
* @vSelf The node identifier
|
||||||
|
* @vPath The initial path
|
||||||
|
* @vDepth The initial depth
|
||||||
|
* @vIndex The initial lft index
|
||||||
|
* @vSons The number of direct sons
|
||||||
|
*/
|
||||||
|
DECLARE vChildFk INT;
|
||||||
|
DECLARE vLft INT;
|
||||||
|
DECLARE vMySons INT;
|
||||||
|
DECLARE vDone BOOL;
|
||||||
|
DECLARE vChildren CURSOR FOR
|
||||||
|
SELECT id FROM department
|
||||||
|
WHERE (vSelf IS NULL AND parentFk IS NULL)
|
||||||
|
OR (vSelf IS NOT NULL AND parentFk = vSelf);
|
||||||
|
|
||||||
|
DECLARE CONTINUE HANDLER FOR NOT FOUND SET vDone = TRUE;
|
||||||
|
|
||||||
|
SET vSons = 0;
|
||||||
|
|
||||||
|
OPEN vChildren;
|
||||||
|
myLoop: LOOP
|
||||||
|
SET vDone = FALSE;
|
||||||
|
FETCH vChildren INTO vChildFk;
|
||||||
|
|
||||||
|
IF vDone THEN
|
||||||
|
LEAVE myLoop;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
SET vIndex = vIndex + 1;
|
||||||
|
SET vLft = vIndex;
|
||||||
|
SET vSons = vSons + 1;
|
||||||
|
|
||||||
|
CALL department_calcTreeRec(
|
||||||
|
vChildFk,
|
||||||
|
CONCAT(vPath, vChildFk, '/'),
|
||||||
|
vDepth + 1,
|
||||||
|
vIndex,
|
||||||
|
vMySons
|
||||||
|
);
|
||||||
|
|
||||||
|
SET vIndex = vIndex + 1;
|
||||||
|
|
||||||
|
INSERT INTO tNestedTree
|
||||||
|
SET id = vChildFk,
|
||||||
|
path = vPath,
|
||||||
|
lft = vLft,
|
||||||
|
rgt = vIndex,
|
||||||
|
depth = vDepth,
|
||||||
|
sons = vMySons;
|
||||||
|
END LOOP;
|
||||||
|
CLOSE vChildren;
|
||||||
|
END$$
|
||||||
|
|
||||||
|
DELIMITER ;
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
USE `vn`;
|
||||||
|
DROP procedure IF EXISTS `department_doCalc`;
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
USE `vn`$$
|
||||||
|
CREATE DEFINER=`root`@`%` PROCEDURE `department_doCalc`()
|
||||||
|
proc: BEGIN
|
||||||
|
/**
|
||||||
|
* Recalculates the department tree.
|
||||||
|
*/
|
||||||
|
DECLARE vIsChanged BOOL;
|
||||||
|
|
||||||
|
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
|
||||||
|
BEGIN
|
||||||
|
DO RELEASE_LOCK('vn.department_doCalc');
|
||||||
|
RESIGNAL;
|
||||||
|
END;
|
||||||
|
|
||||||
|
IF !GET_LOCK('vn.department_doCalc', 0) THEN
|
||||||
|
LEAVE proc;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
SELECT isChanged INTO vIsChanged
|
||||||
|
FROM department_recalc;
|
||||||
|
|
||||||
|
IF vIsChanged THEN
|
||||||
|
UPDATE department_recalc SET isChanged = FALSE;
|
||||||
|
CALL vn.department_calcTree;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
DO RELEASE_LOCK('vn.department_doCalc');
|
||||||
|
END$$
|
||||||
|
|
||||||
|
DELIMITER ;
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
USE `vn`;
|
||||||
|
DROP procedure IF EXISTS `department_getLeaves`;
|
||||||
|
|
||||||
|
DELIMITER $$
|
||||||
|
USE `vn`$$
|
||||||
|
CREATE DEFINER=`root`@`%` PROCEDURE `department_getLeaves`(
|
||||||
|
vParentFk INT,
|
||||||
|
vSearch VARCHAR(255)
|
||||||
|
)
|
||||||
|
BEGIN
|
||||||
|
DECLARE vIsNumber BOOL;
|
||||||
|
DECLARE vIsSearch BOOL DEFAULT vSearch IS NOT NULL AND vSearch != '';
|
||||||
|
|
||||||
|
DROP TEMPORARY TABLE IF EXISTS tNodes;
|
||||||
|
CREATE TEMPORARY TABLE tNodes
|
||||||
|
(UNIQUE (id))
|
||||||
|
ENGINE = MEMORY
|
||||||
|
SELECT id FROM department LIMIT 0;
|
||||||
|
|
||||||
|
IF vIsSearch THEN
|
||||||
|
SET vIsNumber = vSearch REGEXP '^[0-9]+$';
|
||||||
|
|
||||||
|
INSERT INTO tNodes
|
||||||
|
SELECT id FROM department
|
||||||
|
WHERE (vIsNumber AND `name` = vSearch)
|
||||||
|
OR (!vIsNumber AND `name` LIKE CONCAT('%', vSearch, '%'))
|
||||||
|
LIMIT 1000;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF vParentFk IS NULL THEN
|
||||||
|
DROP TEMPORARY TABLE IF EXISTS tChilds;
|
||||||
|
CREATE TEMPORARY TABLE tChilds
|
||||||
|
ENGINE = MEMORY
|
||||||
|
SELECT id FROM tNodes;
|
||||||
|
|
||||||
|
DROP TEMPORARY TABLE IF EXISTS tParents;
|
||||||
|
CREATE TEMPORARY TABLE tParents
|
||||||
|
ENGINE = MEMORY
|
||||||
|
SELECT id FROM department LIMIT 0;
|
||||||
|
|
||||||
|
myLoop: LOOP
|
||||||
|
DELETE FROM tParents;
|
||||||
|
INSERT INTO tParents
|
||||||
|
SELECT parentFk id
|
||||||
|
FROM department g
|
||||||
|
JOIN tChilds c ON c.id = g.id
|
||||||
|
WHERE g.parentFk IS NOT NULL;
|
||||||
|
|
||||||
|
INSERT IGNORE INTO tNodes
|
||||||
|
SELECT id FROM tParents;
|
||||||
|
|
||||||
|
IF ROW_COUNT() = 0 THEN
|
||||||
|
LEAVE myLoop;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
DELETE FROM tChilds;
|
||||||
|
INSERT INTO tChilds
|
||||||
|
SELECT id FROM tParents;
|
||||||
|
END LOOP;
|
||||||
|
|
||||||
|
DROP TEMPORARY TABLE
|
||||||
|
tChilds,
|
||||||
|
tParents;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF !vIsSearch THEN
|
||||||
|
INSERT IGNORE INTO tNodes
|
||||||
|
SELECT id FROM department
|
||||||
|
WHERE parentFk <=> vParentFk;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
SELECT d.id,
|
||||||
|
d.`name`,
|
||||||
|
d.parentFk,
|
||||||
|
d.sons
|
||||||
|
FROM department d
|
||||||
|
JOIN tNodes n ON n.id = d.id
|
||||||
|
ORDER BY depth, `name`;
|
||||||
|
|
||||||
|
DROP TEMPORARY TABLE tNodes;
|
||||||
|
END$$
|
||||||
|
|
||||||
|
DELIMITER ;
|
||||||
|
|
|
@ -14,7 +14,8 @@
|
||||||
icon="keyboard_arrow_down"
|
icon="keyboard_arrow_down"
|
||||||
translate-attr="{title: 'Toggle'}">
|
translate-attr="{title: 'Toggle'}">
|
||||||
</vn-icon>
|
</vn-icon>
|
||||||
<vn-check
|
<section class="tplItem"></section>
|
||||||
|
<!-- <vn-check
|
||||||
vn-acl="{{$ctrl.aclRole}}"
|
vn-acl="{{$ctrl.aclRole}}"
|
||||||
ng-if="$ctrl.selectable"
|
ng-if="$ctrl.selectable"
|
||||||
field="item.selected"
|
field="item.selected"
|
||||||
|
@ -29,9 +30,9 @@
|
||||||
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="{{$ctrl.aclRole}}"
|
||||||
vn-acl-action="remove">
|
vn-acl-action="remove">
|
||||||
</vn-icon-button>
|
</vn-icon-button> -->
|
||||||
</div>
|
</div>
|
||||||
<vn-treeview-child
|
<!-- <vn-treeview-child
|
||||||
items="item.childs"
|
items="item.childs"
|
||||||
parent="item"
|
parent="item"
|
||||||
selectable="$ctrl.selectable"
|
selectable="$ctrl.selectable"
|
||||||
|
@ -42,9 +43,9 @@
|
||||||
icons="::$ctrl.icons"
|
icons="::$ctrl.icons"
|
||||||
parent-scope="::$ctrl.parentScope"
|
parent-scope="::$ctrl.parentScope"
|
||||||
acl-role="$ctrl.aclRole">
|
acl-role="$ctrl.aclRole">
|
||||||
</vn-treeview-child>
|
</vn-treeview-child> -->
|
||||||
</li>
|
</li>
|
||||||
<li
|
<!-- <li
|
||||||
ng-if="$ctrl.isInsertable && $ctrl.editable"
|
ng-if="$ctrl.isInsertable && $ctrl.editable"
|
||||||
ng-click="$ctrl.onCreate($ctrl.parent)"
|
ng-click="$ctrl.onCreate($ctrl.parent)"
|
||||||
vn-acl="{{$ctrl.aclRole}}"
|
vn-acl="{{$ctrl.aclRole}}"
|
||||||
|
@ -57,5 +58,5 @@
|
||||||
Create new one
|
Create new one
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li> -->
|
||||||
</ul>
|
</ul>
|
|
@ -2,9 +2,14 @@ import ngModule from '../../module';
|
||||||
import Component from '../../lib/component';
|
import Component from '../../lib/component';
|
||||||
|
|
||||||
class Controller extends Component {
|
class Controller extends Component {
|
||||||
constructor($element, $scope) {
|
constructor($element, $scope, $transclude) {
|
||||||
super($element, $scope);
|
super($element, $scope);
|
||||||
this.$scope = $scope;
|
this.$scope = $scope;
|
||||||
|
this.$transclude = $transclude;
|
||||||
|
|
||||||
|
$transclude($scope.$parent, tClone => {
|
||||||
|
this.element.querySelector('.tplItem').appendChild(tClone[0]);
|
||||||
|
}, null, 'tplItem');
|
||||||
}
|
}
|
||||||
|
|
||||||
toggle(event, item) {
|
toggle(event, item) {
|
||||||
|
@ -35,6 +40,8 @@ class Controller extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Controller.$inject = ['$element', '$scope', '$transclude'];
|
||||||
|
|
||||||
ngModule.component('vnTreeviewChild', {
|
ngModule.component('vnTreeviewChild', {
|
||||||
template: require('./child.html'),
|
template: require('./child.html'),
|
||||||
controller: Controller,
|
controller: Controller,
|
||||||
|
@ -50,6 +57,9 @@ ngModule.component('vnTreeviewChild', {
|
||||||
aclRole: '<?',
|
aclRole: '<?',
|
||||||
parentScope: '<'
|
parentScope: '<'
|
||||||
},
|
},
|
||||||
|
transclude: {
|
||||||
|
tplItem: '?tplItem'
|
||||||
|
},
|
||||||
require: {
|
require: {
|
||||||
treeview: '^vnTreeview'
|
treeview: '^vnTreeview'
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,10 +8,18 @@ import './style.scss';
|
||||||
* @property {String} position The relative position to the parent
|
* @property {String} position The relative position to the parent
|
||||||
*/
|
*/
|
||||||
export default class Treeview extends Component {
|
export default class Treeview extends Component {
|
||||||
constructor($element, $scope) {
|
constructor($element, $scope, $transclude) {
|
||||||
super($element, $scope);
|
super($element, $scope);
|
||||||
this.$scope = $scope;
|
this.$scope = $scope;
|
||||||
|
this.$transclude = $transclude;
|
||||||
this.data = [];
|
this.data = [];
|
||||||
|
|
||||||
|
$transclude($scope.$parent, tClone => {
|
||||||
|
this.element.querySelector('vn-treeview-child').appendChild(tClone[0]);
|
||||||
|
// Object.assign(scope, option);
|
||||||
|
// li.appendChild(clone[0]);
|
||||||
|
// this.scopes[i] = scope;
|
||||||
|
}, null, 'tplItem');
|
||||||
}
|
}
|
||||||
|
|
||||||
$onInit() {
|
$onInit() {
|
||||||
|
@ -76,7 +84,7 @@ export default class Treeview extends Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Treeview.$inject = ['$element', '$scope'];
|
Treeview.$inject = ['$element', '$scope', '$transclude'];
|
||||||
|
|
||||||
ngModule.component('vnTreeview', {
|
ngModule.component('vnTreeview', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
|
@ -90,5 +98,8 @@ ngModule.component('vnTreeview', {
|
||||||
draggable: '<?',
|
draggable: '<?',
|
||||||
droppable: '<?',
|
droppable: '<?',
|
||||||
aclRole: '@?'
|
aclRole: '@?'
|
||||||
|
},
|
||||||
|
transclude: {
|
||||||
|
tplItem: '?tplItem'
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,20 +1,14 @@
|
||||||
|
|
||||||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethod('getLeaves', {
|
Self.remoteMethod('getLeaves', {
|
||||||
description: 'Returns the first shipped and landed possible for params',
|
description: 'Returns the nodes for a department',
|
||||||
accepts: [{
|
accepts: [{
|
||||||
arg: 'parentFk',
|
arg: 'parentFk',
|
||||||
type: 'Number',
|
type: 'Number',
|
||||||
default: 1,
|
description: 'Get the children of the specified father',
|
||||||
required: false,
|
}, {
|
||||||
},
|
arg: 'search',
|
||||||
{
|
type: 'String',
|
||||||
arg: 'filter',
|
description: 'Filter nodes whose name starts with',
|
||||||
type: 'Object',
|
|
||||||
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
|
||||||
http: {source: 'query'}
|
|
||||||
}],
|
}],
|
||||||
returns: {
|
returns: {
|
||||||
type: ['object'],
|
type: ['object'],
|
||||||
|
@ -26,61 +20,30 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.getLeaves = async(parentFk = 1, filter) => {
|
Self.getLeaves = async(parentFk = null, search) => {
|
||||||
let conn = Self.dataSource.connector;
|
let [res] = await Self.rawSql(
|
||||||
let stmt = new ParameterizedSQL(
|
`CALL department_getLeaves(?, ?)`,
|
||||||
`SELECT
|
[parentFk, search]
|
||||||
child.id,
|
);
|
||||||
child.name,
|
|
||||||
child.lft,
|
|
||||||
child.rgt,
|
|
||||||
child.depth,
|
|
||||||
child.sons
|
|
||||||
FROM department parent
|
|
||||||
JOIN department child ON child.lft > parent.lft
|
|
||||||
AND child.rgt < parent.rgt
|
|
||||||
AND child.depth = parent.depth + 1
|
|
||||||
WHERE parent.id = ?`, [parentFk]);
|
|
||||||
|
|
||||||
// Get nodes from depth greather than Origin
|
let map = new Map();
|
||||||
stmt.merge(conn.makeSuffix(filter));
|
for (let node of res) {
|
||||||
|
if (!map.has(node.parentFk))
|
||||||
const nodes = await Self.rawStmt(stmt);
|
map.set(node.parentFk, []);
|
||||||
|
map.get(node.parentFk).push(node);
|
||||||
if (nodes.length == 0)
|
|
||||||
return nodes;
|
|
||||||
|
|
||||||
// Get parent nodes
|
|
||||||
const minorDepth = nodes.reduce((a, b) => {
|
|
||||||
return b < a ? b : a;
|
|
||||||
}).depth;
|
|
||||||
|
|
||||||
const parentNodes = nodes.filter(element => {
|
|
||||||
return element.depth === minorDepth;
|
|
||||||
});
|
|
||||||
const leaves = Object.assign([], parentNodes);
|
|
||||||
|
|
||||||
nestLeaves(leaves);
|
|
||||||
|
|
||||||
function nestLeaves(elements) {
|
|
||||||
elements.forEach(element => {
|
|
||||||
let childs = Object.assign([], getLeaves(element));
|
|
||||||
if (childs.length > 0) {
|
|
||||||
element.childs = childs;
|
|
||||||
nestLeaves(element.childs);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getLeaves(parent) {
|
function setLeaves(nodes) {
|
||||||
let elements = nodes.filter(element => {
|
if (!nodes) return;
|
||||||
return element.lft > parent.lft && element.rgt < parent.rgt
|
for (let node of nodes) {
|
||||||
&& element.depth === parent.depth + 1;
|
node.childs = map.get(node.id);
|
||||||
});
|
setLeaves(node.childs);
|
||||||
|
}
|
||||||
return elements;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return leaves;
|
let leaves = map.get(parentFk);
|
||||||
|
setLeaves(leaves);
|
||||||
|
|
||||||
|
return leaves || [];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,25 +1,26 @@
|
||||||
<vn-crud-model
|
<vn-crud-model
|
||||||
vn-id="model"
|
vn-id="model"
|
||||||
url="/worker/api/departments/getLeaves"
|
url="/worker/api/departments/getLeaves"
|
||||||
params="::$ctrl.params"
|
|
||||||
auto-load="false">
|
auto-load="false">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
|
<div class="content-block" compact>
|
||||||
<form name="form">
|
<form name="form" compact>
|
||||||
<div margin-medium>
|
|
||||||
<vn-card margin-medium-v pad-medium>
|
<vn-card margin-medium-v pad-medium>
|
||||||
<vn-treeview vn-id="treeview" model="model"
|
<vn-treeview vn-id="treeview" model="model"
|
||||||
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"
|
icons="$ctrl.icons">
|
||||||
draggable="true" droppable="true"
|
<tpl-item>
|
||||||
acl-role="hr" editable="true">
|
test
|
||||||
|
</tpl-item>
|
||||||
</vn-treeview>
|
</vn-treeview>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
</div>
|
<vn-button-bar>
|
||||||
</form>
|
<vn-button ui-sref="worker.index" label="Back"></vn-button>
|
||||||
|
</vn-button-bar>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
<vn-confirm
|
<vn-confirm
|
||||||
vn-id="deleteNode"
|
vn-id="deleteNode"
|
||||||
on-response="$ctrl.onRemoveResponse(response)"
|
on-response="$ctrl.onRemoveResponse(response)"
|
||||||
|
|
|
@ -6,7 +6,6 @@ class Controller {
|
||||||
this.$http = $http;
|
this.$http = $http;
|
||||||
this.vnApp = vnApp;
|
this.vnApp = vnApp;
|
||||||
this.$translate = $translate;
|
this.$translate = $translate;
|
||||||
this.params = {parentFk: 1};
|
|
||||||
this.icons = [{icon: 'delete', tooltip: 'Delete', callback: this.onDelete}];
|
this.icons = [{icon: 'delete', tooltip: 'Delete', callback: this.onDelete}];
|
||||||
this.newNode = {
|
this.newNode = {
|
||||||
name: ''
|
name: ''
|
||||||
|
|
Loading…
Reference in New Issue