Commit bc63423e by Sebastián Collado

Merge branch 'issue588' of http://scm.ujaen.es/softuno/pictogram into issue588

parents b4cc7b86 59bc9458
/* global Instruction, Method */
/**
* MetaInstructionController manages the requests related to the MetaInstruction model.
* Read it's documentation for further information.
* @type {Object}
*/
module.exports = {
/**
* Create a new Instruction, which is associated to the given method
* @param {request} req
* {
* method: metaMethodId,
* name: 'New instruction' (optional)
* objective: 'This instruction has an objective... description' (optional)
* }
* @param {response} res
* {
* id (instructionId)
* method
* name
* objective
* }
*/
create: function (req, res) {
MetaMethod.findOne({ id: req.param('method') }).then(function (method) {
if (!method)
return res.badRequest();
MetaInstruction.create({
id_met: method.id,
name: req.param('name'),
objective: req.param('objective'),
})
.then(function (instruction) {
if (instruction)
return res.ok(instruction);
return res.badRequest();
})
.catch(function (err) {
return res.serverError(err);
});
})
.catch(function (err) {
return res.serverError(err);
});
},
/**
* Update an existing Instruction template, known by it's ID
* @param {request} req (with instruction id as url parameter)
* {
* method: methodId, (optional)
* name: 'New instruction' (optional)
* objective: 'This instruction has an objective... description' (optional)
* }
* @param {response} res
* {
* id
* method
* name
* objective
* }
*/
update: function (req, res) {
if (!req.params.id)
return res.badRequest();
MetaInstruction.findOne({ id: req.params.id })
.then(function (instruction) {
if (!instruction)
return res.badRequest();
instruction.method = req.param('method') || instruction.method;
instruction.name = req.param('name') || instruction.name;
instruction.objective = req.param('objective') || instruction.objective;
instruction.save(function (error) {
if (error)
return res.serverError();
return res.ok(instruction);
});
})
.catch(function () {
return res.serverError();
});
},
/**
* Delete an instruction template by its ID
* @param {request} req {} (with instructionId as url parameter)
* @param {response} res {}
*/
destroy: function (req, res) {
if (!req.params.id)
return res.badRequest();
MetaInstruction.destroy({ id: req.params.id }).exec(function (error) {
if (error)
return res.badRequest();
else
return res.ok();
});
}
};
/* global sails, Method, MetaMethod */
/**
* MethodController
*
* @description :: Server-side logic for managing methods
* @help :: See http://links.sailsjs.org/docs/controllers
*/
module.exports = {
/**
* Return all the metamethods of a given supervisor (including the public metamethods)
* not associated to a concrete supervisor.
* @param {request} req {} (with idSup specified as url parameter)
* @param {response} res
* [
* {
* id: metamethodId
* name: 'Metamethod Name'
* description: 'Metamethod description, which can be longer'
* },
* ...
* ]
*/
supVisible: function (req, res) {
var params = req.allParams();
MetaMethod.find({ or: [
{ supervisor: null },
{ supervisor: params.id_sup }
] }).then(function (metaMethods) {
res.ok(metaMethods);
})
.catch(function (err) {
res.serverError(err);
});
},
/**
* Return all the metamethods of a given supervisor he owns
* @param {request} req {} (with idSup specified as url parameter)
* @param {response} res
* [
* {
* id: metamethodId
* name: 'Metamethod Name'
* description: 'Metamethod description, which can be longer'
* },
* ...
* ]
*/
supOwned: function (req, res) {
var params = req.allParams();
if (!params.id_sup)
return res.badRequest();
MetaMethod.find({ supervisor: params.id_sup })
.populate('metainstructions')
.then(function (metaMethods) {
res.ok(metaMethods);
})
.catch(function (err) {
res.serverError(err);
});
},
/**
* Creates a new method from scratch (without using a template)
* @param {request} req
* {
* id_stu: studentId,
* name: 'Method name'
* }
* @param {response} res
* {
* id: methodId,
* name: 'Method name'
* }
*/
create: function(req, res){
var params = req.allParams();
if (!params.id_sup)
return res.badRequest("No supervisor defined");
MetaMethod.create({
"name": params.name,
"description": "",
"supervisor": params.id_sup
})
.then(function(createdMethod){
return res.ok(createdMethod);
})
.catch(function(err) {
sails.log.debug("Create Method template error: " + err);
return res.serverError(err);
});
},
//
// Updates a method template (just method, no instructions)
//
update: function (req, res) {
var params = req.allParams();
if (!params.id)
return res.badRequest("No template id specified");
MetaMethod.findOne(params.id)
.then(function (method) {
if (!method)
return res.serverError("No template found");
method.name = params.name;
method.description = params.description;
delete method.metainstructions;
method.save(function (err) {
if (err)
return res.serverError(err);
return res.ok(method);
});
})
.catch(function (err) {
sails.log.debug("Error updating method" + err.msg);
return res.serverError("Error updating method");
});
},
//
// Deletes a meta methdo
//
destroy: function(req, res){
var params = req.allParams();
if (!params.id) {
return res.badRequest("No meta method defined");
}
// Destroy instructions
MetaInstruction.destroy({ id_met: params.id })
.then(function(metainstructions) {
MetaMethod.destroy({ id: params.id })
.then(function(metamethod) {
if (!metamethod){
sails.log.debug("Destroy MetaMethod: " + err);
return res.serverError("No meta method found");
}
return res.ok(metamethod);
})
.catch(function (err) {
return res.serverError(err);
});
})
.catch(function(err) {
return res.serverError(err);
});
}
};
...@@ -595,4 +595,5 @@ module.exports = { ...@@ -595,4 +595,5 @@ module.exports = {
res.badRequest(); res.badRequest();
} }
} }
}; };
...@@ -145,6 +145,9 @@ ...@@ -145,6 +145,9 @@
"month_totals": "Month totals", "month_totals": "Month totals",
"monthly":"Monthly", "monthly":"Monthly",
"name": "Name", "name": "Name",
"new_instruction": "New instruction",
"new_method": "New method",
"new_objective": "New objective",
"new_session": "New session", "new_session": "New session",
"next_actions": "Next actions", "next_actions": "Next actions",
"next_sessions": "Next sessions", "next_sessions": "Next sessions",
...@@ -171,6 +174,7 @@ ...@@ -171,6 +174,7 @@
"office_not_updated": "Office not updated", "office_not_updated": "Office not updated",
"office_updated": "Office updated", "office_updated": "Office updated",
"offices": "Offices", "offices": "Offices",
"own_instructions": "Own method templates",
"own_labels": "Your labels", "own_labels": "Your labels",
"own_pictos": "Your pictograms", "own_pictos": "Your pictograms",
"pages": "Pages", "pages": "Pages",
......
...@@ -145,6 +145,9 @@ ...@@ -145,6 +145,9 @@
"month_totals": "Totales mes", "month_totals": "Totales mes",
"monthly":"Mensual", "monthly":"Mensual",
"name": "Nombre", "name": "Nombre",
"new_instruction": "Nueva instrucción",
"new_method": "Nuevo método",
"new_objective": "Nuevo objetivo",
"new_session": "Nueva sesión", "new_session": "Nueva sesión",
"next_actions": "Acciones posteriores", "next_actions": "Acciones posteriores",
"next_sessions": "Sesiones posteriores", "next_sessions": "Sesiones posteriores",
...@@ -171,6 +174,7 @@ ...@@ -171,6 +174,7 @@
"office_not_updated": "El gabinete no se ha podido actualizar", "office_not_updated": "El gabinete no se ha podido actualizar",
"office_updated": "Gabinete actualizado", "office_updated": "Gabinete actualizado",
"offices": "Gabinetes", "offices": "Gabinetes",
"own_instructions": "Plantillas de métodos propias",
"own_labels": "Propias", "own_labels": "Propias",
"own_pictos": "Propios", "own_pictos": "Propios",
"pages": "Páginas", "pages": "Páginas",
......
...@@ -94,6 +94,12 @@ dashboardApp.config(function ($stateProvider, $urlRouterProvider) { ...@@ -94,6 +94,12 @@ dashboardApp.config(function ($stateProvider, $urlRouterProvider) {
templateUrl: 'modules/supervisor/views/setup.html', templateUrl: 'modules/supervisor/views/setup.html',
controller: 'SetupCtrl', controller: 'SetupCtrl',
}) })
.state('instructions', {
url: '/instructions',
parent: 'supervisor',
templateUrl: 'modules/supervisor/views/instructions.html',
controller: 'InstructionsCtrl',
})
// Abstract page for student // Abstract page for student
.state('student', { .state('student', {
templateUrl: 'modules/student/views/student.html', templateUrl: 'modules/student/views/student.html',
......
...@@ -22,14 +22,14 @@ dashboardControllers.controller('StudentInstructionsCtrl', function StudentInstr ...@@ -22,14 +22,14 @@ dashboardControllers.controller('StudentInstructionsCtrl', function StudentInstr
// Query to meta_methods to fill the select fill with precharged methods // Query to meta_methods to fill the select fill with precharged methods
// and supervisor template methods // and supervisor template methods
$http $http
.get(config.backend+'/metamethods/' + $scope.user.id) .get(config.backend+'/method/template/' + $scope.user.id)
.success(function(data, status, headers, config) { .success(function(data, status, headers, config) {
// Add to list // Add to list
$scope.methods_available = data; $scope.methods_available = data;
console.log("Meta Methods charged:"); console.log("Meta Methods charged:");
console.log(JSON.stringify($scope.methods_available)); console.log(JSON.stringify($scope.methods_available));
// Option to add new methods // Option to add new methods
$scope.methods_available.push({ id: 0, name: "Nuevo método" }); $scope.methods_available.push({ id: 0, name: $translate.instant('new_method') });
}) })
.error(function(data, status, headers, config) { .error(function(data, status, headers, config) {
console.log("Error from API: " + data.error); console.log("Error from API: " + data.error);
...@@ -99,7 +99,7 @@ dashboardControllers.controller('StudentInstructionsCtrl', function StudentInstr ...@@ -99,7 +99,7 @@ dashboardControllers.controller('StudentInstructionsCtrl', function StudentInstr
.success(function(data, status, headers, config) { .success(function(data, status, headers, config) {
console.log('Created Method and Instructions'); console.log('Created Method and Instructions');
console.log('Method (with Instructions):' + JSON.stringify(data)); console.log('Method (with Instructions):' + JSON.stringify(data));
$scope.methods.push(data); $scope.methods.unshift(data);
}) })
.error(function(data, status, headers, config) { .error(function(data, status, headers, config) {
console.log("Error from API: " + data.error); console.log("Error from API: " + data.error);
...@@ -217,7 +217,6 @@ dashboardControllers.controller('StudentInstructionsCtrl', function StudentInstr ...@@ -217,7 +217,6 @@ dashboardControllers.controller('StudentInstructionsCtrl', function StudentInstr
// Add instruction // Add instruction
$scope.add_instruction = function(method){ $scope.add_instruction = function(method){
$http $http
.post(config.backend+'/instruction', { method: method.id } ) .post(config.backend+'/instruction', { method: method.id } )
.success(function(data, status, headers, config) { .success(function(data, status, headers, config) {
......
'use strict';
//-----------------------
// Instructions Controller
//-----------------------
dashboardControllers.controller('InstructionsCtrl', function InstructionsCtrl($scope, $stateParams, $http, config, $window, $translate, $modal, ngToast, newconfirm) {
// ----------------------------------------------------------------------
// METHODS
// Load student methods and instructions
//
//
//
// Array with methods available in meta_methods
//
$scope.methods_available = [];
// Query to meta_methods to fill the select fill with precharged methods
// and supervisor template methods
$http
.get(config.backend+'/method/template/owned/' + $scope.user.id)
.success(function(data, status, headers, config) {
// Add to list
$scope.methods = data;
})
.error(function(data, status, headers, config) {
console.log("Error from API: " + data.error);
});
// -----------------------------------------------------------------------
// Functions
//
// Add new method template (metamethod) selected to the student
$scope.add_method = function(){
var new_data = {
name: $translate.instant("new_method"),
id_sup: $scope.user.id
};
$http
.post(config.backend+'/method/template', new_data)
.success(function(data, status, headers, config) {
data.metainstructions = [];
$scope.methods.unshift(data);
})
.error(function(data, status, headers, config) { //error
ngToast.warning($translate.instant("method_name_duplicated", {method_name: new_data.name}));
});
};
// Delete method template
$scope.delete_method = function(method){
newconfirm($translate.instant('confirmation'))
.then(function() {
$http
.delete(config.backend+'/method/template/' + method.id)
.success(function(data, status, headers, config) {
console.log('Delete Method Template and its Instructions');
ngToast.success($translate.instant('template_deleted'));
for(var i=0; i<$scope.methods.length; i++) {
if($scope.methods[i].id == method.id){
$scope.methods.splice(i,1);
break;
}
}
})
.error(function(data, status, headers, config) {
console.log("Error from API: " + data.error);
});
});
};
// Update method template
$scope.update_method = function(method){
// Remove instructions as we only update title or description
var method_to_save = {};
Object.assign(method_to_save, method);
delete method_to_save.metainstructions;
$http
.put(config.backend+'/method/template/' + method.id, method_to_save)
.success(function(data, status, headers, config) {
console.log('Updated method:' + JSON.stringify(data));
})
.error(function(data, status, headers, config) {
console.log("Error from API: " + JSON.stringify(data));
});
};
// Add instruction template
$scope.add_instruction = function(method){
var new_instruction = {
method: method.id,
name: $translate.instant("new_instruction"),
objective: $translate.instant("new_objective")
};
$http
.post(config.backend+'/instruction/template/', new_instruction)
.success(function(data, status, headers, config) {
console.log('Added instruction:' + JSON.stringify(data));
// Add in view
method.metainstructions.push(data);
})
.error(function(data, status, headers, config) {
console.log("Error from API: " + data.error);
});
};
// Update instruction template
$scope.update_instruction = function(ins){
$http
.put(config.backend+'/instruction/template/' + ins.id, ins)
.success(function(data, status, headers, config) {
console.log('Updated instruction:' + JSON.stringify(data));
})
.error(function(data, status, headers, config) {
console.log("Error from API: " + data.error);
});
};
// Delete instruction template
$scope.delete_instruction = function(ins){
$http
.delete(config.backend+'/instruction/template/' + ins.id)
.success(function(data, status, headers, config) {
console.log('Deleted instruction:' + JSON.stringify(data));
// Buscar method
for(var i=0; i<$scope.methods.length; i++) {
var m = $scope.methods[i];
if(ins.id_met == m.id){
// Buscar la instrucción y eliminar de la vista
for(var j=0; j<m.metainstructions.length; j++) {
if(ins.id == m.metainstructions[j].id){
$scope.methods[i].metainstructions.splice(j,1);
break;
}
}
break;
}
}
})
.error(function(data, status, headers, config) {
console.log("Error from API: " + data.error);
// Show message
ngToast.warning($translate.instant('cannot_delete_instruction'));
});
};
});
...@@ -27,6 +27,18 @@ ...@@ -27,6 +27,18 @@
</div> </div>
<ul class="dropdown-menu" role="menu"> <ul class="dropdown-menu" role="menu">
<li> <li>
<a class="pointer" role="menuitem" tabindex="0" href="/app/#/students">
<i class="glyphicon glyphicon-user" aria-hidden="true"></i>
{{ 'students' | translate }}
</a>
</li>
<li>
<a class="pointer" role="menuitem" tabindex="0" href="/app/#/instructions">
<i class="glyphicon glyphicon-tasks" aria-hidden="true"></i>
{{ 'instructions' | translate }}
</a>
</li>
<li>
<a class="pointer" role="menuitem" tabindex="0" href="/app/#/setup"> <a class="pointer" role="menuitem" tabindex="0" href="/app/#/setup">
<i class="glyphicon glyphicon-cog" aria-hidden="true"></i> <i class="glyphicon glyphicon-cog" aria-hidden="true"></i>
{{ 'setup' | translate }} {{ 'setup' | translate }}
......
<!-- InstructionsCtrl controls here, see app.js -->
<div class="panel panel-default">
<div class="panel-heading"><h3 class="panel-title" translate>own_instructions</h3></div>
<div class="panel-body">
<!-- Select to add new method -->
<div class="form-group">
<!-- Botón añadir método -->
<button ng-click="add_method()" class="btn btn-success btn-sm" popover="{{ 'add' | translate}}" popover-trigger="mouseenter">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> <span translate>new_method</span>
</button>
</div>
<!-- END select to add new method -->
<!-- Method instructions -->
<div class="method_details" ng-repeat="m in methods">
<input type="text" class="editable title" ng-model="m.name " ng-blur="update_method(m)"/>
<div class="options">
<a ng-click="delete_method(m)" popover="{{ 'delete' | translate}}" popover-trigger="mouseenter"><span class="text_medium delete color_red glyphicon glyphicon-remove-circle" aria-hidden="true"></span></a>
</div>
<textarea class="editable" ng-model="m.description " placeholder="{{'description' | translate}}" ng-blur="update_method(m)"></textarea>
<!-- Tabla método -->
<table class="table_instructions table">
<tr>
<th translate>instruction</th>
<th translate>objetive</th>
<th></th>
</tr>
<tr ng-repeat="i in m.metainstructions">
<td><input class="editable" type="text" ng-model="i.name" ng-blur="update_instruction(i)" /></td>
<td><input class="elipsis editable" type="text" ng-model="i.objective" ng-blur="update_instruction(i)" /></td>
<td><a confirmed-click="delete_instruction(i);" ng-confirm-click="{{ 'confirmation' | translate}}" class="delete_instruction"><span class="text_medium delete color_red glyphicon glyphicon-remove-circle" aria-hidden="true"></span></a></td>
</tr>
</table>
<!-- Añadir instrucción al método -->
<p class="text-right">
<a ng-click="add_instruction(m)" class="add_instruction btn btn-success btn-sm" role="button">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> {{ 'add_instruction' | translate }}
</a>
</p>
</div>
<!-- Fin de .method_details -->
</div>
<!-- END .panel-body -->
</div>
<!-- END .panel -->
</div>
...@@ -37,14 +37,26 @@ module.exports.policies = { ...@@ -37,14 +37,26 @@ module.exports.policies = {
destroy: ['tokenAuth'] destroy: ['tokenAuth']
}, },
MetaInstructionController: {
update: ['tokenAuth'],
create: ['tokenAuth'],
destroy: ['tokenAuth']
},
MetaMethodController: {
supVisible: ['tokenAuth'],
supOwned: ['tokenAuth'],
create: ['tokenAuth'],
update: ['tokenAuth'],
destroy: ['tokenAuth']
},
MethodController: { MethodController: {
update: ['tokenAuth'], update: ['tokenAuth'],
create: ['tokenAuth'], create: ['tokenAuth'],
newMethod: ['tokenAuth'], newMethod: ['tokenAuth'],
save: ['tokenAuth'], save: ['tokenAuth'],
destroy: ['tokenAuth'], destroy: ['tokenAuth'],
destroyTemplate: ['tokenAuth'],
meta_methods: ['tokenAuth']
}, },
OfficeController: { OfficeController: {
......
...@@ -35,14 +35,21 @@ module.exports.routes = { ...@@ -35,14 +35,21 @@ module.exports.routes = {
'POST /instruction': 'InstructionController.create', 'POST /instruction': 'InstructionController.create',
'DELETE /instruction/:id': 'InstructionController.destroy', 'DELETE /instruction/:id': 'InstructionController.destroy',
'GET /metamethods/:id_sup': 'MethodController.meta_methods', 'PUT /instruction/template/:id': 'MetaInstructionController.update',
'POST /instruction/template': 'MetaInstructionController.create',
'DELETE /instruction/template/:id': 'MetaInstructionController.destroy',
'PUT /method/:id': 'MethodController.update', 'PUT /method/:id': 'MethodController.update',
'POST /method': 'MethodController.create', 'POST /method': 'MethodController.create',
'POST /method/new': 'MethodController.newMethod', 'POST /method/new': 'MethodController.newMethod',
'POST /method/save': 'MethodController.save', 'POST /method/save': 'MethodController.save',
'DELETE /method/:id': 'MethodController.destroy', 'DELETE /method/:id': 'MethodController.destroy',
'DELETE /method/template/:id_mmet': 'MethodController.destroyTemplate',
'GET /method/template/:id_sup': 'MetaMethodController.supVisible',
'GET /method/template/owned/:id_sup': 'MetaMethodController.supOwned',
'POST /method/template': 'MetaMethodController.create',
'PUT /method/template/:id': 'MetaMethodController.update',
'DELETE /method/template/:id': 'MetaMethodController.destroy',
'GET /office/get_all': 'OfficeController.getAll', 'GET /office/get_all': 'OfficeController.getAll',
'GET /office/get/:id': 'OfficeController.get', 'GET /office/get/:id': 'OfficeController.get',
......
...@@ -44,6 +44,7 @@ module.exports = function (grunt) { ...@@ -44,6 +44,7 @@ module.exports = function (grunt) {
'assets/scripts/modules/supervisor/controllers/supervisor.js', 'assets/scripts/modules/supervisor/controllers/supervisor.js',
'assets/scripts/modules/supervisor/controllers/students.js', 'assets/scripts/modules/supervisor/controllers/students.js',
'assets/scripts/modules/supervisor/controllers/setup.js', 'assets/scripts/modules/supervisor/controllers/setup.js',
'assets/scripts/modules/supervisor/controllers/instructions.js',
'assets/scripts/modules/student/controllers/setup.js', 'assets/scripts/modules/student/controllers/setup.js',
'assets/scripts/modules/student/controllers/student.js', 'assets/scripts/modules/student/controllers/student.js',
'assets/scripts/modules/student/controllers/session.js', 'assets/scripts/modules/student/controllers/session.js',
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment