Commit 97a73800 authored by D’jalmar Gutierrez Titirico's avatar D’jalmar Gutierrez Titirico 🚲
Browse files

Merge branch 'iss6175-implementar-nuevo-organigrama' into 'desarrollo'

#42 Iss6175 implementar nuevo organigrama



See merge request !61
parents de1fea12 c82af783
...@@ -228,9 +228,9 @@ input[type=checkbox].with-font:checked ~ label:before { ...@@ -228,9 +228,9 @@ input[type=checkbox].with-font:checked ~ label:before {
@import 'tiposEntidad/tiposEntidad.scss'; @import 'tiposEntidad/tiposEntidad.scss';
@import '../components/footer/footer.scss'; @import '../components/footer/footer.scss';
@import '../components/modal/modal.scss'; @import '../components/modal/modal.scss';
@import '../components/organigrama/framework/angular-treant-js/Treant.scss';
@import '../components/organigrama/framework/angular-treant-js/collapsable.scss';
@import '../components/organigrama/framework/angular-treant-js/custom-colored.scss';
@import '../components/organigrama/framework/angular-treant-js/vendor/perfect-scrollbar/perfect-scrollbar.scss';
@import '../components/organigrama/framework/jquery.orgchart.scss'; @import '../components/organigrama/framework/jquery.orgchart.scss';
@import '../components/organigrama/framework/treant-js/Treant.scss';
@import '../components/organigrama/framework/treant-js/collapsable.scss';
@import '../components/organigrama/framework/treant-js/custom-colored.scss';
@import '../components/organigrama/framework/treant-js/vendor/perfect-scrollbar/perfect-scrollbar.scss';
// endinjector // endinjector
...@@ -14,24 +14,24 @@ ...@@ -14,24 +14,24 @@
this.cargoConvocatoria = Object.assign({cargo_superior_id: null}, this.cargoInicial); this.cargoConvocatoria = Object.assign({cargo_superior_id: null}, this.cargoInicial);
this.entidadSeleccionada = parametro.entidad; this.entidadSeleccionada = parametro.entidad;
this.entidades = {rows: [this.entidadSeleccionada], count: 1} this.entidades = {rows: [this.entidadSeleccionada], count: 1};
this.unidad = parametro.unidad; this.unidad = parametro.unidad;
this.unidadService.getUnidades() this.entidadService.unidadesOrganizacionales(this.entidadSeleccionada._id)
.then(unidades => { .then(unidades => {
this.unidades = unidades; this.unidades = unidades;
this.unidadSeleccionada = this.unidades.rows.find(x=>x._id === this.unidad._id); this.unidadSeleccionada = this.unidades.rows.find(x=>x._id === this.unidad._id);
}); });
this.service.getCargos() this.unidadService.cargos(this.unidad._id)
.then(cargosSuperiores => { .then(cargosSuperiores => {
this.cargosSuperiores = cargosSuperiores; this.cargosSuperiores = cargosSuperiores;
this.cargoSuperiorSeleccionada = this.cargosSuperiores.rows.find(x=>x._id === this.cargoInicial.cargo_superior_id); this.cargoSuperiorSeleccionada = this.cargosSuperiores.rows.find(x=>x._id === this.cargoInicial.cargo_superior_id);
}); });
if(this.cargoInicial){ if (this.cargoInicial) {
this.entidadId = this.entidadSeleccionada._id; this.entidadId = this.entidadSeleccionada._id;
this.entidadService.tiposCargo(this.entidadId) this.entidadService.tiposCargo(this.entidadId)
.then(tiposCargos=>{ .then(tiposCargos=> {
this.tiposCargo = tiposCargos; this.tiposCargo = tiposCargos;
this.tipoCargoSeleccionada = this.tiposCargo.rows.find(x=>x._id === this.cargoInicial.fk_tipo_cargo); this.tipoCargoSeleccionada = this.tiposCargo.rows.find(x=>x._id === this.cargoInicial.fk_tipo_cargo);
}) })
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
method: 'GET', method: 'GET',
url: appConfig.serverAddress + '/api/entidades/:id/convocatorias' url: appConfig.serverAddress + '/api/entidades/:id/convocatorias'
}, },
cargosDisponibles: { cargosDisponibles: {
isArray: false, isArray: false,
method: 'GET', method: 'GET',
...@@ -34,6 +35,11 @@ ...@@ -34,6 +35,11 @@
tiposCargo: { tiposCargo: {
method: 'GET', method: 'GET',
url: appConfig.serverAddress + '/api/entidades/:id/tiposCargo' url: appConfig.serverAddress + '/api/entidades/:id/tiposCargo'
},
ordenarUnidades: {
method: 'PUT',
isArray: true,
url: appConfig.serverAddress + '/api/entidades/:id/ordenarUnidades'
} }
}) })
} }
...@@ -48,7 +54,7 @@ ...@@ -48,7 +54,7 @@
return this.resource.get(parametros).$promise; return this.resource.get(parametros).$promise;
} }
getOrganigrama(id) { organigrama(id) {
return this.resource.organigrama({id: id}).$promise; return this.resource.organigrama({id: id}).$promise;
} }
...@@ -82,6 +88,10 @@ ...@@ -82,6 +88,10 @@
return this.resource.tiposCargo({id: id}).$promise; return this.resource.tiposCargo({id: id}).$promise;
} }
ordenarUnidades(id, parametros) {
return this.resource.ordenarUnidades({id: id}, parametros).$promise;
}
} }
angular.module('moduloPersonalApp') angular.module('moduloPersonalApp')
......
'use strict';
(()=> {
class EntidadEditarModalController {
constructor($uibModalInstance, parametros, EntidadService, tipoEntidadService) {
this.enviado = false;
this.errores = {};
this.modal = $uibModalInstance;
this.service = EntidadService;
this.entidad = parametros.entidad;
this.entidades = Object.assign({}, this.entidad);
this.entidadesSuperior = {};
tipoEntidadService.getTiposEntidad({ordenarPor: 'nombre'})
.then(tipoEntidad=> {
this.tiposEntidad = tipoEntidad;
this.tipoEntidadSeleccionado = this.tiposEntidad.rows.find(x=>x._id == this.entidad.fk_tipo_entidad);
});
EntidadService.getEntidades()
.then(entidad=> {
this.entidadesSuperior = entidad;
this.entidadesSuperiorSeleccionado = this.entidadesSuperior.rows.find(x=>x._id == this.entidad.fk_entidad_superior);
});
}
guardarEntidad(form) {
this.enviado = true;
if (form.$valid) {
this.entidades.fk_tipo_entidad = this.tipoEntidadSeleccionado._id;
if (this.entidadesSuperiorSeleccionado) {
this.entidades.fk_entidad_superior = this.entidadesSuperiorSeleccionado._id;
}
this.service.editarEntidad(this.entidad._id, this.entidades)
.then(entidad=> {
this.modal.close(entidad);
})
.catch(err=> {
this.errores.otros = err.data.message;
})
}
}
}
angular.module('moduloPersonalApp')
.controller('EntidadEditarModalCtrl', EntidadEditarModalController);
})();
...@@ -4,72 +4,1474 @@ ...@@ -4,72 +4,1474 @@
'use strict'; 'use strict';
(()=> { (()=> {
class EntidadOrganigramaController {
constructor(EntidadService, $stateParams) { //region Angular-Treant
this.service = EntidadService; class Treant {
this.id = $stateParams.entidadId; static JSONconfig = {
EntidadService.getOrganigrama(this.id).then(arbol => { make: function (configArray) {
this.arbol = arbol;
$('#chart').orgchart({ var i = configArray.length, node;
'data': this.arbol,
'nodeTitle': 'name', this.jsonStructure = {
'nodeContent': 'title', chart: null,
'draggable': true, nodeStructure: null
'createNode': function ($node, data) { };
switch (data.tipo) { //fist loop: find config, find root;
case 'oficina': while (i--) {
$node.addClass('success'); node = configArray[i];
break; if (node.hasOwnProperty('container')) {
case 'unidadOrganizacional': this.jsonStructure.chart = node;
$node.addClass('success'); continue;
break; }
case 'cargo':
$node.addClass('info'); if (!node.hasOwnProperty('parent') && !node.hasOwnProperty('container')) {
break; this.jsonStructure.nodeStructure = node;
case 'entidad': node.myID = this.getID();
$node.addClass('primary'); }
break; }
case 'tipoCargo':
$node.addClass('small'); this.findChildren(configArray);
$node.addClass('primary');
break; return this.jsonStructure;
default: },
break;
findChildren: function (nodes) {
var parents = [0]; // start witha a root node
while (parents.length) {
var parentId = parents.pop(),
parent = this.findNode(this.jsonStructure.nodeStructure, parentId),
i = 0, len = nodes.length,
children = [];
for (; i < len; i++) {
var node = nodes[i];
if (node.parent && (node.parent.myID == parentId)) { // skip config and root nodes
node.myID = this.getID();
delete node.parent;
children.push(node);
parents.push(node.myID);
} }
} }
});
this.arbolFormateado = this.formatearArbol(this.arbol); if (children.length) {
this.arbolFormateado.collapsed = true; parent.children = children;
this.chart_config = { }
chart: { }
container: "#collapsable-example", },
animateOnInit: true, findNode: function (node, nodeId) {
node: { var childrenLen, found;
collapsable: true,
HTMLclass: 'nodeExample1' if (node.myID === nodeId) {
}, return node;
connectors: { } else if (node.children) {
type: 'curve' childrenLen = node.children.length;
}, while (childrenLen--) {
nodeAlign:'BOTTOM', found = this.findNode(node.children[childrenLen], nodeId);
animation: { if (found) {
nodeAnimation: "easeOutQuart", return found;
nodeSpeed: 700,
connectorsAnimation: "easeOutQuart",
connectorsSpeed: 300
} }
}, }
nodeStructure: this.arbolFormateado }
},
getID: (function () {
var i = 0;
return function () {
return i++;
}; };
var chart = new Treant(this.chart_config); })()
};
constructor(jsonConfig, callback) {
if (jsonConfig instanceof Array) {
jsonConfig = Treant.JSONconfig.make(jsonConfig);
}
var newTree = TreeStore.createTree(jsonConfig);
newTree.positionTree(callback);
this.tree_id = newTree.id;
}
static destroy(tree_id) {
TreeStore.destroy(tree_id);
};
}
class ImageLoader {
constructor() {
this.loading = [];
}
processNode(node) {
var images = node.nodeDOM.getElementsByTagName('img'),
i = images.length;
while (i--) {
this.create(node, images[i]);
}
}
removeAll(img_src) {
var i = this.loading.length;
while (i--) {
if (this.loading[i] === img_src) {
this.loading.splice(i, 1);
}
}
}
create(node, image) {
var self = this,
source = image.src;
this.loading.push(source);
function imgTrigger() {
self.removeAll(source);
node.width = node.nodeDOM.offsetWidth;
node.height = node.nodeDOM.offsetHeight;
}
if (image.complete) {
return imgTrigger();
}
UTIL.addEvent(image, 'load', imgTrigger);
UTIL.addEvent(image, 'error', imgTrigger); // handle broken url-s
// load event is not fired for cached images, force the load event
image.src += "?" + new Date().getTime();
}
isNotLoading() {
return this.loading.length === 0;
}
}
class NodeDB {
constructor(nodeStructure, tree) {
this.db = [];
var self = this;
function itterateChildren(node, parentId) {
var newNode = self.createNode(node, parentId, tree, null);
if (node.children) {
newNode.children = [];
// pseudo node is used for descending children to the next level
if (node.childrenDropLevel && node.childrenDropLevel > 0) {
while (node.childrenDropLevel--) {
// pseudo node needs to inherit the connection style from its parent for continuous connectors
var connStyle = UTIL.cloneObj(newNode.connStyle);
newNode = self.createNode('pseudo', newNode.id, tree, null);
newNode.connStyle = connStyle;
newNode.children = [];
}
}
var stack = (node.stackChildren && !self.hasGrandChildren(node)) ? newNode.id : null;
// svildren are position on separate leves, one beneeth the other
if (stack !== null) {
newNode.stackChildren = [];
}
for (var i = 0, len = node.children.length; i < len; i++) {
if (stack !== null) {
newNode = self.createNode(node.children[i], newNode.id, tree, stack);
if ((i + 1) < len) newNode.children = []; // last node cant have children
} else {
itterateChildren(node.children[i], newNode.id);
}
}
}
}
if (tree.CONFIG.animateOnInit) nodeStructure.collapsed = true;
itterateChildren(nodeStructure, -1); // root node
this.createGeometries(tree);
}
createGeometries(tree) {
var i = this.db.length, node;
while (i--) {
this.get(i).createGeometry(tree);
}
}
get(nodeId) {
return this.db[nodeId]; // get node by ID
}
createNode(nodeStructure, parentId, tree, stackParentId) {
var node = new TreeNode(nodeStructure, this.db.length, parentId, tree, stackParentId);
this.db.push(node);
if (parentId >= 0) this.get(parentId).children.push(node.id); //skip root node
if (stackParentId) {
this.get(stackParentId).stackParent = true;
this.get(stackParentId).stackChildren.push(node.id);
}
return node;
}
getMinMaxCoord(dim, parent, MinMax) { // used for getting the dimensions of the tree, dim = 'X' || 'Y'
// looks for min and max (X and Y) within the set of nodes
var parent = parent || this.get(0),
i = parent.childrenCount(),
MinMax = MinMax || { // start with root node dimensions
min: parent[dim],
max: parent[dim] + ((dim == 'X') ? parent.width : parent.height)
};
while (i--) {
var node = parent.childAt(i),
maxTest = node[dim] + ((dim == 'X') ? node.width : node.height),
minTest = node[dim];
if (maxTest > MinMax.max) {
MinMax.max = maxTest;
}
if (minTest < MinMax.min) {
MinMax.min = minTest;
}
this.getMinMaxCoord(dim, node, MinMax);
}
return MinMax;
}
static hasGrandChildren(nodeStructure) {
var i = nodeStructure.children.length;
while (i--) {
if (nodeStructure.children[i].children) return true;
}
}
}
class Tree {
static CONFIG = {
maxDepth: 100,
rootOrientation: 'NORTH', // NORTH || EAST || WEST || SOUTH
nodeAlign: 'CENTER', // CENTER || TOP || BOTTOM
levelSeparation: 30,
siblingSeparation: 30,
subTeeSeparation: 30,
hideRootNode: false,
animateOnInit: false,
animateOnInitDelay: 500,
padding: 15, // the difference is seen only when the scrollbar is shown
scrollbar: 'native', // "native" || "fancy" || "None" (PS: "fancy" requires jquery and perfect-scrollbar)
connectors: {
type: 'curve', // 'curve' || 'step' || 'straight' || 'bCurve'
style: {
stroke: 'black'
},
stackIndent: 15
},
node: { // each node inherits this, it can all be overrifen in node config
// HTMLclass: 'node',
// drawLineThrough: false,
// collapsable: false,
link: {
target: '_self'
}
},
animation: { // each node inherits this, it can all be overrifen in node config
nodeSpeed: 450,
nodeAnimation: 'linear',
connectorsSpeed: 450,
connectorsAnimation: 'linear'
}
};
constructor(jsonConfig, treeId) {
this.id = treeId;
this.imageLoader = new ImageLoader();
this.CONFIG = UTIL.createMerge(Tree.CONFIG, jsonConfig.chart);
this.drawArea = document.getElementById(this.CONFIG.container.substring(1));
this.drawArea.className += " Treant";
this.nodeDB = new NodeDB(jsonConfig.nodeStructure, this);
// key store for storing reference to node connectors,
// key = nodeId where the connector ends
this.connectionStore = {};
}
positionTree(callback) {
var self = this;
if (this.imageLoader.isNotLoading()) {
var root = this.root(),
orient = this.CONFIG.rootOrientation;
this.resetLevelData();
this.firstWalk(root, 0);
this.secondWalk(root, 0, 0, 0);
this.positionNodes();
if (this.CONFIG.animateOnInit) {
setTimeout(function () {
root.toggleCollapse();
}, this.CONFIG.animateOnInitDelay);
}
if (!this.loaded) {
this.drawArea.className += " Treant-loaded"; // nodes are hidden until .loaded class is add
if (Object.prototype.toString.call(callback) === "[object Function]") {
callback(self);
}
this.loaded = true;
}
} else {
setTimeout(function () {
self.positionTree(callback);
}, 10);
}