Skip to content

Commit

Permalink
Created Students Update View (#67)
Browse files Browse the repository at this point in the history
* Add students edit view

- Finished Students Update View
- Add test
- Renamed StudentsUpdateCtrl to StudentsEditCtrl
- Update styles
  - Improve responsive style
    - Clone show style
  - Align texts
  - Style buttons
- Add angular-messages dependency for form errors
- Add form errors view and style
  - Add form error messages to all required fields
- Add toy update and cancel form functions
  - Add form validations trigger on submission
  - Add redirect after successful update
  - Add return to previous window location when cancel
- Add new test cases
  • Loading branch information
MatiasMercado committed Jan 31, 2017
1 parent 218be46 commit 2af1fc0
Show file tree
Hide file tree
Showing 20 changed files with 559 additions and 51 deletions.
9 changes: 5 additions & 4 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,11 @@ module.exports = function (grunt) { // eslint-disable-line strict
}
},
watch: {
bower: {
files: ['bower.json'],
tasks: ['wiredep:serve']
},
// commented as it may introduce linter errors on files
// bower: {
// files: ['bower.json'],
// tasks: ['wiredep:serve']
// },
js: {
files: ['<%= yeoman.app %>/scripts/**/*.js'],
tasks: ['newer:eslint:all'],
Expand Down
8 changes: 7 additions & 1 deletion app/scripts/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ require.config({
'angular-material': '../../bower_components/angular-material/angular-material',
'angular-aria': '../../bower_components/angular-aria/angular-aria',
lodash: '../../bower_components/lodash/dist/lodash',
restangular: '../../bower_components/restangular/dist/restangular'
restangular: '../../bower_components/restangular/dist/restangular',
'angular-messages': '../../bower_components/angular-messages/angular-messages'
},
shim: {
angular: {
Expand Down Expand Up @@ -102,6 +103,11 @@ require.config({
'angular',
'lodash'
]
},
'angular-messages': {
deps: [
'angular'
]
}
},
packages: [
Expand Down
47 changes: 47 additions & 0 deletions app/scripts/controllers/students/StudentsEditCtrl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
'use strict';

define(['paw'], function(paw) {
paw.controller('StudentsEditCtrl', [
'$routeParams',
'$log',
'$window',
'$location',
function($routeParams, $log, $window, $location) {

var _this = this;

var docket = $routeParams.docket;

this.student = {
docket: '55019',
firstName: 'Matías',
lastName: 'Mercado',
email: 'mmercado@itba.edu.ar',
genre: 'Masculino',
dni: '38917403',
birthday: '1995-05-04',
address: {
country: 'Argentina',
city: 'Buenos Aires',
neighborhood: 'Almagro',
number: '682',
street: 'Corrientes',
floor: '2',
door: 'A',
telephone: '1544683390',
zipCode: '1100'
}
};

this.editedStudent = angular.copy(this.student);

this.cancel = function() {
$window.history.back();
};

this.update = function(editedStudent) {
$log.info('POST /students/' + docket + ' ' + JSON.stringify(editedStudent));
$location.path('/students/' + docket);
};
}]);
});
50 changes: 32 additions & 18 deletions app/scripts/i18n/translations.es.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,36 +50,50 @@ define([], function() {
i18nCourseDelete: 'Eliminar',

// Tables common headers
i18Actions: 'Acciones',
i18nActions: 'Acciones',

// User show
// User Update
i18nRequiredFields: 'Campos Obligatorios',
i18nRequiredIcon: '*',
i18nMale: 'Masculino',
i18nFemale: 'Femenino',
i18nBirthdayPlaceholder: 'yyyy-mm-dd',
i18nButtonSaveChanges: 'Guardar Cambios',
i18nButtonCancel: 'Cancelar',

// User Show
i18nStudents: 'Alumnos',
i18nProfile: 'Perfil',
i18nDni: 'DNI',
i18Docket: 'Legajo',
i18nDocket: 'Legajo',
i18nFirstName: 'Nombre',
i18nLastName: 'Apellido',
i18Birthday: 'Fecha de nacimiento',
i18Email: 'Email',
i18Genre: 'Género',
i18Telephone: 'Teléfono',
i18Country: 'País',
i18City: 'Ciudad',
i18Neighborhood: 'Localidad',
i18Street: 'Calle',
i18Number: 'Altura',
i18Floor: 'Piso nro.',
i18Door: 'Departamento',
i18ZipCode: 'Código postal',
i18nBirthday: 'Fecha de Nacimiento',
i18nEmail: 'Email',
i18nGenre: 'Género',
i18nTelephone: 'Teléfono',
i18nCountry: 'País',
i18nCity: 'Ciudad',
i18nNeighborhood: 'Localidad',
i18nStreet: 'Calle',
i18nNumber: 'Altura',
i18nFloor: 'Piso Nro.',
i18nDoor: 'Dpto.',
i18nZipCode: 'Cód. Postal',

//
i18nId: 'Código',
i18nName: 'Nombre',

// Search filters
i18SearchButton: 'Buscar',
i18ResetButton: 'Resetear',
i18NoStudentsFound: 'No se encontraron alumnos'
i18nSearchButton: 'Buscar',
i18nResetButton: 'Resetear',
i18nNoStudentsFound: 'No se encontraron alumnos',

// Form errors
i18nRequiredField: 'Este campo es requerido',
i18nLengthPrefix: 'Este campo debe tener entre',
i18nLengthAnd: 'y',
i18nLengthSuffix: 'caracteres.'
};
});
4 changes: 3 additions & 1 deletion app/scripts/paw.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ define(['routes',
'angular-bootstrap',
'jquery-mousewheel',
'angular-material',
'angular-aria'],
'angular-aria',
'angular-messages'],
function(config, dependencyResolverFor, i18n) {
var paw = angular.module('paw', [
'ngRoute',
'ngCookies',
'ngAnimate',
'ngMaterial',
'ngMessages',
'ui.bootstrap',
'restangular',
'pascalprecht.translate'
Expand Down
5 changes: 5 additions & 0 deletions app/scripts/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ define([], function() {
templateUrl: 'views/students/show.html',
controller: 'StudentsShowCtrl',
relativePath: '/students'
},
'/students/:docket/edit': {
templateUrl: 'views/students/edit.html',
controller: 'StudentsEditCtrl',
relativePath: '/students'
}
/* ===== yeoman hook ===== */
/* Do not remove these commented lines! Needed for auto-generation */
Expand Down
99 changes: 99 additions & 0 deletions app/specs/controllers/students/StudentsEditCrtl.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// disable max-nested-callbacks linter for this test
// it is good to have a good separation of contexts inside tests

/* eslint-disable max-nested-callbacks */

'use strict';

define(['paw',
'angular-mocks',
'controllers/students/StudentsEditCtrl'],
function() {
describe('Students Update Ctrl', function() {
beforeEach(module('paw'));

// Hardcoded data until Service call is tested
var expectedStudent = {
docket: '55019',
firstName: 'Matías',
lastName: 'Mercado',
email: 'mmercado@itba.edu.ar',
genre: 'Masculino',
dni: '38917403',
birthday: '1995-05-04',
address: {
country: 'Argentina',
city: 'Buenos Aires',
neighborhood: 'Almagro',
number: '682',
street: 'Corrientes',
floor: '2',
door: 'A',
telephone: '1544683390',
zipCode: '1100'
}
};
var docket = 123;

var $controller, $rootScope, $log, $window, $location, controller;

var expectedDocket = {
docket: docket
};

beforeEach(inject(
function(_$controller_, _$rootScope_, _$log_, _$window_, _$location_) {
$controller = _$controller_;
$rootScope = _$rootScope_;
$log = _$log_;
spyOn($log, 'info');
$window = _$window_;
spyOn($window.history, 'back');
$location = _$location_;
spyOn($location, 'path');
controller = $controller('StudentsEditCtrl', {
$routeParams: expectedDocket,
$log: $log,
$window: $window,
$location: $location
});
}));

it('correctly fetch the student', function() {
expect(controller.student).toEqual(expectedStudent);
});

it('creates a copy of the fetched student', function() {
expect(controller.editedStudent).toEqual(expectedStudent);
});

describe('when calling the cancel function', function() {
beforeEach(function() {
controller.cancel();
});

it('is expected to go back on window history', function() {
expect($window.history.back).toHaveBeenCalled();
});
});

describe('when calling the update function', function() {
var editedStudent, expectedLog;
beforeEach(function() {
editedStudent = expectedStudent;
editedStudent.firstName = 'Other name';
controller.update(editedStudent);

expectedLog = 'POST /students/' + docket + ' ' + JSON.stringify(editedStudent);
});

it('is expected to correctly log the post', function() {
expect($log.info).toHaveBeenCalledWith(expectedLog);
});

it('is expected to redirect to student show view', function() {
expect($location.path).toHaveBeenCalledWith('/students/' + docket);
});
});
});
});
6 changes: 6 additions & 0 deletions app/specs/test-main.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ require.config({
'angular-aria': '../bower_components/angular-aria/angular-aria',
lodash: '../bower_components/lodash/dist/lodash',
restangular: '../bower_components/restangular/dist/restangular',
'angular-messages': '../bower_components/angular-messages/angular-messages',

// all directives templates should go here and on shim section
'backdrop-template': '../views/directives/backdrop.html',
Expand Down Expand Up @@ -135,6 +136,11 @@ require.config({
'lodash'
]
},
'angular-messages': {
deps: [
'angular'
]
},
// all directives templates should be declared as follows
'backdrop-template': {
deps: [
Expand Down
2 changes: 2 additions & 0 deletions app/styles/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ $fa-font-path: '../bower_components/font-awesome/fonts';
@import 'modules/common';
@import 'modules/tables';
@import 'modules/filters';
@import 'modules/forms';
@import 'directives/navbar';
@import 'directives/sidebar';
@import 'directives/backdrop';
@import 'partials/index';
@import 'partials/home';
@import 'partials/students/show';
@import 'partials/students/edit';
1 change: 0 additions & 1 deletion app/styles/modules/_filters.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
.own-input-group {
width: 100%;
display: flex;
align-items: center;
flex-wrap: wrap;
justify-content: center;

Expand Down
48 changes: 48 additions & 0 deletions app/styles/modules/_forms.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
@import 'modules/variables/importer';

.form-errors {
color: $persian-red;
margin-top: -10px;
}

input.ng-invalid.ng-touched {
border-color: $persian-red;
}

.form-input-field {
display: block;
width: 100%;
height: 35px;
padding: 6px 12px;
margin: 0 0 15px;
background-color: $white;
background-image: none;
border: 1px solid $silver;
border-radius: 0;
transition: border-color ease-in-out 0.15s;


&:focus {
border-color: $mine-shaft;
outline: none;
}
}

.required-fields {
padding: 0 5px 15px;
}

.buttons-container {
display: flex;
justify-content: space-between;
width: 100%;
flex-wrap: wrap;

.btn {
min-width: 150px;
width: 40%;
max-width: 300px;
height: 35px;
margin: 5px;
}
}
Loading

0 comments on commit 2af1fc0

Please sign in to comment.