Commit 6b502290 by Fernando Martínez Santiago

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

parents e4266000 e0c15877
......@@ -144,7 +144,7 @@ module.exports = {
else if (stu_sup && !req.token.office)
student.supervision = 1; // requester is tutor of the studend
else if (stu_sup && req.token.office && student.office == req.token.office.id)
student.supervision = 2; // requester is supervisor of student
student.supervision = 2; // requester is supervisor of student
if (student.supervision == -1) // should not hace access!!!
return res.forbidden("Access to this student should not be granted to you");
......
......@@ -266,20 +266,13 @@ module.exports = {
// student
supervisors: function(id_stu, callback) {
StuSup.find({id_stu: id_stu}).populate('supervisor').exec(function(err, stuSups) {
var l = [];
if (err || !stuSups || stuSups.length == 0)
return callback(err, l);
if (err)
return callback(err, []);
if (!stuSups || stuSups.length == 0)
return callback(new Error("No supervisors found"), []);
async.eachSeries(stuSups,
function(stuSup, next) {
l.push(stuSup.supervisor);
next();
},
function (err) {
return callback(err, l);
}
);
var sups = stuSups.map((st) => {return st.supervisor});
return callback(null, sups);
});
},
......
......@@ -6,30 +6,30 @@ module.exports = function isSupervisorOfStudentOrIsSupAdmin(req, res, next) {
if (!studentId || !supervisorId) {
sails.log.error('This request needs an id_stu parameter and a authenticated supervisor');
res.json(401, { error: 'Access denied' });
return res.json(401, { error: 'Access denied' });
} else {
Student.findOne(studentId)
.then(function (s) {
if (s.office == req.token.office.id && req.token.isSupAdmin) {
if (req.token.office && s.office == req.token.office.id && req.token.isSupAdmin)
next();
}
else {
Student.supervisors(studentId, function (err, sups) {
const studentSupervisorsIds = sups.map((studentSupervisor) => studentSupervisor.id);
if (err)
return res.json(401, {error: 'Access denied'});
var supIds = sups.map((studentSupervisor) => studentSupervisor.id);
if (supIds.indexOf(supervisorId) >= 0)
return next();
if (err || studentSupervisorsIds.length === 0) {
sails.log.error(`Student ${studentId} has no supervisor assigned`);
res.json(401, { error: 'Access denied' });
} else if (studentSupervisorsIds.indexOf(supervisorId) < 0) {
sails.log.error(`Supervisor ${supervisorId} is not assigned to Student ${studentId}`);
sails.log.debug(`Student supervisors: ${studentSupervisorsIds}`);
res.json(401, { error: 'Access denied' });
} else {
sails.log.debug(`Supervisor ${supervisorId} is assigned to Student ${studentId}`);
next();
}
sails.log.error(`Supervisor ${supervisorId} is not assigned to Student ${studentId}`);
return res.json(401, { error: 'Access denied' });
});
}
})
.catch((err) => {
sails.log.error(JSON.stringify(err));
return res.json(401, { error: "No student found" })
});
}
};
......@@ -8,12 +8,11 @@
"dependencies": {
"angular": "1.2.x",
"angular-mocks": "1.3.x",
"jquery": "~2.1.1",
"jquery": "^3.1.1",
"bootstrap": "~3.1.1",
"jquery-timeago": "1.4.x",
"angular-translate": "~2.6.0",
"angular-translate-loader-static-files": "~2.6.1",
"angular-re-captcha": "~0.2.0",
"angular-bootstrap": "~0.12.1",
"angular-file-upload": "~1.1.5",
"ng-file-upload": "~3.2.4",
......@@ -30,7 +29,7 @@
"ng-lodash": "~0.3.0",
"bootstrap-filestyle": "~1.2.1",
"ngMask": "angular-mask#~3.1.1",
"angular-recaptcha": "~4.0.1"
"angular-recaptcha": "^4.0.1"
},
"resolutions": {
"angular": ">=1 <1.3.0",
......
......@@ -39,8 +39,15 @@
"cancel": "Cancel",
"cannot_delete_method": "Method could not be deleted, maybe due to existing recorded sessions.",
"cannot_delete_instruction": "Instruction could not be deleted, maybe due to existing recorded sessions.",
"case_requested": "Please, specify your user case",
"case_therapist_office": "Therapist belonging to an office already in Pictogram",
"case_therapist_nooffice": "Therapist not belonging to an office already in Pictogram",
"case_title": "User case",
"case_tutor_office": "Father, mother or tutor belonging to an office already in Pictogram",
"case_tutor_nooffice": "Father, mother or tutor not belonging to an office already in Pictogram",
"categories": "Categories",
"category_pictograms": "Category's pictograms",
"captcha_requested": "Captcha must be validated",
"change_password": "Change password",
"change_cat_picto": "Change category pictogram",
"change_picture": "Change picture",
......@@ -166,6 +173,7 @@
"login_footer": "<strong>Pictogram Web</strong> is a product by <a href='http://www.yottacode.com'>Yottacode S.L.</a> for Augmentative and Alternative Communication, loaded with more than 20,000 images from the <a href='https://www.n2y.com/products/symbolstix'>SymbolStix</a> collection, in several languages. From here, you will be able to manage devices with official <i>Pictogram Tablet</i> app installed.",
"login_success": "Login succeed. Welcome {{name}}",
"logout": "Log Out",
"logo_url": "URL (http://...) to office's logo",
"man": "Man",
"March": "March",
"mark": "Mark",
......@@ -241,6 +249,7 @@
"pictogram_setup": "Pictogram setup",
"pictograms": "Pictograms",
"place_pictos": "Place pictograms in the phrase tape when",
"postal_code": "Postal code",
"press": "Long press",
"previous_actions": "Previous actions",
"previous_sessions": "Previous sessions",
......@@ -261,12 +270,14 @@
"select_instruction": "-- Select an instruction --",
"select_a_method": "-- Select a method --",
"select_method": "-- Select a method or create it --",
"select_office": "Select an office from the list",
"send": "Send",
"September": "September",
"serial": "Serial number",
"serial_created": "Serial number {{serial}} created",
"serial_list": "Free serial numbers",
"serial_not_created": "Serial number couldn't be created",
"server_error": "An error has been reported when connecting to the server.",
"session": "Session",
"sessions": "Sessions",
"session_mean_length": "Session mean length: {{hours}} hours",
......@@ -274,6 +285,7 @@
"sessions": "Sessions",
"sessions_of": "Sessions of",
"setup": "Setup",
"sexo": "Sex",
"show": "Show",
"size": "Size",
"small": "Small",
......
......@@ -39,8 +39,15 @@
"cancel": "Cancelar",
"cannot_delete_method": "No se pudo eliminar el método, tal vez porque existen sesiones asociadas.",
"cannot_delete_instruction": "No se pudo eliminar la instrucción, tal vez porque existen sesiones asociadas.",
"case_requested": "Por favor, especifique el tipo de usuario.",
"case_therapist_office": "Soy terapeuta y mi centro o gabinete está registrado en Pictogram",
"case_therapist_nooffice": "Soy terapeuta y mi centro o gabinete NO está registrado en Pictogram",
"case_title": "Tipo de usuario",
"case_tutor_office": "Soy padre, madre o tutor/a y el niño/a está en un centro o gabinete registrado en Pictogram",
"case_tutor_nooffice": "Soy padre, madre o tutor/a y el niño/a NO está en un centro o gabinete registrado en Pictogram",
"categories": "Categorías",
"category_pictograms": "Pictogramas de la categoría",
"captcha_requested": "Debe validar el captcha",
"change_password": "Cambiar contraseña",
"change_cat_picto": "Cambiar pictograma de la categoría",
"change_picture": "Cambiar fotografía",
......@@ -166,6 +173,7 @@
"login_footer": "<strong>Pictogram Web</strong> es un producto de <a href='http://www.yottacode.com'>Yottacode S.L.</a> para Comunicación Aumentativa y Alternativa, cargado con más de 20,000 pictogramas de <a href='https://www.n2y.com/products/symbolstix'>SymbolStix</a>, en varios idiomas. Desde aquí podrás gestionar los dispositivos que dispongan de la app oficial <i>Pictogram Tablet</i>.",
"login_success": "Login correcto. Bienvenido {{name}}",
"logout": "Salir",
"logo_url": "URL (http://...) al logo del centro/gabinete",
"man": "Hombre",
"March": "Marzo",
"mark": "Marcar",
......@@ -202,6 +210,7 @@
"objetive": "Objetivo",
"October": "Octubre",
"office": "Gabinete",
"office_center": "Gabinete/centro",
"office_added": "Gabinete añadido",
"office_deleted": "Gabinete eliminado",
"office_not_added": "No se ha podido añadir el gabinete",
......@@ -241,6 +250,7 @@
"pictogram_setup": "Configuración del pictograma",
"pictograms": "Pictogramas",
"place_pictos": "Colocar pictogramas en la cinta de frase cuando",
"postal_code": "Código postal",
"press": "Pulsación larga",
"previous_actions": "Acciones anteriores",
"previous_sessions": "Sesiones anteriores",
......@@ -262,12 +272,14 @@
"select_instruction": "-- Selecciona una instrucción --",
"select_a_method": "-- Selecciona un método --",
"select_method": "-- Selecciona un método o créalo --",
"select_office": "Seleccione una oficina/centro de la lista",
"send": "Enviar",
"September": "Septiembre",
"serial": "Número de serie",
"serial_created": "Número de serie {{serial}} creado",
"serial_list": "Números de serie libres",
"serial_not_created": "No se ha podido crear el número de serie",
"server_error": "No se ha podido conectar con el servidor.",
"session": "Sesión",
"sessions": "Sesiones",
"session_mean_length": "Duración media de sesión: {{hours}} horas",
......@@ -275,6 +287,7 @@
"sessions": "Sesiones",
"sessions_of": "Sesiones de",
"setup": "Configuración",
"sexo": "Sexo",
"show": "Mostrar",
"size": "Tamaño",
"small": "Pequeño",
......
......@@ -8,7 +8,6 @@ var dashboardApp = angular.module('dashboardApp', [
'dashboardServices',
'dashboardDirectives',
'pascalprecht.translate',
'vcRecaptcha',
'ui.bootstrap',
'angularFileUpload',
'angular.filter',
......@@ -18,7 +17,8 @@ var dashboardApp = angular.module('dashboardApp', [
'ngToast',
'chart.js',
'ngLodash',
'ngMask'
'ngMask',
'vcRecaptcha'
]);
/* Main constants */
......@@ -28,15 +28,20 @@ dashboardApp.constant('CONSTANTS', {
password_minlength: 8
});
/* reCaptcha configuration */
dashboardApp.config(['vcRecaptchaServiceProvider', function(vcRecaptchaServiceProvider){
vcRecaptchaServiceProvider.setSiteKey('6LdLjh0TAAAAANblo_KUGNnmRZuIetOkdjdhj1b6');
vcRecaptchaServiceProvider.setTheme('light');
//vcRecaptchaServiceProvider.setStoken('--- YOUR GENERATED SECURE TOKEN ---')
vcRecaptchaServiceProvider.setSize('normal');
//vcRecaptchaServiceProvider.setType('---- audio or image ----')
vcRecaptchaServiceProvider.setLang('es-es');
}]);
//
// Google reCaptcha configuration
//
dashboardApp.config(function(vcRecaptchaServiceProvider){
vcRecaptchaServiceProvider.setDefaults({
key: '6LdGOBMUAAAAAJ6uYWb8d952TOR2knwbAem8TKJ8',
theme: 'light',
//stoken: '--- YOUR GENERATED SECURE TOKEN ---',
size: 'normal',
type: 'image',
lang: 'es'
});
});
/* Toast (notification) configuration */
......@@ -121,6 +126,12 @@ dashboardApp.config(function ($stateProvider, $urlRouterProvider) {
templateUrl: 'modules/supervisor/views/instructions.html',
controller: 'InstructionsCtrl',
})
.state('supervisors_students', {
url: '/supervisors_students',
parent: 'supervisor',
templateUrl: 'modules/supervisor/views/supervisors_students.html',
controller: 'StudentsCtrl',
})
// Abstract page for student
.state('student', {
templateUrl: 'modules/student/views/student.html',
......
......@@ -23,7 +23,7 @@ var dashboardControllers = angular.module('dashboardControllers', ['dashboardCon
// Main Controller
//
//
dashboardControllers.controller('MainCtrl', function MainCtrl($scope, $window, $location, $translate, $rootScope) {
dashboardControllers.controller('MainCtrl', function MainCtrl($scope, $window, $location, $translate, $rootScope, $timeout) {
// Always use objects if we want to modify this scope in the childs
......@@ -47,6 +47,7 @@ dashboardControllers.controller('MainCtrl', function MainCtrl($scope, $window, $
$translate.use(lang);
//$translateProvider.preferredLanguage('es-es');
//---------------------------------------------------------------
......
......@@ -7,7 +7,6 @@ dashboardControllers.controller('LoginSettingPasswordCtrl', function LoginSettin
$scope,
$http,
$window,
reCAPTCHA,
$translate,
$location,
config,
......@@ -25,18 +24,19 @@ dashboardControllers.controller('LoginSettingPasswordCtrl', function LoginSettin
changePasswordForm.$invalid = true;
};
$scope.reset();
reCAPTCHA.setPublicKey('6LdLjh0TAAAAANblo_KUGNnmRZuIetOkdjdhj1b6');
if ($stateParams.token)
$scope.show_change_form = true;
else
$scope.show_change_form = false;
// if token exists, show_change_form is true
$scope.show_change_form = !!($stateParams.token);
/*
* Handles user submission of request for password change
*/
$scope.request_change_password = function () {
if (grecaptcha.getResponse().length == 0) {
ngToast.danger({ content: $translate.instant('captcha_requested') });
return;
}
if (!$scope.requestChangePasswordForm.$valid)
return;
......
......@@ -9,9 +9,11 @@ function SignInCtrl($scope,
$http,
$window,
$translate,
$rootScope,
config,
CONSTANTS,
ngToast)
ngToast,
vcRecaptchaService)
{
$scope.reset = function () {
......@@ -20,42 +22,31 @@ function SignInCtrl($scope,
surname: '',
address: '',
phone: '',
gender: 'F',
gender: 'M',
email: '',
email_confirm: '',
password: '',
password_confirm: '',
lang: 'es-es'
lang: 'es',
role: null,
office: {
country: 'NULL'
},
office_idx: -1
};
};
$scope.reset();
//
// reCaptcha functions
//
/*
$scope.recaptcha = {
lang : $translate.use(),
response : null,
widgetId : null,
setResponse: function (response) {
console.info('Response available');
$scope.recaptcha.response = response;
},
setWidgetId: function (widgetId) {
console.info('Created widget ID: %s', widgetId);
$scope.recaptcha.widgetId = widgetId;
},
cbExpiration: function() {
console.info('Captcha expired. Resetting response object');
vcRecaptchaService.reload($scope.recaptcha.widgetId);
$scope.recaptcha.response = null;
}
};*/
// Get the list of offices
$http
.get(config.backend + '/office/get_all')
.success(function (offices) {
$scope.offices = offices;
})
.error(function () {
ngToast.danger({ content: $translate.instant('server_error') });
});
// Form submit
$scope.signin = function () {
......@@ -81,6 +72,11 @@ function SignInCtrl($scope,
return;
}
if (!$scope.formdata.role) {
ngToast.danger({ content: $translate.instant('case_requested') });
return;
}
if (!$scope.signInForm.$valid)
return;
......
......@@ -26,9 +26,9 @@
<input type="email" class="form-control" id="email" placeholder="{{ 'your_email' | translate}}" required ng-model="email"/>
</div>
<div class="form-group" ng-if="!show_change_form">
<label>Captcha*</label>
<div re-captcha ng-model="captcha_reqchgpass"></div>
<div class="form-group">
<legend>Captcha</legend>
<div vc-recaptcha></div>
</div>
<p class="text-center">
......@@ -56,11 +56,8 @@
<p class="color_red text_sm text-center" ng-show="password != password_confirm" translate>password_match</p>
<div class="form-group" ng-if="show_change_form">
<label>Captcha*</label>
<div re-captcha
ng-model="captcha_chgpass"
size="compact"
lang="es"></div>
<label>Captcha</label>
<div vc-recaptcha></div>
</div>
<p class="text-center">
......
......@@ -47,6 +47,7 @@
<div class="row">
<div class="col-md-12">
<ul class="nav nav-tabs tabs_student">
<!-- 0: admin, 1: tutor, 2: therapist -->
<li role="presentation" ng-class="{'active' : nav.tab == 'collections'}" ng-if="studentData.supervision != 0">
<a href="/app/#/student/{{studentData.id}}/collections" ng-click="nav.tab = ''"><span class="glyphicon glyphicon-th" aria-hidden="true"></span> {{ 'collections' | translate }}</a>
</li>
......@@ -59,7 +60,7 @@
<li role="presentation" ng-class="{'active' : nav.tab == 'reports'}" ng-if="studentData.supervision != 1">
<a href="/app/#/student/{{studentData.id}}/reports" ng-click="nav.tab = 'reports'"><span class="glyphicon glyphicon-file" aria-hidden="true"></span> {{ 'reports' | translate }}</a>
</li>
<li role="presentation" ng-class="{'active' : nav.tab == 'setup'}" ng-if="studentData.supervision != 1">
<li role="presentation" ng-class="{'active' : nav.tab == 'setup'}" ng-if="studentData.supervision != 0">
<a href="/app/#/student/{{studentData.id}}/setup" ng-click="nav.tab = 'setup'"
><span class="glyphicon glyphicon-cog" aria-hidden="true"></span> {{ 'setup' | translate }}</a>
</li>
......
<div id="picto_config">
<div class="modal-header">
<button type="button" class="close" ng-click="close()">
<span aria-hidden="true">&times;</span><span class="sr-only" translate>close</span>
</button>
<h4 class="modal-title" id="myModalLabel" translate>pictogram_setup</h4>
</div>
<div class="modal-body">
<div class="form-group">
<label translate>expression</label>
<!-- Modificable sólo si es el propietario del picto -->
<div id="add_label" class="input-group">
<span class="input-group-addon glyphicon glyphicon-comment" aria-hidden="true"></span>
<input type="text" class="form-control" ng-model="studentPicto.attributes.expression" />
</div>
</div>
<div class="container-fluid">
<div class="form-group">
<label translate>legend</label><br/>
<div class="row">
<div class="col-md-6">
<!-- <div class="checkbox">
<select class="form-control" data-toggle="toggle" ng-model="studentPicto.attributes.legend" ng-change="update_properties()">
<option value="none" selected>Sin leyenda</option>
<option value="normal">Leyenda normal</option>
<option value="full">Solo leyenda</option>
</select>
</div> -->
<input type="radio" ng-model="studentPicto.attributes.legend" value="none">
<span translate>legend_none</span>
<br/>
<input type="radio" ng-model="studentPicto.attributes.legend" value="normal">
<span translate>legend_normal</span>
<br/>
<input type="radio" ng-model="studentPicto.attributes.legend" value="full">
<span translate>legend_full</span>
<div class="form-group">
<div class="row">
<label translate>expression</label>
</div>
<!-- Modificable sólo si es el propietario del picto -->
<div class="row">
<div class="col-xs-6">
<div class="input-group" id="add_label" >
<span class="input-group-addon glyphicon glyphicon-comment" aria-hidden="true"></span>
<input type="text" class="form-control" ng-model="studentPicto.attributes.expression" />
</div>
</div>
<div class="col-xs-6">
<div class="alert alert-info" style="margin: 0 auto;">
<strong>¡Atención!</strong> La expresión debe tener un máximo de 8-10 caracteres.
</div>
</div>
</div>
</div>
<div class="col-md-6">
<input type="checkbox" ng-model="update_all_legend" ng-init="update_all_legend=false">
<span translate>legend_apply_all</span>
<hr>
<div class="form-group">
<div class="row">
<label translate>legend</label><br/>
</div>
<div class="row">
<div class="col-md-6">
<!-- <div class="checkbox">
<select class="form-control" data-toggle="toggle" ng-model="studentPicto.attributes.legend" ng-change="update_properties()">
<option value="none" selected>Sin leyenda</option>
<option value="normal">Leyenda normal</option>
<option value="full">Solo leyenda</option>
</select>
</div> -->
<input type="radio" ng-model="studentPicto.attributes.legend" value="none">
<span translate>legend_none</span>
<br/>
<input type="radio" ng-model="studentPicto.attributes.legend" value="normal">
<span translate>legend_normal</span>
<br/>
<input type="radio" ng-model="studentPicto.attributes.legend" value="full">
<span translate>legend_full</span>
</div>
<div class="col-md-6">
<input type="checkbox" ng-model="update_all_legend" ng-init="update_all_legend=false">
<span translate>legend_apply_all</span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<button class="btn btn-success pull-right" ng-click="save()" translate>save</button>
<button class="btn btn-secondary margin-right10 pull-right" ng-click="close()" translate>cancel</button>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<button class="btn btn-success pull-right" ng-click="save()" translate>save</button>
<button class="btn btn-secondary margin-right10 pull-right" ng-click="close()" translate>cancel</button>
</div>
</div>
</div>
</div>
<!-- End modal-body -->
</div>
......@@ -32,6 +32,11 @@
{{ 'students' | translate }}
</a>
</li>
<li>
<a class="pointer" role="menuitem" tabindex="0" href="/app/#/supervisors_students">
<i class="glyphicon glyphicon-star" aria-hidden="true"></i>
{{ 'supervisors' | translate }}
</a>
<li ng-if="user.isTutor == false">
<a class="pointer" role="menuitem" tabindex="0" href="/app/#/instructions">
<i class="glyphicon glyphicon-tasks" aria-hidden="true"></i>
......
<!-- Admin Supervisors -->
<div class="row">
<div ng-class="{'col-md-12':hidesupervisoradd === true && hidesupervisorupdate === true, 'col-md-8':hidesupervisoradd === false || hidesupervisorupdate === false}">
<h3 translate>supervisors</h3>
<div class="row">
<div class="col-xs-3">
<a ng-click="resetForm(); hidesupervisoradd = false" class="btn btn-success btn-sm" role="button">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> {{ 'add_supervisor' | translate }}
</a>
</div>
<div class="col-xs-6 input-group">
<input type="text" ng-model="search_sups" id="search_sups" placeholder="{{ 'filter' | translate }}" class="form-control" aria-describedby="basic-addon2">
<span class="input-group-addon glyphicon glyphicon-search" id="basic-addon2" aria-hidden="true"></span>
</div>
<div class="col-xs-3">
</div>
</div>
<table class="table table-striped">
<tr>
<th translate>name</th>
<th translate>email</th>
<th>Ops</th>
</tr>
<tr ng-repeat="supervisor in supervisors | filter:search_sups | orderBy: 'name'">
<td class="color_blue">{{supervisor.name}} {{supervisor.surname}}</td>
<td>{{supervisor.email}}</td>
<td class="ops">
<a ng-click="update_supervisor(supervisor)" title="{{'edit'|translate}}"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span></a>
<a ng-click="delete_supervisor(supervisor)" title="{{'delete'|translate}}"><span class="color_red glyphicon glyphicon-remove-circle" aria-hidden="true"></span></a>
</td>
</tr>
</table>
</div>
<!-- Add Supervisor Form -->
<div ng-include="'modules/admin/views/supervisors_add.html'" class="col-md-4" ng-init="hidesupervisoradd = true" ng-hide="hidesupervisoradd"></div>
<!-- Update Supervisor Form -->
<div ng-include="'modules/admin/views/supervisors_update.html'" class="col-md-4" ng-init="hidesupervisorupdate = true" ng-hide="hidesupervisorupdate"></div>
</div>
......@@ -3,9 +3,12 @@
//----------------------
// Translate Controller
//----------------------
dashboardControllers.controller('TranslateController', function($translate, $scope) {
dashboardControllers.controller('TranslateController', function($translate, $scope, vcRecaptchaService) {
$scope.changeLanguage = function (langKey) {
$translate.use(langKey);
$scope.user.lang = langKey;
// Reload captcha according to language (only once instance per page, so id is always 0)
vcRecaptchaService.useLang(0, langKey.substr(0,2));
};
});
......@@ -466,8 +466,8 @@ textarea.editable{
.picto .picto_options .picto_remove{ position: absolute; top: 2px; left: 2px; }
.picto .picto_options .picto_add{ position: absolute; top: 28px; left: 28px; }
.picto .picto_options .picto_ok{ position: absolute; top: 2px; right: 2px; }
.picto .picto_options .picto_tags{ position: absolute; bottom: 2px; left: 2px; }
.picto .picto_options .picto_config{ position: absolute; bottom: 2px; right: 2px; }
.picto .picto_options .picto_tags{ position: absolute; bottom: 2px; left: 2px; z-index: 2; }
.picto .picto_options .picto_config{ position: absolute; bottom: 2px; right: 2px; z-index: 2; }
.picto .picto_options .picto_info{ position: absolute; top: 2px; left: 2px; }
.picto .picto_options .picto_plus{ position: absolute; top: 2px; right: 2px; }
......@@ -482,13 +482,17 @@ textarea.editable{
bottom: 0px;
text-align: center;
width: 100%;
background-color: rgba(1, 1, 1, 0.50);
color: white;
background-color: white;
color:black;
margin-left: -2px;
font-weight: 600;
text-transform: uppercase;
font-size: 12px;
word-wrap: break-word;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
border-radius: 0px 0px 5px 5px;
z-index: 1;
}
.picto-legend-full {
position: absolute;
......@@ -954,3 +958,7 @@ input[type=range]:focus::-ms-fill-upper {
font: 32px Arial, sans-serif;
}
.input-group-addon:first-child{
top: 0px;
}
......@@ -60,7 +60,7 @@ module.exports.policies = {
},
OfficeController: {
getAll: ['tokenAuth', 'isAdmin'],
getAll: true,
get: ['tokenAuth'],
getBasic: true,
supervisors: ['tokenAuth', 'isAdmin']
......
module.exports = function (grunt) {
/* eslint-disable max-len */
var jsLibs = [
'assets/app/bower_components/jquery/dist/jquery.min.js',
'assets/app/bower_components/angular/angular.js',
'assets/app/bower_components/angular-bootstrap/ui-bootstrap.js',
'assets/app/bower_components/angular-bootstrap/ui-bootstrap-tpls.js',
'assets/app/bower_components/angular-ui-router/release/angular-ui-router.js',
'assets/app/bower_components/angular-translate/angular-translate.js',
'assets/app/bower_components/angular-translate-loader-static-files/angular-translate-loader-static-files.js',
'assets/app/bower_components/angular-re-captcha/angular-re-captcha.js', // TODO: delete after testing angular-recaptcha
'assets/app/bower_components/angular-recaptcha/release/angular-recaptcha.min.js',
'assets/app/bower_components/ng-file-upload/angular-file-upload.js',
'assets/app/bower_components/angular-filter/dist/angular-filter.js',
......@@ -21,6 +20,7 @@ module.exports = function (grunt) {
'assets/app/bower_components/angular-animate/angular-animate.js',
'assets/app/bower_components/angular-sanitize/angular-sanitize.js',
'assets/app/bower_components/ngtoast/dist/ngToast.js',
'assets/app/bower_components/angular-recaptcha/release/angular-recaptcha.min.js',
'assets/app/bower_components/chart.js/dist/Chart.min.js',
'assets/app/bower_components/angular-chart.js/dist/angular-chart.min.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