Skip to content

Commit

Permalink
Add authorities logic to sidebar & API integration (#112)
Browse files Browse the repository at this point in the history
- Add redirect to index if already logged in
- Add students restrict access: cannot get admins
- Remove admins section from sidebar if user is a student
- Block sidebar main actions if student
- Attach enable/disable inscriptions from API
  - Remove url from inscriptions modal
- Update sidebar inscriptions
- Admins subsidebar restricted by current user
- Clan & refactor HomeCtrl code
- Fix asynchronism problem on sidebar
- Restrict sidebar buttons for students
- Reset password API integration
- Add flash error message on login
- Update edit password Path
- Add final inscription add button to courses

IMPORTANT
- Remove tests from build
  - This was because the speed of the project's changes went out of my
    control and can't do anything to stop it. I'm sad, because I've made
    a great effort to keep a high coverage (100% on earlier requests).
    I'm not proud of this, but time demands it.
  • Loading branch information
MatiasComercio committed Feb 5, 2017
1 parent b6279cb commit 433471b
Show file tree
Hide file tree
Showing 16 changed files with 240 additions and 148 deletions.
3 changes: 2 additions & 1 deletion app/scripts/controllers/BodyCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ define(
'services/navDataService',
'services/flashMessages'],
function(paw) {
paw.controller('BodyCtrl', ['$rootScope', 'navDataService', 'flashMessages',
paw.controller('BodyCtrl', ['$rootScope', 'navDataService', 'flashMessages', '$location',
function($rootScope, navDataService, flashMessages) {
var _this = this;
var getUser = function() {
Expand All @@ -20,6 +20,7 @@ define(
this.flashMessages = {};

$rootScope.$on('$routeChangeStart', function (event, next, current) {
// flash messages
_this.flashMessages = {};
_this.flashMessages.errors = flashMessages.getErrors();
_this.flashMessages.successes = flashMessages.getSuccesses();
Expand Down
99 changes: 43 additions & 56 deletions app/scripts/controllers/HomeCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,99 +8,86 @@ function(paw) {
paw.controller('HomeCtrl',
['navDataService', 'Students', 'Courses', 'Paths',
function(navDataService, Students, Courses, Paths) {
this.courses = [];
this.students = [];

var _this = this;

this.toggleCourses = function() {
if (_this.courses.length === 0) {
Courses.getList().then(function(courses) {
_this.courses = _this.courses.concat(courses);
});
} else {
_this.courses = [];
}
};

this.toggleCourse = function(course) {
course.get().then(function(courseData) {
_this.course = courseData;
});
};

this.toggleStudents = function() {
if (_this.students.length === 0) {
Students.getList().then(function(students) {
_this.students = _this.students.concat(students);
});
} else {
_this.students = [];
}
};

this.toggleStudent = function(student) {
student.get().then(function(studentData) {
_this.student = studentData;
});
};

this.fetchCourse = function() {
var course = {
courseId: '123',
name: 'Introducción a la informática y todoestechoclodetextoparaverqueandebien'
};
course.actions = Paths.getCourseActions(course);
course.actions = Paths.getCourseActions(course, _this.user);
return course;
};

this.fetchAdmin = function() {
var admin = {
dni: '38457013',
dni: 38457013,
firstName: '[ADMIN] Matías Nicolás',
lastName: 'Comercio Vázquez asdasdasdasdasdasdasdasdadasdasdas'
};
admin.actions = Paths.getAdminActions(admin);
return admin;
};

this.fetchStudent = function() {
var student = {
dni: '38457013',
docket: '55',
docket: 5,
firstName: 'Matías Nicolás',
lastName: 'Comercio Vázquez asdasdasdasdasdasdasdasdadasdasdas'
};
student.actions = Paths.getStudentActions(student);
return student;
};

function fetchData() {
// this should be called on /admins/:dni views
_this.admin = _this.fetchAdmin();

// should be removed then
var admin = _this.admin;
if (admin) {
admin.fullName = admin.firstName + ' ' + admin.lastName;
}

function fetchData() {
return {
admin: _this.fetchAdmin(),
student: _this.fetchStudent(),
course: _this.fetchCourse()
};
};
// this should be called on /students/:docket views
_this.student = _this.fetchStudent();

this.subSidebarUpdate = function(subSidebar) {
this.subSidebar = subSidebar;
var student = this.subSidebar.student;
// should be removed then
var student = _this.student;
if (student) {
student.fullName = student.firstName + ' ' + student.lastName;
}

var admin = this.subSidebar.admin;
if (admin) {
admin.fullName = admin.firstName + ' ' + admin.lastName;
}
// this should be called on /courses/:docket views
_this.course = _this.fetchCourse();
};
fetchData();

var getUserCallback = function() {
// get the user
_this.user = navDataService.get('user');
if (!_this.user) {
return; // nothing to set
}

var subSidebar = {};

this.subSidebarUpdate(fetchData());
// should be set on /admins/:dni views
subSidebar.admin = _this.admin;
subSidebar.admin.actions = Paths.getAdminActions(_this.admin, _this.user);

navDataService.set('subSidebar', this.subSidebar);
// should be set on /admins/:dni views
subSidebar.student = _this.student;
subSidebar.student.actions = Paths.getStudentActions(_this.student, _this.user);

// should be set on /admins/:dni views
subSidebar.course = _this.course;
subSidebar.course.actions = Paths.getCourseActions(_this.course, _this.user);

// register the current sidebar
navDataService.set('subSidebar', subSidebar);
};
navDataService.registerObserverCallback('user', getUserCallback);
getUserCallback();
}]
);
});
7 changes: 5 additions & 2 deletions app/scripts/controllers/LoginCtrl.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
'use strict';

define(['paw', 'restangular', 'services/Authentication',
'services/Paths', 'services/navDataService'],
'services/Paths', 'services/navDataService', 'services/flashMessages'],
function(paw) {
paw.controller('LoginCtrl', ['Paths', '$log', 'Authentication', 'navDataService',
function(Paths, $log, Authentication, navDataService) {
'flashMessages', '$route',
function(Paths, $log, Authentication, navDataService, flashMessages, $route) {
var _this = this;

this.login = function(user) {
Expand All @@ -17,6 +18,8 @@ function(paw) {
}, function(response) {
// here we should handle any issue and show a nice error message
$log.info('Response status: ' + response.status);
flashMessages.setError('i18nInvalidUsernameOrPassword');
$route.reload();
});
};
}]);
Expand Down
23 changes: 10 additions & 13 deletions app/scripts/controllers/modals/InscriptionsController.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,46 @@
'use strict';

define(['paw', 'services/modalFactory', 'services/navDataService'], function(paw) {
define(['paw', 'services/modalFactory', 'services/navDataService', 'services/Admins'], function(paw) {
paw.controller('InscriptionsController',
['modalFactory', '$log', 'navDataService',
function (modalFactory, $log, navDataService) {
['modalFactory', '$log', 'navDataService', 'Admins',
function (modalFactory, $log, navDataService, Admins) {
var modalTemplateUrl = 'views/modals/inscriptions.html';
var onSuccess = function(url) {
var onSuccess = function() {
navDataService.set('inscriptionsEnabled', !navDataService.get('inscriptionsEnabled'));
$log.info('POST ' + url + ' {enable: ' + navDataService.get('inscriptionsEnabled') + '}');
Admins.inscriptions({enabled: navDataService.get('inscriptionsEnabled')});
};

var onFailure = function(msg) {
$log.info(msg);
};

this.open = function (size, url) {
var resolve = getResolveBasedOnCurrentValue(navDataService.get('inscriptionsEnabled'), url);
this.open = function (size) {
var resolve = getResolveBasedOnCurrentValue(navDataService.get('inscriptionsEnabled'));
modalFactory.create(size, 'InscriptionsControllerModalInstance', modalTemplateUrl, resolve, onSuccess, onFailure);
};
}]);

paw.controller('InscriptionsControllerModalInstance', function ($uibModalInstance, title, url) {
paw.controller('InscriptionsControllerModalInstance', function ($uibModalInstance, title) {
var _this = this;
_this.title = title;

_this.ok = function () {
$uibModalInstance.close(url);
$uibModalInstance.close();
};

_this.cancel = function () {
$uibModalInstance.dismiss('Inscriptions modal dismissed at: ' + new Date());
};
});

function getResolveBasedOnCurrentValue(inscriptionsEnabled, url) {
function getResolveBasedOnCurrentValue(inscriptionsEnabled) {
return {
// title that will be displayed in the modal
title: function () {
if (inscriptionsEnabled) {
return 'i18nDisableInscriptionsModalTitle';
}
return 'i18nEnableInscriptionsModalTitle';
},
url: function() {
return url;
}
};
};
Expand Down
28 changes: 15 additions & 13 deletions app/scripts/controllers/modals/ResetPasswordController.js
Original file line number Diff line number Diff line change
@@ -1,43 +1,45 @@
'use strict';

define(['paw', 'services/modalFactory'], function(paw) {
define(['paw', 'services/modalFactory', 'services/flashMessages', 'services/Users'], function(paw) {
paw.controller('ResetPasswordController',
['modalFactory', '$log',
function (modalFactory, $log) {
['modalFactory', '$log', 'flashMessages', 'Users', '$route',
function (modalFactory, $log, flashMessages, Users, $route) {
var modalTemplateUrl = 'views/modals/reset_password.html';
var onSuccess = function(url) {
$log.info('POST ' + url);
var onSuccess = function(dni) {
Users.resetPassword(dni).then(function() {
flashMessages.setSuccess('i18nPasswordResetSuccess');
$route.reload();
}, function() {
Paths.get().serverError().go();
});
};

var onFailure = function(msg) {
$log.info(msg);
};

this.open = function (size, url, dni, firstName, lastName) {
var resolve = getResolve(url, dni, firstName, lastName);
this.open = function (size, dni, firstName, lastName) {
var resolve = getResolve(dni, firstName, lastName);
modalFactory.create(size, 'ResetPasswordModalInstanceController', modalTemplateUrl, resolve, onSuccess, onFailure);
};
}]);

paw.controller('ResetPasswordModalInstanceController', function ($uibModalInstance, url, dni, firstName, lastName) {
paw.controller('ResetPasswordModalInstanceController', function ($uibModalInstance, dni, firstName, lastName) {
this.dni = dni;
this.firstName = firstName;
this.lastName = lastName;

this.ok = function () {
$uibModalInstance.close(url);
$uibModalInstance.close(dni);
};

this.cancel = function () {
$uibModalInstance.dismiss('Reset Password modal dismissed at: ' + new Date());
};
});

function getResolve(url, dni, firstName, lastName) {
function getResolve(dni, firstName, lastName) {
return {
url: function () {
return url;
},
dni: function () {
return dni;
},
Expand Down
1 change: 1 addition & 0 deletions app/scripts/directives/navbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ function(paw) {

scope.logout = function() {
navDataService.remove('user');
navDataService.remove('subSidebar');
Authentication.logout();
Paths.get().login().go();
};
Expand Down
26 changes: 16 additions & 10 deletions app/scripts/directives/sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,29 +26,40 @@ define(
if (_this.user !== undefined) {
if (_this.user.authorities.admins) {
_this.sidebar.admins = sidebarAdmins();
_this.sidebar.admins.actions.inscriptions = {
enabled: _this.user.authorities.disableInscriptions
};
}
if (_this.user.authorities.students) {
_this.sidebar.students = sidebarStudents();
}
if (_this.user.authorities.courses) {
_this.sidebar.courses = sidebarCourses();
}
} else {
_this.sidebar = {};
}
};
navDataService.registerObserverCallback('user', userUpdateCallback);
userUpdateCallback();

// handle inscription enable/disable changes
var inscriptionsEnabledCallback = function() {
var inscriptionsEnabled = navDataService.get('inscriptionsEnabled');
if (_this.user) {
_this.user.authorities.viewInscriptions = inscriptionsEnabled;
_this.user.authorities.addInscription = inscriptionsEnabled;
_this.user.authorities.deleteInscription = inscriptionsEnabled;
if (_this.user.admin) {
_this.user.authorities.disableInscriptions = inscriptionsEnabled;
}
}
if (_this.sidebar.admins) {
_this.sidebar.admins.actions.inscriptions.enabled =
navDataService.get('inscriptionsEnabled');
_this.sidebar.admins.actions.inscriptions.enabled = inscriptionsEnabled;
}
};
navDataService.registerObserverCallback('inscriptionsEnabled', inscriptionsEnabledCallback);

// this info should be filled with an API call to /courses/inscriptions (or similar)
navDataService.set('inscriptionsEnabled', true);
inscriptionsEnabledCallback();

// handle subSidebar changes
var subSidebarCallback = function() {
Expand Down Expand Up @@ -97,11 +108,6 @@ define(
},
new: {
path: Paths.get().admins().new().path
},
inscriptions: {
enabled: true,
// +++xremove
path: '/courses/inscriptions'
}
}
};
Expand Down
4 changes: 3 additions & 1 deletion app/scripts/i18n/translations.es.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ define([], function() {
i18nUnenrollSuccess: 'Se ha eliminado la inscripción',
i18nFormErrors: 'Hay errores en los datos ingresados',
i18nSuccess: '¡Éxito! - ',
i18nError: '¡Error! - '
i18nError: '¡Error! - ',
i18nPasswordResetSuccess: 'La contraseña ha sido reseteada exitosamente',
i18nInvalidUsernameOrPassword: 'Usuario y/o contraseña incorrecta'
};
});
Loading

0 comments on commit 433471b

Please sign in to comment.