150 lines
3.8 KiB
JavaScript
150 lines
3.8 KiB
JavaScript
import ngModule from '../../module';
|
|
import Component from '../../lib/component';
|
|
import './style.scss';
|
|
|
|
/**
|
|
* A simple tooltip.
|
|
*
|
|
* @property {String} position The relative position to the parent
|
|
*/
|
|
export default class Treeview extends Component {
|
|
constructor($element, $scope) {
|
|
super($element, $scope);
|
|
this.data = [];
|
|
}
|
|
|
|
$onInit() {
|
|
this.refresh();
|
|
}
|
|
|
|
refresh() {
|
|
this.model.refresh().then(() => {
|
|
this.data = this.model.data;
|
|
this.repaintAll();
|
|
});
|
|
}
|
|
|
|
repaintAll() {
|
|
let oldData = this.data;
|
|
oldData.forEach(node => {
|
|
this.repaintAsc(node);
|
|
this.repaintDesc(node);
|
|
});
|
|
}
|
|
|
|
repaintNode(node) {
|
|
this.repaintAsc(node);
|
|
this.repaintDesc(node);
|
|
}
|
|
|
|
repaintAsc(node) {
|
|
if (!node.parent) return;
|
|
|
|
const parent = node.parent;
|
|
if ((node.selected || node.included) && !parent.selected) {
|
|
parent.included = true;
|
|
parent.hasCheckedChilds = true;
|
|
} else if (!this.hasCheckedChilds(parent) && !this.hasCheckedParents(node))
|
|
parent.included = false;
|
|
|
|
// FIXME - Propagate hasCheckedCHilds
|
|
if (!node.selected && this.hasCheckedParents(node)) {
|
|
node.included = true;
|
|
parent.hasCheckedChilds = false;
|
|
}
|
|
|
|
if (!this.hasCheckedChilds(node))
|
|
node.hasCheckedChilds = false;
|
|
|
|
this.repaintAsc(parent);
|
|
}
|
|
|
|
repaintDesc(node) {
|
|
/* if (node.hasCheckedChilds)
|
|
node.included = false; */
|
|
|
|
if (!node.selected && this.hasCheckedChilds(node)) {
|
|
node.hasCheckedChilds = true;
|
|
node.included = true;
|
|
} else if (!node.selected && node.childs && !this.hasCheckedChilds(node))
|
|
node.hasCheckedChilds = false;
|
|
|
|
|
|
const childs = node.childs || [];
|
|
for (let i = 0; i < childs.length; i++) {
|
|
childs[i].included = false;
|
|
|
|
if ((node.selected || node.included && this.hasCheckedParents(childs[i])) && !childs[i].selected)
|
|
childs[i].included = true;
|
|
|
|
this.repaintDesc(childs[i]);
|
|
}
|
|
|
|
if (!node.selected && node.hasCheckedChilds)
|
|
node.included = true;
|
|
}
|
|
|
|
hasCheckedChilds(node) {
|
|
if (!node.childs) return false;
|
|
|
|
const childs = node.childs;
|
|
for (let i = 0; i < childs.length; i++) {
|
|
if (childs[i].selected || this.hasCheckedChilds(childs[i]))
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
hasCheckedParents(node) {
|
|
if (!node.parent) return false;
|
|
|
|
const parent = node.parent;
|
|
if (parent.selected || this.hasCheckedParents(parent))
|
|
return true;
|
|
|
|
return false;
|
|
}
|
|
|
|
onSelection(item) {
|
|
item.selected = !item.selected;
|
|
|
|
if (item.selected && item.included)
|
|
item.included = false;
|
|
|
|
if (this.hasCheckedChilds(item))
|
|
item.hasCheckedChilds = true;
|
|
else if (this.childs)
|
|
item.hasCheckedChilds = false;
|
|
|
|
this.emit('selection', {item});
|
|
}
|
|
|
|
onToggle(item) {
|
|
if (item.childs && item.childs.length == 0)
|
|
return;
|
|
|
|
if (item.childs)
|
|
item.childs = undefined;
|
|
else {
|
|
this.model.applyFilter({}, {parentFk: item.id}).then(() => {
|
|
item.childs = this.model.data;
|
|
item.childs.forEach(child => {
|
|
child.parent = item;
|
|
});
|
|
this.repaintNode(item);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
Treeview.$inject = ['$element', '$scope'];
|
|
|
|
ngModule.component('vnTreeview', {
|
|
template: require('./index.html'),
|
|
controller: Treeview,
|
|
bindings: {
|
|
model: '<'
|
|
}
|
|
});
|