issues #432 and #408 fixed

parent 080284e2
......@@ -273,6 +273,7 @@
"new_instruction": "New instruction",
"new_method": "New method",
"new_objective": "New objective",
"new_grid": "New grid",
"new_grid_with_categories": "Create grid with categories",
"new_grid_without_categories": "Create grid without categories",
"new_session": "New session",
......
......@@ -272,6 +272,7 @@
"new_instruction": "Nueva instrucción",
"new_method": "Nuevo método",
"new_objective": "Nuevo objetivo",
"new_grid": "Nuevo tablero",
"new_grid_with_categories": "Crear escena con categorías",
"new_grid_without_categories": "Crear escena sin categorías",
"new_session": "Nueva sesión",
......
......@@ -250,3 +250,42 @@ dashboardDirectives.directive('popoveraddpicto', function() {
}
}
});
// for assigning a class within ng-options
dashboardDirectives.directive('optionsClass', function ($parse) {
return {
require: 'select',
link: function(scope, elem, attrs, ngSelect) {
// get the source for the items array that populates the select.
var pattern = /.* in ([\w]+) .*/g;
var optionsSourceStr = pattern.exec(attrs.ngOptions)[1],
// use $parse to get a function from the options-class attribute
// that you can use to evaluate later.
getOptionsClass = $parse(attrs.optionsClass);
scope.$watch(optionsSourceStr, function(items) {
// when the options source changes loop through its items.
angular.forEach(items, function(item, index) {
// evaluate against the item to get a mapping object for
// for your classes.
var classes = getOptionsClass(item),
// also get the option you're going to need. This can be found
// by looking for the option with the appropriate index in the
// value attribute.
option = elem.find('option[value=' + item.id + ']');
// now loop through the key/value pairs in the mapping object
// and apply the classes that evaluated to be truthy.
angular.forEach(classes, function(add, className) {
if (add) {
angular.element(option).addClass(className);
} else {
angular.element(option).removeClass(className);
}
});
});
});
}
};
});
......@@ -18,7 +18,8 @@ dashboardControllers.controller('StudentCollectionsCtrl', function StudentCollec
$anchorScroll,
$modal,
$translate,
ngToast) {
ngToast,
$timeout) {
$scope.emptyStudentPicto = {
id: null,
......@@ -42,74 +43,21 @@ dashboardControllers.controller('StudentCollectionsCtrl', function StudentCollec
$scope.mainGrid = null;
$scope.loadingPictos = true;
$scope.viewingGrid = {};
$scope.gridsList = null;
$scope.gridsList = [];
$scope.newGridName = "";
$scope.breadcrumbs = [];
// function to make category colores brighter
$scope.shadeColor = function (color, percent) {
if (!color)
return;
var f=parseInt(color.slice(1),16),t=percent<0?0:255,p=percent<0?percent*-1:percent,R=f>>16,G=f>>8&0x00FF,B=f&0x0000FF;
return "#"+(0x1000000+(Math.round((t-R)*p)+R)*0x10000+(Math.round((t-G)*p)+G)*0x100+(Math.round((t-B)*p)+B)).toString(16).slice(1);
};
/*
* Generates the grid of pictos with empty ones
*/
function generateGrid() {
var i;
var j;
var gridWidth = 10;
var gridHeight = 5;
var grid = [];
for (i = 0; i < gridHeight; i++) {
grid[i] = [];
for (j = 0; j < gridWidth; j++) {
grid[i][j] = $scope.emptyStudentPicto;
}
}
return grid;
}
/*
* Places a picto in the grid
*/
function placePicto(picto) {
var positionX = picto.attributes.coord_x;
var positionY = picto.attributes.coord_y;
// Fill with grid (if not done before)
$scope.mainGrid = $scope.mainGrid || generateGrid();
if (positionX !== null && positionY !== null) {
$scope.mainGrid[positionX][positionY] = picto;
}
};
/***************************************************************************
* GRIDS MANAGEMENT
********************************/
/**
* get and show active grid
*/
$scope.showActiveGrid = function (grid) {
$scope.loadingPictos = true;
$scope.mainGrid = $scope.mainGrid || generateGrid();
$http.get(config.backend + '/stu/' + $scope.studentData.id + '/activeGrid')
.success(function (activeGrid) {
activeGrid.name = $translate.instant(activeGrid.name);
activeGrid.pictos.forEach(placePicto);
$scope.viewingGrid = activeGrid;
$scope.loadingPictos = false;
$scope.breadcrumbs = [{id:activeGrid.id,name:activeGrid.name}];
})
.error(function () {
$translate('error_loading_grid').then(function (translation) {
ngToast.danger({ content: translation });
});
});
$scope.showActiveGrid = function () {
var active = $scope.gridsList.find((x) => x.active);
$scope.showGrid(active.id, 'menu');
$scope.viewingGrid = active;
};
/**
......@@ -131,7 +79,6 @@ dashboardControllers.controller('StudentCollectionsCtrl', function StudentCollec
grid.name = $translate.instant(grid.name);
grid.pictos.forEach(placePicto);
$scope.viewingGrid = grid;
$scope.loadingPictos = false;
// Breadcrumbs update
......@@ -150,29 +97,34 @@ dashboardControllers.controller('StudentCollectionsCtrl', function StudentCollec
// Add new element
$scope.breadcrumbs.push({id:grid.id,name:grid.name});
}
})
.error(function () {
$translate('error_loading_grid').then(function (translation) {
ngToast.danger({ content: translation });
});
ngToast.danger($translate.instant('error_loading_grid'));
});
};
/**
* Load the grid list
*/
$scope.loadGridsList = function () {
$scope.loadGridsListNoScope = function (callback) {
$http.get(config.backend + '/stu/' + $scope.studentData.id +'/grids')
.success(function (grids) {
grids.map((sce) => {sce.name = $translate.instant(sce.name); return sce});
$scope.gridsList = grids;
//setTimeout(function () { $scope.$apply(); });
grids.map((g) => {
g.name = $translate.instant(g.name);
return g;
});
if (callback) callback(grids);
})
.error(function () {
$translate('error_loading_grids').then(function (translation) {
ngToast.danger({ content: translation });
});
ngToast.danger($translate.instant('error_loading_grids'));
if (callback) callback(null);
});
};
$scope.loadGridsList = function (callback) {
$scope.loadGridsListNoScope((grids) => {
$scope.gridsList = grids;
if (callback) callback(grids);
});
};
......@@ -196,15 +148,9 @@ dashboardControllers.controller('StudentCollectionsCtrl', function StudentCollec
action: 'delete',
grid: {id:grid.id}
}, function () {});
//Reload active grid
if(grid == $scope.viewingGrid){
$scope.loadGridsList(() => {
$scope.showActiveGrid();
}
//Reload grids list
$scope.loadGridsList();
});
ngToast.success($translate.instant('grid_deleted'));
}).error(function () {
......@@ -277,13 +223,141 @@ dashboardControllers.controller('StudentCollectionsCtrl', function StudentCollec
}, function () {});
ngToast.success($translate.instant('grid_duplicated'));
$scope.loadGridsList();
$scope.loadGridsList(() => {
$scope.showGrid(newGrid.id, 'menu');
});
}).error(function () {});
};
/**
* Modal window to open grid color config
*/
$scope.open_grid_color = function (grid) {
var modalInstance = $modal.open({
animation: true,
templateUrl: 'modules/student/views/gridconfig.html',
controller: 'GridConfigCtrl',
size: 'md',
resolve: { // Passing data to the controller of the window
gridColor: function () {
return $scope.viewingGrid.color;
},
}
});
modalInstance.result.then(function (color) {
$scope.viewingGrid.color = color;
$http.put(config.backend + '/grid/' + $scope.viewingGrid.id + '/stu/' + $scope.studentData.id, {
color: $scope.viewingGrid.color
})
.success(function (stu) {
io.socket.post('/stu/config', {
action: 'update',
attributes: stu
}, function () {});
ngToast.success($translate.instant('grid_updated'));
}).error(function () {});
});
};
/**
* Modal window to create grids
*/
$scope.open_new_grid = function () {
var modalInstance = $modal.open({
animation: true,
templateUrl: 'modules/student/views/newgrid.html',
controller: 'NewGridCtrl',
size: 'md',
resolve: { }
});
// Returned data from the modal window
modalInstance.result.then(function (name) {
if(!name)
return;
$http.post(config.backend + '/grid/stu/' + $scope.studentData.id, {
name: name,
id_sup: $rootScope.user.id,
id_stu: $scope.studentData.id
})
.success(function (grid) {
var data = {
name: grid.name,
active: false,
student: grid.student,
supervisor: grid.supervisor
};
io.socket.post('/grid', {
action: 'add',
grid: data
}, function () {});
ngToast.success($translate.instant('grid_added'));
$scope.loadGridsList(() => {$scope.showGrid(grid.id, 'menu')});
}).error(function () {});
});
};
/***************************************************************************
* PICTOS MANAGEMENT
********************************/
// function to make category colores brighter
$scope.shadeColor = function (color, percent) {
if (!color)
return;
var f=parseInt(color.slice(1),16),t=percent<0?0:255,p=percent<0?percent*-1:percent,R=f>>16,G=f>>8&0x00FF,B=f&0x0000FF;
return "#"+(0x1000000+(Math.round((t-R)*p)+R)*0x10000+(Math.round((t-G)*p)+G)*0x100+(Math.round((t-B)*p)+B)).toString(16).slice(1);
};
/*
* Generates the grid of pictos with empty ones
*/
function generateGrid() {
var i;
var j;
var gridWidth = 10;
var gridHeight = 5;
var grid = [];
for (i = 0; i < gridHeight; i++) {
grid[i] = [];
for (j = 0; j < gridWidth; j++) {
grid[i][j] = $scope.emptyStudentPicto;
}
}
return grid;
}
/*
* Places a picto in the grid
*/
function placePicto(picto) {
var positionX = picto.attributes.coord_x;
var positionY = picto.attributes.coord_y;
// Fill with grid (if not done before)
$scope.mainGrid = $scope.mainGrid || generateGrid();
if (positionX !== null && positionY !== null) {
$scope.mainGrid[positionX][positionY] = picto;
}
};
/**
* Delete picto
*/
$scope.deletePicto = function (studentPicto) {
......@@ -449,9 +523,9 @@ dashboardControllers.controller('StudentCollectionsCtrl', function StudentCollec
})
.error(function (err) {
if (err.code && err.code == 1) // codes are in sails/config/pictogram.js
ngToast.danger({ content: $translate.instant('error_duplicated_picto') });
ngToast.danger($translate.instant('error_duplicated_picto'));
else
ngToast.danger({ content: $translate.instant('error_adding_picto') });
ngToast.danger($translate.instant('error_adding_picto'));
});
});
};
......@@ -520,97 +594,17 @@ dashboardControllers.controller('StudentCollectionsCtrl', function StudentCollec
});
};
/**
* Modal window to open grid color config
*/
$scope.open_grid_color = function (grid) {
var modalInstance = $modal.open({
animation: true,
templateUrl: 'modules/student/views/gridconfig.html',
controller: 'GridConfigCtrl',
size: 'md',
resolve: { // Passing data to the controller of the window
gridColor: function () {
return $scope.viewingGrid.color;
},
}
});
modalInstance.result.then(function (color) {
$scope.viewingGrid.color = color;
$http.put(config.backend + '/grid/' + $scope.viewingGrid.id + '/stu/' + $scope.studentData.id, {
color: $scope.viewingGrid.color
})
.success(function (stu) {
io.socket.post('/stu/config', {
action: 'update',
attributes: stu
}, function () {});
ngToast.success($translate.instant('grid_updated'));
}).error(function () {});
});
};
/**
* Modal window to create grids
*/
$scope.open_new_grid = function () {
var modalInstance = $modal.open({
animation: true,
templateUrl: 'modules/student/views/newgrid.html',
controller: 'NewGridCtrl',
size: 'md',
resolve: { }
});
// Returned data from the modal window
modalInstance.result.then(function (name) {
if(!name)
return;
$http.post(config.backend + '/grid/stu/' + $scope.studentData.id, {
name: name,
id_sup: $rootScope.user.id,
id_stu: $scope.studentData.id
})
.success(function (grid) {
var data = {
name: grid.name,
active: false,
student: grid.student,
supervisor: grid.supervisor
};
io.socket.post('/grid', {
action: 'add',
grid: data
}, function () {});
ngToast.success($translate.instant('grid_added'));
$scope.loadGridsList();
$scope.showGrid(grid.id, 'menu');
}).error(function () {});
});
};
/***************************************************************************
* WEBSOCKETS
*********************************/
// Add new listener to the event
io.socket.off('vocabulary');
io.socket.on('vocabulary', function (data) {
if(data.attributes.id_grid == $scope.viewingGrid.id){
//Reload grid
$translate('reload_grid').then(function (translation) {
ngToast.success({ content: translation });
});
$scope.showGrid(data.attributes.id_grid);
ngToast.success($translate.instant('reload_grid'));
$scope.showGrid(data.attributes.id_grid, 'menu');
}
$scope.$apply();
});
......@@ -620,16 +614,12 @@ dashboardControllers.controller('StudentCollectionsCtrl', function StudentCollec
io.socket.on('grid', function (data) {
if(data.action == "delete" && data.grid.id == $scope.viewingGrid.id){
//Grid deleted
$translate('grid_deleted').then(function (translation) {
ngToast.success({ content: translation });
});
ngToast.success($translate.instant('grid_deleted'));
$scope.showActiveGrid();
}else if(data.action == "update" && data.grid.id == $scope.viewingGrid.id){
$translate('grid_updated').then(function (translation) {
ngToast.success({ content: translation });
});
$scope.showGrid(data.grid.id);
} else if(data.action == "update" && data.grid.id == $scope.viewingGrid.id){
ngToast.success($translate.instant('grid_updated'));
$scope.showGrid(data.grid.id, 'menu');
}
$scope.loadGridsList();
$scope.$apply();
......@@ -643,7 +633,14 @@ dashboardControllers.controller('StudentCollectionsCtrl', function StudentCollec
}
);
// Load pictos
$scope.showActiveGrid();
$scope.loadGridsList();
/***************************************************************************
* INITIALIZATION
*********************************/
$scope.loadGridsListNoScope((grids) => {
$scope.viewingGrid = grids.find((x) => x.active);
$scope.gridsList = grids;
$scope.showActiveGrid();
});
});
......@@ -122,11 +122,7 @@
</div>
<div class="form-group row">
<button type="button" class="btn btn-default" ng-click="open_grid_color(viewingGrid)" style="min-width:9.25em;">{{ 'setup' | translate }}</button>
</div>
<div class="form-group row">
<button type="button" class="btn btn-success" ng-click="open_new_grid()" aria-expanded="false"><i class="fa fa-plus" aria-hidden="true"></i></button>
<button type="button" class="btn btn-primary" ng-click="open_grid_color(viewingGrid)" aria-expanded="false" title="{{ 'setup' | translate }}"><span class="glyphicon glyphicon-cog" aria-hidden="true"></span></button>
<button type="button" class="btn btn-primary" ng-click="copy_grid()" title="{{ 'duplicate' | translate }}"><i class="fa fa-files-o" aria-hidden="true"></i></button>
<button type="button" class="btn btn-danger" ng-click="delete_grid(viewingGrid)" title="{{ 'delete' | translate }}"><i class="fa fa-trash" aria-hidden="true"></i></button>
</div>
......@@ -135,19 +131,12 @@
<label class="grid-panel-head">{{ 'show_grids' | translate }}</label>
<div class="form-group row">
<select class="grid-panel-select" ng-model="viewingGrid.id" ng-change="showGrid(viewingGrid.id,'menu')" size="7">
<option value="{{grid.id}}" ng-repeat="grid in gridsList | orderBy: 'name' track by $index" ng-selected="grid.id == viewingGrid.id" ng-class="{'grid-panel-select-optionactive': grid.active}">
{{ grid.name }}
</option>
</select>
<select ng-options="grid as grid.name for grid in gridsList | orderBy: 'name' track by grid.id" ng-model="viewingGrid" ng-change="showGrid(viewingGrid.id,'menu')" size="7" options-class="{'grid-panel-select-optionactive': active, 'grid-panel-select-optioninactive': !active}"></select>
</div>
<!--<div class="list-group">
<a class="list-group-item" ng-repeat="grid in gridsList track by $index" ng-click="showGrid(grid.id,false)" ng-class="(grid.id == viewingGrid.id) ? 'active' : ''">
<i class="fa fa-star" aria-hidden="true" ng-if="grid.active"></i> {{ grid.name }}
</a>
</div>-->
<div class="form-group row">
<button type="button" class="btn btn-success" ng-click="open_new_grid()" style="min-width:9.25em;"><i class="fa fa-plus" aria-hidden="true"></i> {{ 'new_grid' | translate }}</button>
</div>
</div>
......
......@@ -1151,6 +1151,9 @@ input.editable.grid-name {
.grid-panel-select-optionactive{
background-color:#c5e4c5;
}
.grid-panel-select-optioninactive{
background-color: #eeffee;/*transparent;*/
}
.grid-panel-select-optionselected{
background-color:#c5e4c5;
}
......
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