add & remove childs
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
6a184496d6
commit
9919f9a46e
|
@ -25,11 +25,11 @@
|
||||||
label="{{::item.name}}">
|
label="{{::item.name}}">
|
||||||
</vn-check>
|
</vn-check>
|
||||||
-->
|
-->
|
||||||
<vn-icon-button
|
<vn-icon-button title="Create"
|
||||||
icon="add_circle"
|
icon="add_circle"
|
||||||
ng-click="$ctrl.treeview.onAdd(item, item.childs)">
|
ng-click="$ctrl.treeview.onCreate(item, item.childs)">
|
||||||
</vn-icon-button>
|
</vn-icon-button>
|
||||||
<vn-icon-button
|
<vn-icon-button title="Remove"
|
||||||
icon="delete"
|
icon="delete"
|
||||||
ng-click="$ctrl.treeview.onRemove(item, $ctrl.items, $ctrl.parent)">
|
ng-click="$ctrl.treeview.onRemove(item, $ctrl.items, $ctrl.parent)">
|
||||||
</vn-icon-button>
|
</vn-icon-button>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<section class="add-item" ng-click="$ctrl.onAdd(null, $ctrl.items)" >
|
<section class="add-item" ng-click="$ctrl.onCreate(null, $ctrl.items)" >
|
||||||
<vn-icon-button
|
<vn-icon-button
|
||||||
icon="add_circle">
|
icon="add_circle">
|
||||||
</vn-icon-button>
|
</vn-icon-button>
|
||||||
|
|
|
@ -27,24 +27,20 @@ export default class Treeview extends Component {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Emits selection event
|
|
||||||
* @param {Object} item - Selected item
|
|
||||||
* @param {Boolean} value - Changed value
|
|
||||||
*/
|
|
||||||
onSelection(item, value) {
|
|
||||||
this.emit('selection', {item, value});
|
|
||||||
}
|
|
||||||
|
|
||||||
onCreate(parent) {
|
|
||||||
this.emit('create', {parent});
|
|
||||||
}
|
|
||||||
|
|
||||||
onToggle(item) {
|
onToggle(item) {
|
||||||
if (item.active)
|
if (item.active)
|
||||||
|
this.fold(item);
|
||||||
|
else
|
||||||
|
this.unfold(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
fold(item) {
|
||||||
item.childs = undefined;
|
item.childs = undefined;
|
||||||
else {
|
item.active = false;
|
||||||
this.model.applyFilter({}, {parentFk: item.id}).then(() => {
|
}
|
||||||
|
|
||||||
|
unfold(item) {
|
||||||
|
return this.model.applyFilter({}, {parentFk: item.id}).then(() => {
|
||||||
const newData = this.model.data;
|
const newData = this.model.data;
|
||||||
|
|
||||||
if (item.childs) {
|
if (item.childs) {
|
||||||
|
@ -68,10 +64,7 @@ export default class Treeview extends Component {
|
||||||
|
|
||||||
return a.name.localeCompare(b.name);
|
return a.name.localeCompare(b.name);
|
||||||
});
|
});
|
||||||
});
|
}).then(() => item.active = true);
|
||||||
}
|
|
||||||
|
|
||||||
item.active = !item.active;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onDrop(item, dragged, dropped) {
|
onDrop(item, dragged, dropped) {
|
||||||
|
@ -80,7 +73,7 @@ export default class Treeview extends Component {
|
||||||
|
|
||||||
onRemove(item, items, parent) {
|
onRemove(item, items, parent) {
|
||||||
if (!this.removeFunc) return;
|
if (!this.removeFunc) return;
|
||||||
let res = this.removeFunc({$item: item});
|
let res = this.removeFunc({$item: item, $parent: parent});
|
||||||
|
|
||||||
function remove() {
|
function remove() {
|
||||||
let index = items.indexOf(item);
|
let index = items.indexOf(item);
|
||||||
|
@ -94,25 +87,50 @@ export default class Treeview extends Component {
|
||||||
remove();
|
remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
onAdd(parent, childs) {
|
onCreate(parent, childs) {
|
||||||
if (!this.addFunc) return;
|
if (!this.createFunc) return;
|
||||||
let res = this.addFunc({$parent: parent});
|
let res = this.createFunc({$parent: parent, $childs: childs});
|
||||||
|
|
||||||
function add() {
|
function create() {
|
||||||
if (!childs) childs = [];
|
if (!childs) childs = [];
|
||||||
childs.push(res);
|
childs.push(res);
|
||||||
if (parent) {
|
if (parent) parent.sons++;
|
||||||
parent.childs = childs;
|
|
||||||
parent.sons++;
|
|
||||||
parent.active = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res instanceof Object && res.then)
|
if (res instanceof Object && res.then) {
|
||||||
res.then(add);
|
if (parent && !parent.active)
|
||||||
else if (res)
|
this.unfold(parent).then(() => res.then(create));
|
||||||
add();
|
else res.then(create);
|
||||||
|
} else if (res) {
|
||||||
|
if (parent && !parent.active)
|
||||||
|
this.unfold(parent).then(() => create());
|
||||||
|
else create();
|
||||||
|
} else if (parent && !parent.active)
|
||||||
|
this.unfold(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* onCreate(parent, childs) {
|
||||||
|
if (!this.createFunc) return;
|
||||||
|
let res = this.createFunc({$parent: parent});
|
||||||
|
|
||||||
|
function create() {
|
||||||
|
if (!childs) childs = [];
|
||||||
|
|
||||||
|
childs.push(res);
|
||||||
|
|
||||||
|
if (parent) parent.sons++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (res instanceof Object && res.then) {
|
||||||
|
if (!parent.active)
|
||||||
|
this.unfold(parent).then(() => res.then(create));
|
||||||
|
else res.then(create);
|
||||||
|
} else if (res) {
|
||||||
|
if (!parent.active)
|
||||||
|
this.unfold(parent).then(() => create());
|
||||||
|
else create();
|
||||||
|
}
|
||||||
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
Treeview.$inject = ['$element', '$scope', '$transclude'];
|
Treeview.$inject = ['$element', '$scope', '$transclude'];
|
||||||
|
@ -130,7 +148,7 @@ ngModule.component('vnTreeview', {
|
||||||
droppable: '<?',
|
droppable: '<?',
|
||||||
aclRole: '@?',
|
aclRole: '@?',
|
||||||
removeFunc: '&?',
|
removeFunc: '&?',
|
||||||
addFunc: '&?'
|
createFunc: '&?'
|
||||||
},
|
},
|
||||||
transclude: true
|
transclude: true
|
||||||
});
|
});
|
||||||
|
|
|
@ -107,5 +107,6 @@
|
||||||
"Invalid quantity": "Cantidad invalida",
|
"Invalid quantity": "Cantidad invalida",
|
||||||
"This postal code is not valid": "This postal code is not valid",
|
"This postal code is not valid": "This postal code is not valid",
|
||||||
"is invalid": "is invalid",
|
"is invalid": "is invalid",
|
||||||
"The postcode doesn't exists. Ensure you put the correct format": "El código postal no existe. Asegúrate de ponerlo con el formato correcto"
|
"The postcode doesn't exists. Ensure you put the correct format": "El código postal no existe. Asegúrate de ponerlo con el formato correcto",
|
||||||
|
"The department name can't be repeated": "The department name can't be repeated"
|
||||||
}
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('createChild', {
|
||||||
|
description: 'Creates a new child department',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'parentId',
|
||||||
|
type: 'Number'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'name',
|
||||||
|
type: 'String',
|
||||||
|
required: true,
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: 'object',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/createChild`,
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.createChild = async(parentId = null, name) => {
|
||||||
|
const models = Self.app.models;
|
||||||
|
const nameExists = await models.Department.count({name});
|
||||||
|
|
||||||
|
if (nameExists)
|
||||||
|
throw new UserError(`The department name can't be repeated`);
|
||||||
|
|
||||||
|
const newDep = await models.Department.create({
|
||||||
|
parentFk: parentId,
|
||||||
|
name: name
|
||||||
|
});
|
||||||
|
|
||||||
|
return newDep;
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,43 +0,0 @@
|
||||||
|
|
||||||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
|
||||||
|
|
||||||
module.exports = Self => {
|
|
||||||
Self.remoteMethod('nodeAdd', {
|
|
||||||
description: 'Returns the first shipped and landed possible for params',
|
|
||||||
accessType: 'WRITE',
|
|
||||||
accepts: [{
|
|
||||||
arg: 'parentFk',
|
|
||||||
type: 'Number',
|
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
arg: 'name',
|
|
||||||
type: 'String',
|
|
||||||
required: true,
|
|
||||||
}],
|
|
||||||
returns: {
|
|
||||||
type: 'object',
|
|
||||||
root: true
|
|
||||||
},
|
|
||||||
http: {
|
|
||||||
path: `/nodeAdd`,
|
|
||||||
verb: 'POST'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Self.nodeAdd = async(parentFk = 1, name) => {
|
|
||||||
let stmts = [];
|
|
||||||
let conn = Self.dataSource.connector;
|
|
||||||
let nodeIndex = stmts.push(new ParameterizedSQL(
|
|
||||||
`CALL nst.nodeAdd('vn', 'department', ?, ?)`, [parentFk, name])) - 1;
|
|
||||||
|
|
||||||
stmts.push(`CALL nst.nodeRecalc('vn', 'department')`);
|
|
||||||
|
|
||||||
|
|
||||||
let sql = ParameterizedSQL.join(stmts, ';');
|
|
||||||
let result = await conn.executeStmt(sql);
|
|
||||||
let [node] = result[nodeIndex];
|
|
||||||
|
|
||||||
return node;
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -1,29 +0,0 @@
|
||||||
|
|
||||||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
|
||||||
|
|
||||||
module.exports = Self => {
|
|
||||||
Self.remoteMethod('nodeDelete', {
|
|
||||||
description: 'Returns the first shipped and landed possible for params',
|
|
||||||
accessType: 'WRITE',
|
|
||||||
accepts: [{
|
|
||||||
arg: 'parentFk',
|
|
||||||
type: 'Number',
|
|
||||||
required: false,
|
|
||||||
}],
|
|
||||||
returns: {
|
|
||||||
type: ['object'],
|
|
||||||
root: true
|
|
||||||
},
|
|
||||||
http: {
|
|
||||||
path: `/nodeDelete`,
|
|
||||||
verb: 'POST'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Self.nodeDelete = async parentFk => {
|
|
||||||
let stmt = new ParameterizedSQL(
|
|
||||||
`CALL nst.nodeDelete('vn', 'department', ?)`, [parentFk]);
|
|
||||||
|
|
||||||
return await Self.rawStmt(stmt);
|
|
||||||
};
|
|
||||||
};
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('removeChild', {
|
||||||
|
description: 'Returns the first shipped and landed possible for params',
|
||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'id',
|
||||||
|
type: 'Number',
|
||||||
|
description: 'The department id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: 'Object',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/:id/removeChild`,
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.removeChild = async id => {
|
||||||
|
const models = Self.app.models;
|
||||||
|
const department = await models.Department.findById(id);
|
||||||
|
|
||||||
|
return await department.destroy();
|
||||||
|
};
|
||||||
|
};
|
|
@ -1,15 +1,5 @@
|
||||||
const UserError = require('vn-loopback/util/user-error');
|
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
require('../methods/department/getLeaves')(Self);
|
require('../methods/department/getLeaves')(Self);
|
||||||
require('../methods/department/nodeAdd')(Self);
|
require('../methods/department/createChild')(Self);
|
||||||
require('../methods/department/nodeDelete')(Self);
|
require('../methods/department/removeChild')(Self);
|
||||||
|
|
||||||
Self.rewriteDbError(function(err) {
|
|
||||||
if (err.code === 'ER_ROW_IS_REFERENCED_2')
|
|
||||||
return new UserError(`You cannot remove this department`);
|
|
||||||
if (err.code === 'ER_DUP_ENTRY')
|
|
||||||
return new UserError(`The department name can't be repeated`);
|
|
||||||
return err;
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,6 +13,9 @@
|
||||||
},
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "String"
|
"type": "String"
|
||||||
|
},
|
||||||
|
"parentFk": {
|
||||||
|
"type": "Number"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,12 +6,9 @@
|
||||||
<div class="content-block" compact>
|
<div class="content-block" compact>
|
||||||
<form name="form" compact>
|
<form name="form" compact>
|
||||||
<vn-card margin-medium-v pad-medium>
|
<vn-card margin-medium-v pad-medium>
|
||||||
<vn-treeview
|
<vn-treeview vn-id="treeview" model="model"
|
||||||
vn-id="treeview"
|
remove-func="$ctrl.onRemove($item)"
|
||||||
model="model"
|
create-func="$ctrl.onCreate($parent, $childs)">
|
||||||
on-selection="$ctrl.onSelection(item, value)"
|
|
||||||
remove-func="true"
|
|
||||||
add-func="{name: 'Dept1'}">
|
|
||||||
{{::item.name}}
|
{{::item.name}}
|
||||||
</vn-treeview>
|
</vn-treeview>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
|
@ -37,7 +34,7 @@
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-textfield vn-one
|
<vn-textfield vn-one
|
||||||
label="Name"
|
label="Name"
|
||||||
model="$ctrl.newNode.name">
|
model="$ctrl.newChild.name">
|
||||||
</vn-textfield>
|
</vn-textfield>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
</tpl-body>
|
</tpl-body>
|
||||||
|
|
|
@ -6,23 +6,6 @@ class Controller {
|
||||||
this.$http = $http;
|
this.$http = $http;
|
||||||
this.vnApp = vnApp;
|
this.vnApp = vnApp;
|
||||||
this.$translate = $translate;
|
this.$translate = $translate;
|
||||||
this.icons = [{icon: 'delete', tooltip: 'Delete', callback: this.onDelete}];
|
|
||||||
this.newNode = {
|
|
||||||
name: ''
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
onCreate(parent) {
|
|
||||||
if (parent instanceof Object)
|
|
||||||
this.newNode.parentFk = parent.id;
|
|
||||||
|
|
||||||
this.selectedNode = {parent};
|
|
||||||
this.$scope.createNode.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
onDelete(item, parent, index) {
|
|
||||||
this.selectedNode = {id: item.id, parent, index};
|
|
||||||
this.$scope.deleteNode.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onDrop(item, dragged, dropped) {
|
onDrop(item, dragged, dropped) {
|
||||||
|
@ -39,25 +22,37 @@ class Controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onCreate(parent, childs) {
|
||||||
|
this.newChild = {
|
||||||
|
parent: parent,
|
||||||
|
childs: childs,
|
||||||
|
name: ''
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$scope.createNode.show();
|
||||||
|
}
|
||||||
|
|
||||||
onCreateDialogOpen() {
|
onCreateDialogOpen() {
|
||||||
this.newNode.name = '';
|
this.newChild.name = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
onCreateResponse(response) {
|
onCreateResponse(response) {
|
||||||
if (response == 'ACCEPT') {
|
if (response == 'ACCEPT') {
|
||||||
try {
|
try {
|
||||||
if (!this.newNode.name)
|
if (!this.newChild.name)
|
||||||
throw new Error(`Name can't be empty`);
|
throw new Error(`Name can't be empty`);
|
||||||
|
|
||||||
this.$http.post(`/worker/api/Departments/nodeAdd`, this.newNode).then(response => {
|
const params = {name: this.newChild.name};
|
||||||
if (response.data) {
|
const parent = this.newChild.parent;
|
||||||
let parent = this.selectedNode.parent;
|
const parentId = parent && parent.id || null;
|
||||||
if ((parent instanceof Object) && !(parent instanceof Array)) {
|
let childs = this.newChild.childs;
|
||||||
const childs = parent.childs;
|
|
||||||
|
if (parent) params.parentId = parentId;
|
||||||
|
|
||||||
|
const query = `/api/departments/createChild`;
|
||||||
|
this.$http.post(query, params).then(response => {
|
||||||
|
if (!childs) childs = [];
|
||||||
childs.push(response.data);
|
childs.push(response.data);
|
||||||
} else if ((parent instanceof Object) && (parent instanceof Array))
|
|
||||||
parent.push(response.data);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
this.vnApp.showError(this.$translate.instant(e.message));
|
this.vnApp.showError(this.$translate.instant(e.message));
|
||||||
|
@ -67,17 +62,24 @@ class Controller {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onRemove(item) {
|
||||||
|
this.removedChild = item;
|
||||||
|
this.$scope.deleteNode.show();
|
||||||
|
}
|
||||||
|
|
||||||
onRemoveResponse(response) {
|
onRemoveResponse(response) {
|
||||||
if (response === 'ACCEPT') {
|
if (response === 'ACCEPT') {
|
||||||
const path = `/worker/api/Departments/nodeDelete`;
|
const childId = this.removedChild.id;
|
||||||
this.$http.post(path, {parentFk: this.selectedNode.id}).then(() => {
|
const path = `/api/departments/${childId}/removeChild`;
|
||||||
let parent = this.selectedNode.parent;
|
this.$http.post(path).then(() => {
|
||||||
|
items.splice(index, 1);
|
||||||
|
/* let parent = this.selectedNode.parent;
|
||||||
|
|
||||||
if ((parent instanceof Object) && !(parent instanceof Array)) {
|
if ((parent instanceof Object) && !(parent instanceof Array)) {
|
||||||
const childs = parent.childs;
|
const childs = parent.childs;
|
||||||
childs.splice(this.selectedNode.index, 1);
|
childs.splice(this.selectedNode.index, 1);
|
||||||
} else if ((parent instanceof Object) && (parent instanceof Array))
|
} else if ((parent instanceof Object) && (parent instanceof Array))
|
||||||
parent.splice(this.selectedNode.index, 1);
|
parent.splice(this.selectedNode.index, 1); */
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue