Skip to content

Commit

Permalink
Add students grades view (#98)
Browse files Browse the repository at this point in the history
- Add POST API integration
- Add flash messages service
  - BodyCtrl is in charge of flash messages usage
- Add handling error service
- Add actions behavior on view
- Show edit course grade if not final taken
- Add edit course grade modal
- Add alert directive
- Add some style to server side errors
  • Loading branch information
MatiasComercio committed Feb 4, 2017
1 parent 3d535bc commit 311e962
Show file tree
Hide file tree
Showing 19 changed files with 459 additions and 11 deletions.
7 changes: 7 additions & 0 deletions app/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@

<!-- dynamic content -->
<div class='container' ng-class="{'sidebar-hidden' : !controller.user}">
<div class='flash-messages' ng-show='controller.flashMessages'>
<xalert ng-repeat='error in controller.flashMessages.errors' msg='{{ error }}' type='danger'>
</xalert>
<xalert ng-repeat='success in controller.flashMessages.successes' msg='{{ success }}' type='success'>
</xalert>
</div>

<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
Expand Down
16 changes: 14 additions & 2 deletions app/scripts/controllers/BodyCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,27 @@ define(
['paw',
'directives/navbar',
'directives/sidebar',
'services/navDataService'],
'directives/alert',
'services/navDataService',
'services/flashMessages'],
function(paw) {
paw.controller('BodyCtrl', ['navDataService', function(navDataService) {
paw.controller('BodyCtrl', ['$rootScope', 'navDataService', 'flashMessages',
function($rootScope, navDataService, flashMessages) {
var _this = this;
var getUser = function() {
_this.user = navDataService.get('user');
};
navDataService.registerObserverCallback('user', getUser);
getUser();

this.flashMessages = {};

$rootScope.$on('$routeChangeStart', function (event, next, current) {
_this.flashMessages = {};
_this.flashMessages.errors = flashMessages.getErrors();
_this.flashMessages.successes = flashMessages.getSuccesses();
flashMessages.clear();
});
}]);
}
);
78 changes: 78 additions & 0 deletions app/scripts/controllers/modals/EditCourseGradeController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
'use strict';

define(['paw', 'services/modalFactory', 'services/Students', 'services/flashMessages'], function(paw) {
paw.controller('EditCourseGradeController',
['modalFactory', '$log', 'Students', '$route', 'flashMessages',
function (modalFactory, $log, Students, $route, flashMessages) {
var modalTemplateUrl = 'views/modals/edit_course_grade.html';
var onSuccess = function(result) {
Students.updateGrade(result.docket, result.gradeId, result.courseId, result.newGrade)
.then(function(response) {
flashMessages.setSuccess('i18nEditSuccess');
$route.reload();
}, function(response) {
flashMessages.setError('i18nFormErrors');
$log.warn('[ERROR] - Response: ' + JSON.stringify(response));
$route.reload();
});
};

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

this.open = function (size, docket, fullName, courseId, courseName, grade, gradeId) {
var resolve = getResolve(docket, fullName, courseId, courseName, grade, gradeId);
modalFactory.create(size, 'EditCourseGradeModalInstanceController', modalTemplateUrl, resolve, onSuccess, onFailure);
};
}]);

paw.controller('EditCourseGradeModalInstanceController',
function($uibModalInstance, docket, fullName, courseId, courseName, grade, gradeId) {
this.docket = docket;
this.fullName = fullName;
this.courseId = courseId;
this.courseName = courseName;
this.grade = grade;
this.gradeId = gradeId;

var _this = this;

this.ok = function () {
$uibModalInstance.close({
docket: docket,
gradeId: gradeId,
courseId: courseId,
newGrade: _this.grade
});
};

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

function getResolve(docket, fullName, courseId, courseName, grade, gradeId) {
return {
docket: function () {
return docket;
},
fullName: function () {
return fullName;
},
courseId: function () {
return courseId;
},
courseName: function () {
return courseName;
},
grade: function () {
return grade;
},
gradeId: function () {
return gradeId;
}
};
};
}
);
34 changes: 34 additions & 0 deletions app/scripts/controllers/students/StudentsGradesCtrl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use strict';
define(
[
'paw',
'services/Students',
'services/Paths',
'controllers/modals/EditCourseGradeController'
], function(paw) {
paw.controller('StudentsGradesCtrl',
['$routeParams',
'Students',
'$log',
'Paths',
function($routeParams, Students, $log, Paths) {
var _this = this;

Students.get($routeParams.docket).then(function(student) {
_this.student = student;
_this.student.getList('grades').then(function(transcript) {
_this.student.transcript = transcript;
});
}, function(response) {
$log.info('Response status: ' + response.status);
if (response.status === 404) {
Paths.get().notFound().go();
}
});

this.getCoursePath = function(courseId) {
return Paths.get().courses({courseId: courseId}).path;
};
}]);
}
);
22 changes: 22 additions & 0 deletions app/scripts/directives/alert.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
'use strict';

define(['paw'], function(paw) {
paw.directive('xalert', function () {
return {
link: link,
restrict: 'E',
scope: {},
bindToController: {
msg: '@',
type: '@'
},
templateUrl: 'views/directives/alert.html',
controller: function() {},
controllerAs: 'controller'
};

function link(scope, element, attrs) {
scope.show = true;
}
});
});
21 changes: 19 additions & 2 deletions app/scripts/i18n/translations.es.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,19 @@ define([], function() {
// Students Inscriptions
i18nEnroll: 'Matricularse',

// Students Grades
i18nCourseGrade: 'Cursada',
i18nFinalGrade: 'Finales',
i18nUpdatedAt: 'Modificado',
i18nNoCoursesOnSga: 'No hay ninguna materia en su plan de carrera',
i18nEditCourseGrade: 'Editar cursada',
i18nCourse: 'Materia',
i18nShowCourse: 'Ver materia',
i18nStudyBeingTaken: 'Cursando',
i18nFullName: 'Nombre y Apellido',
i18nGradeInvalidRange: 'La nota debe ser mayor o igual a 1 y menor o igual a 10',
i18nOneDecimalOnly: 'La nota debe ser un número entero o un número decimal con un sólo decimal. Ejemplos: 10 ; 5.5 ; 3.4',

// Courses Index
i18nCourseId: 'Código',
i18nCourseName: 'Nombre',
Expand Down Expand Up @@ -156,8 +169,12 @@ define([], function() {
i18nRequiredField: 'Este campo es requerido',
i18nLengthPrefix: 'Este campo debe tener entre',
i18nLengthAnd: 'y',
i18nLengthSuffix: 'caracteres.'

i18nLengthSuffix: 'caracteres.',

// Flash messages
i18nEditSuccess: 'La edición ha sido exitosa',
i18nFormErrors: 'Hay errores en los datos ingresados',
i18nSuccess: '¡Éxito! - ',
i18nError: '¡Error! - '
};
});
5 changes: 5 additions & 0 deletions app/scripts/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ define([], function() {
controller: 'StudentsCoursesIndexCtrl',
relativePath: '/students'
},
'/students/:docket/grades': {
templateUrl: 'views/students/grades.html',
controller: 'StudentsGradesCtrl',
relativePath: '/students'
},
'/students/:docket/inscriptions': {
templateUrl: 'views/students/inscriptions.html',
controller: 'StudentsInscriptionsCtrl',
Expand Down
4 changes: 4 additions & 0 deletions app/scripts/services/Paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ define([], function() {
return append('/unauthorized');
};

_this.notFound = function() {
return append('/notFound');
};

// users
_this.admins = function(admin) {
var updated = append('/admins');
Expand Down
30 changes: 28 additions & 2 deletions app/scripts/services/Students.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,19 @@ define(['paw', 'services/AuthenticatedRestangular'], function(paw) {
var rest = AuthenticatedRestangular.withConfig(function(RestangularConfigurer) {
RestangularConfigurer.addResponseInterceptor(
function(data, operation, what, url, response, deferred) {
return operation === 'getList' ? data.students : data;
if (operation === 'getList') {
if (what === 'students') {
return data.students;
}
if (what === 'grades') {
return data.transcript;
}
return data;
} else if (operation === 'post') {
return response;
} else {
return data;
}
}
);
RestangularConfigurer.setRestangularFields({
Expand All @@ -20,9 +32,23 @@ define(['paw', 'services/AuthenticatedRestangular'], function(paw) {
});
});

var subject = rest.all('students');

// add own methods as follows
rest.getList = function() {
return rest.all('students').getList();
return subject.getList();
};

rest.get = function(docket) {
return subject.get(docket);
};

rest.updateGrade = function(docket, gradeId, courseId, newGrade) {
var body = {
courseId: courseId,
grade: newGrade
};
return rest.one('students', docket).one('grades', gradeId).customPOST(body);
};

return rest;
Expand Down
32 changes: 32 additions & 0 deletions app/scripts/services/flashMessages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
'use strict';

define(['paw'], function(paw) {
paw.service('flashMessages', [
function() {
var memory = this;

memory.getErrors = function() {
return memory.errors;
};

memory.setError = function(error) {
memory.errors.push(error);
};

memory.getSuccesses = function() {
return memory.successes;
};

memory.setSuccess = function(success) {
memory.successes.push(success);
};

memory.clear = function() {
memory.errors = [];
memory.successes = [];
};

// initialize errors and successes arrays
memory.clear();
}]);
});
1 change: 1 addition & 0 deletions app/styles/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,4 @@ $fa-font-path: '../bower_components/font-awesome/fonts';
@import 'partials/courses/final_inscriptions_show';
@import 'partials/courses/final_inscriptions_new';
@import 'partials/admins/edit';
@import 'partials/students/grades';
5 changes: 2 additions & 3 deletions app/styles/modules/common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,8 @@ hr {
}

.page-sub-header {
margin: 0 0 15px;
padding-bottom: 15px;
padding-top: 15px;
margin: 0;
padding: 30px 0 15px;
}

.btn {
Expand Down
1 change: 1 addition & 0 deletions app/styles/modules/variables/colors.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ $white: #fff;
$persian-red: #c9302c;
$tropical-rain-forest: #00695C;
$aqua-deep: #004D40;
$bay-of-many: #283593;
2 changes: 1 addition & 1 deletion app/styles/partials/courses/_show.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
.break-words {
display: inline-block;
word-wrap: break-word; /* Internet Explorer 5.5+ */
width: 190; /* width is mandatory to make break-word work on Mozzila */
width: 190px; /* width is mandatory to make break-word work on Mozzila */
}
}
}
Expand Down
Loading

0 comments on commit 311e962

Please sign in to comment.