Author: obruce Date: 2014-08-04 16:28:50 +0200 (Mon, 04 Aug 2014) New Revision: 3025 Url: http://forge.chorem.org/projects/jtimer/repository/revisions/3025 Log: Report: changement dans l'interface Modified: branches/ng-jtimer/src/main/webapp/css/app.css branches/ng-jtimer/src/main/webapp/js/controllers.js branches/ng-jtimer/src/main/webapp/js/entities.js branches/ng-jtimer/src/main/webapp/partials/contact.html branches/ng-jtimer/src/main/webapp/partials/reportModal.html branches/ng-jtimer/src/main/webapp/partials/tasks.html Modified: branches/ng-jtimer/src/main/webapp/css/app.css =================================================================== --- branches/ng-jtimer/src/main/webapp/css/app.css 2014-08-04 12:39:19 UTC (rev 3024) +++ branches/ng-jtimer/src/main/webapp/css/app.css 2014-08-04 14:28:50 UTC (rev 3025) @@ -390,6 +390,10 @@ padding-left: 10px; } +.paded-top{ + padding-top: 10px; +} + .divYScrolable { overflow-y:scroll; height:170px; Modified: branches/ng-jtimer/src/main/webapp/js/controllers.js =================================================================== --- branches/ng-jtimer/src/main/webapp/js/controllers.js 2014-08-04 12:39:19 UTC (rev 3024) +++ branches/ng-jtimer/src/main/webapp/js/controllers.js 2014-08-04 14:28:50 UTC (rev 3025) @@ -12,14 +12,12 @@ $scope.taskAccess = $scope.todo.lastTaskAccess; $scope.timeAccess = $scope.todo.lastTimeAccess; - // - $scope.currentTaskAlarmState="no-alarm"; - //interval de conec - var interval = 30000; //TODO: obruce 05-05-14 decider d'un intervalle interessant + var interval = 60000; //TODO: obruce 05-05-14 decider d'un intervalle interessant // periode de delais = 3 periode +1msec var delayAccess = interval + 1; + // {TreeNode} l'arbre regenere automatiquement lorsque les donnees changent $scope.tree; // {Array of Function} les listeners qui surveille l'ajout de nouveau temps, et qui les ajoutes dans l'arbre @@ -31,9 +29,6 @@ // {Task} la tache en cours de timing $scope.currentTask = null; - // {Array of TaskId} la tache en cours de timing - $scope.activeTask = []; - // {Date in millis} le temps pour la tache en cours de timing $scope.currentTaskDate = null; // {String} le filtre d'affichage des noeuds (permet la recherche d'un noeud) @@ -68,6 +63,38 @@ } }; + var notifyUser=function (msg) { + + // Let's check if the browser supports notifications + if (!("Notification" in window)) { + alert("This browser does not support desktop notification"); + + }else if (Notification.permission === "granted") { + var notification = new Notification( + "Notification", { + body: msg, + icon: "http://www.gizmodo.fr/wp-content/uploads/2013/05/Coin-coin.png" + + }); + + }else if (Notification.permission !== 'denied') { + Notification.requestPermission(function (permission) { + if(!('permission' in Notification)) { + Notification.permission = "granted"; + } + + if (permission === "granted") { + var notification = new Notification( + "Notification", { + body: msg, + icon: "http://www.gizmodo.fr/wp-content/uploads/2013/05/Coin-coin.png" + }); + } + }); + } + } + + /** * Methode qui retourne la date de derniere mise a jour(serveur) * @returns moment @@ -189,14 +216,14 @@ var limit = alarm.limitHour*60 + alarm.limitMin; var remaining = alarm.remainingHour*60 + alarm.remainingMin; - res = ((limit-remaining)/limit)*100; + var res = ((limit-remaining)/limit)*100; - if(res < 50 ){ - $scope.currentTaskAlarmState="alarmOk"; - }else if(res < 80){ - $scope.currentTaskAlarmState="alarmInter"; - }else{ - $scope.currentTaskAlarmState="alarmDanger"; + if(res == 50 ){ + //$scope.currentTaskAlarmState="alarmOk"; + notifyUser("You've already spend half of the time on the task"); + }else if(res == 80){ + //$scope.currentTaskAlarmState="alarmInter"; + notifyUser("You only got 20% of your time"); } @@ -205,10 +232,8 @@ if(alarm.type=="Total_Time"){ alarms.splice(index,1); } - $window.alert('Alarme déclenchée: '+alarm.name + '\nVotre alarme va être désactivée.'); + notifyUser("Alarms : "+ alarm.name +" end!"); - $scope.currentTaskAlarmState="no-alarm"; - } index+=1; }); @@ -247,7 +272,7 @@ if((!(item.taskId in $scope.data.tasks)) && item.removed == 0){ console.log( "Un element non present " + item.name + item.modificationDate); - var newTask = new Task( item.name, item.taskId, item.parent); + var newTask = new Task( item.name, item.taskId, item.parent, item.tags,item.description); if(item.parent == "" ){ @@ -314,7 +339,7 @@ console.log("Nouvelle tache" +item.name); - var newTask = new Task( item.name, item.taskId, item.parent); + var newTask = new Task( item.name, item.taskId, item.parent, item.tags,item.description); if(item.parent == "" ){ @@ -515,7 +540,7 @@ //On supprime de la base les taches sotckees pour suppression angular.forEach($scope.todo.stockedDeletedTasks, function(task){ - serverTaskAccess.deleteTask({taskId: task,dispatch:true}, + serverTaskAccess.deleteTask({taskId: task,dispatch:true}, function(){ console.log("delete success" + task); $scope.todo.stockedDeletedTasks.shift(); @@ -524,12 +549,12 @@ console.log("fail"); }); }); + //On ajoute au serveur les taches stockees pour l'ajout angular.forEach($scope.todo.stockedNewTasks, function(task){ //On change la date au dernier acces task['modificationDate']= Date.now(); - serverTaskAccess.create({dispatch:true}, angular.toJson(task), //TODO obruce 04/06/14 dispatch a enlever function(){ console.log("persist task success" + task); @@ -537,21 +562,24 @@ }, function(){ console.log("fail"); - }); + } + ); }); + //On ajoute au serveur les taches stockees pour l'ajout angular.forEach($scope.todo.stockedEditedTasks, function(task){ + //On change la date au dernier acces task["modificationDate"]=Date.now(); - - serverTaskAccess.update({dispatch:true},angular.toJson(task), //TODO + serverTaskAccess.create({dispatch:true}, angular.toJson(task), //TODO obruce 04/06/14 dispatch a enlever function(){ - console.log("update task success" + task); - $scope.todo.stockedEditedTasks.shift(); + console.log("persist task success" + task); + $scope.todo.stockedNewTasks.shift(); }, function(){ console.log("fail"); - }); + }); + }); //On ajoute les nouveaux temps au serveur @@ -559,15 +587,15 @@ angular.forEach(times, function(time){ //On change la date au dernier acces time["modificationDate"]=Date.now(); + serverTimeAccess.create({taskId: task,dispatch:true} , angular.toJson(time), + function(){ + console.log("persist time success" + task); + $scope.todo.stockedNewTimes[task].shift(); + }, + function(){ + console.log("fail"); + }); - serverTimeAccess.create({taskId: task,dispatch:true} , angular.toJson(time), - function(){ - console.log("persist time success" + task); - $scope.todo.stockedNewTimes[task].shift(); - }, - function(){ - console.log("fail"); - }); }); }); @@ -576,37 +604,36 @@ angular.forEach(times, function(time){ time["modificationDate"]=Date.now(); - serverTimeAccess.update({taskId: task,dispatch:true}, angular.toJson(time), - function(){ - console.log("update time success" + task); - $scope.todo.stockedEditedTimes[task].shift(); - }, - function(){ - console.log("fail"); - }); - }); + function(){ + console.log("update time success" + task); + $scope.todo.stockedEditedTimes[task].shift(); + }, + function(){ + console.log("fail"); + }); + }); }); //On supprime de la base les taches sotckees pour suppression angular.forEach($scope.todo.stockedDeletedTimes, function(times,task){ angular.forEach(times, function(time){ + time["modificationDate"]=Date.now(); serverTimeAccess.deleteTime({taskId: time,dispatch:true}, - function(){ - console.log("delete time success" + task); - $scope.todo.stockedDeletedTimes[task].shift(); - }, - function(){ - console.log("fail"); - }); + function(){ + console.log("delete time success" + task); + $scope.todo.stockedDeletedTimes[task].shift(); + }, + function(){ + console.log("fail"); + } + ); }); }); save(); } - - /** * Ajoute une tache root */ @@ -640,7 +667,7 @@ */ $scope.addSubTask = function(node) { var task = node.task; - var newTask = new Task("New task", undefined,task.taskId); + var newTask = new Task("New task", undefined,task.taskId, task.tags); $scope.data.tasks[newTask.taskId] = newTask; //On synchronise la tache creer @@ -666,7 +693,7 @@ */ $scope.removeTask = function(node) { // methode pour faire la suppression recursivement - var removeRecurse = function(tasks) { + var removeRecurse = function(tasks) { angular.forEach(tasks, function(task) { task.remove(); @@ -685,7 +712,6 @@ }); - var children = $scope.getChildren(task); removeRecurse(children); save(); @@ -833,8 +859,14 @@ $scope.saveTask = function(node) { node.edit = null; + serverTaskAccess.update({taskId: node.task.taskId, dispatch:true}, function(){ + console.log("delete success" + task.taskId); + }, + function(){ + console.log("fail"); + $scope.todo.stockedEditedTasks.push(node.task); + }); - $scope.todo.stockedEditedTasks.push(node.task); save(); }; @@ -851,8 +883,17 @@ var taskTime = $scope.getRecentTaskTime($scope.currentTask); taskTime.addTime(now - $scope.currentTaskDate); - if(!$scope.todo.stockedNewTimes[task.taskId]){$scope.todo.stockedNewTimes[task.taskId]=[];} - $scope.todo.stockedNewTimes[task.taskId].push(taskTime); + //On pousse la tache + serverTimeAccess.create({taskId: task.taskId,dispatch:true} , angular.toJson(taskTime), + function(){ + console.log("persist time success" + task); + }, + function(){ + console.log("fail"); + if(!$scope.todo.stockedNewTimes[task.taskId]){$scope.todo.stockedNewTimes[task.taskId]=[];} + $scope.todo.stockedNewTimes[task.taskId].push(taskTime); + } + ); } //si ce n'est la la tache courante actuel if ($scope.currentTask !== task) { @@ -1050,6 +1091,7 @@ if ( $scope.online) { updateTasksFromServ(); updateTimesFromServer(); + pushTodoListToServ(); initTasksFromServ(); } @@ -1274,8 +1316,9 @@ */ function ReportModalInstanceCtrl($scope, $modalInstance,$http, $sce, serverReportAccess, tree){ - $scope.modal={radioModel: "Year", showTime : true}; + $scope.modal={radioModel: "Year", showTime : true, tags : false}; $scope.tree = tree; + $scope.tag = { array : [] }; /** @@ -1364,8 +1407,42 @@ }; /** - * + * Method that returns the total time for a task */ + $scope.getTotalPeriodTime = function(node, res, period){ + + angular.forEach(node.children, function(child){ + + //if there is time on the child we add it, else we try to look on the child's child + if($scope.periodTaskData[period][child.task.taskId]){ + res+= $scope.periodTaskData[period][child.task.taskId]; + }else{ + res+= $scope.getTotalPeriodTime(child,0, period); + } + }); + + return res; + }; + + $scope.getTotalForAllPeriod=function(period){ + var res = 0; + + res+=$scope.getTotalPeriodTime(tree, res, period); + + return res; + }; + + $scope.getTotalForAllProject=function(){ + var res = 0; + + res+=$scope.getTotalProjectTime(tree, res); + + return res; + }; + + /** + * Method that return if the task has time or his subtasks + */ $scope.hasSelfOrChildTime= function(collection, node, bool){ if(!bool){ @@ -1383,25 +1460,28 @@ return bool; }; + $scope.hasTags = function(node, array){ + var bool = true; - /** - * Method that returns the total time for a task - */ - $scope.getTotalPeriodTime = function(node, res, period){ + if(array){ - angular.forEach(node.children, function(child){ - - //if there is time on the child we add it, else we try to look on the child's child - if($scope.taskData[period][child.task.taskId]){ - res+= $scope.taskData[period][child.task.taskId]; - }else{ - res+= $scope.getTotalPeriodTime(child,0, period); + for (var i = 0, len = node.task.tags.length; i < len; i++) { + if (!node.task.tags[i] in array) { + bool = false + break; } - }); + } + } - return res; - }; + return bool; + } + $scope.removeTags = function(){ + $scope.tag.array = []; + $scope.generateReport(); + } + + /** * Methode de generation du rapport * @@ -1420,6 +1500,11 @@ $scope.reportedTask = []; $scope.reportWeek = {}; + $scope.taskData={}; + + /** + * Methode qui va reccursivement verifier les taches à repporter + */ var recurseGenerateChildReport = function(child){ // On parcours les data pour maj @@ -1432,15 +1517,17 @@ angular.forEach(tree.children, function(child){recurseGenerateChildReport(child)}); $http({method: "POST", url: "/rest/report", - params:{start_Date : deb, end_Date : end, type : $scope.modal.radioModel}, data : angular.toJson(toReportTask)}) + params:{start_Date : deb, end_Date : end, type : $scope.modal.radioModel}, data : angular.toJson([toReportTask, $scope.tag.array])}) .success(function(data){ if($scope.modal.radioModel=='Project'){ + $scope.taskData = data; + }else{ console.log(data); - $scope.taskData={}; + $scope.periodTaskData={}; angular.forEach(data, function(array,period){ @@ -1463,9 +1550,9 @@ } - $scope.taskData[period]={}; + $scope.periodTaskData[period]={}; angular.forEach(array, function(task){ - $scope.taskData[period][task.taskId]=task.selftime; + $scope.periodTaskData[period][task.taskId]=task.selftime; }); }); } @@ -1677,6 +1764,7 @@ * */ $scope.removeTime = function(ind, item){ + if(!$scope.todo.stockedDeletedTimes[item.taskId]){ $scope.todo.stockedDeletedTimes[item.taskId] = [] }; Modified: branches/ng-jtimer/src/main/webapp/js/entities.js =================================================================== --- branches/ng-jtimer/src/main/webapp/js/entities.js 2014-08-04 12:39:19 UTC (rev 3024) +++ branches/ng-jtimer/src/main/webapp/js/entities.js 2014-08-04 14:28:50 UTC (rev 3025) @@ -404,7 +404,7 @@ * @param {type} parentTaskId l'identifiant de la tache parente * @returns {Task} */ -var Task = function (name,taskId, parentTaskId) { +var Task = function (name,taskId, parentTaskId, parentTags,description) { if(taskId == undefined) { @@ -424,10 +424,10 @@ } this.name = name; - this.description = ""; + this.description = description; this.isReported = true; this.alarms=[]; - this.tags = []; + this.tags = parentTags; this.syncOptions = {}; }; Modified: branches/ng-jtimer/src/main/webapp/partials/contact.html =================================================================== --- branches/ng-jtimer/src/main/webapp/partials/contact.html 2014-08-04 12:39:19 UTC (rev 3024) +++ branches/ng-jtimer/src/main/webapp/partials/contact.html 2014-08-04 14:28:50 UTC (rev 3025) @@ -1 +1 @@ -jtimer-users@listes.chorem.org +jtimer-users@listes.chorem.org \ No newline at end of file Modified: branches/ng-jtimer/src/main/webapp/partials/reportModal.html =================================================================== --- branches/ng-jtimer/src/main/webapp/partials/reportModal.html 2014-08-04 12:39:19 UTC (rev 3024) +++ branches/ng-jtimer/src/main/webapp/partials/reportModal.html 2014-08-04 14:28:50 UTC (rev 3025) @@ -1,5 +1,5 @@ <div> - <h2>Report :</h2> + <h3>Report :</h3> </div> <hr/> @@ -9,7 +9,7 @@ <!-- Datepicker div --> <div style="border:1px solid black; display : inline-block;vertical-align: top;margin-left:1px;margin-right:1px;"> <h4><u>Option :</u></h4> - From : + <span>From :</span> <div style="margin-left:2px;" ng-controller="ReportDatePickerCtrl" class="row"> <div class="col-md-6"> <p class="input-group medium_input"> @@ -64,11 +64,23 @@ <span>Show times </span> <input type="checkbox" ng-model="modal.showTime" /> </div> + <div> + <span>Add tags </span> + <input type="checkbox" ng-model="modal.tags" ng-change="removeTags()"/> + </div> + <div class="tags" ng-show="modal.tags"> + <input class="form-control input-sm" ng-model="tag.array" ng-list> + + <span class="label label-info" ng-repeat="tag in tag.array">{{tag}}</span> + <button class="btn btn-default btn-sm" ng-click="generateReport()">Generate</button> + </div> + + <hr/> <div> - <h4><u>Projet :</u></h4> + <h4><u>Projects :</u></h4> <!--la div de l'arbre--> <div> @@ -110,10 +122,10 @@ <alert type="info" > <span contenteditable="true" ng-if="isGenerated" > - <h4><b>Report :</b></h4> + <div ng-if="modal.radioModel=='Project'"> - + <h4>Projet :</h4> <div> <div class='table'> @@ -140,7 +152,7 @@ </div> - <div class="td" ng-show="$node.task.isRoot()" > + <div class="td" ng-show="$node.task.isRoot() && modal.showTime" > <span class="spacer level{{$level}}"></span> <b> Total : {{getTotalProjectTime($node,0) |time }} </b> @@ -148,46 +160,53 @@ </div> </div> </div> + Total: {{getTotalForAllProject()|time}} </div> </div> <!--Report by week/year/month/day --> <div ng-if="modal.radioModel=='Week' || modal.radioModel=='Year' || modal.radioModel=='Month'|| modal.radioModel=='Day'"> - <div ng-repeat="(period, tasks) in taskData"> - <b> {{modal.radioModel}} : {{period}} </b> + <div ng-repeat="(period, tasks) in periodTaskData"> + <h4> {{modal.radioModel}} : {{period}} </h4> <div class='table'> <div class="tbody" wt-tree-repeat="tree | orderBy:'task.name'" wt-force-open="true"> - <div class="tr" ng-show="hasSelfOrChildTime(taskData[period],$node,false) || ($node.task.isRoot() && getTotalPeriodTime($node,0, period) != 0 ) "> + <div class="tr" ng-show="hasSelfOrChildTime(periodTaskData[period],$node,false) || ($node.task.isRoot() && getTotalPeriodTime($node,0, period) != 0 ) "> - <div class="td" > + <!-- If root task --> + <div class="td paded-top" ng-if="$node.task.isRoot()" > <span class="spacer level{{$level}}"></span> - <b ng-if="$node.task.isRoot()">Projet : {{$node.task.name}}</b> - <span ng-if="!$node.task.isRoot()">{{$node.task.name}} </span> + <b>Projet : {{$node.task.name}}</b> </div > - <div class="td" ng-show="!$node.task.isRoot() && taskData[period][$node.task.taskId] && modal.showTime" > + <div class="td paded-top" ng-show="$node.task.isRoot() && modal.showTime" > <span class="spacer level{{$level}}"></span> - <span>{{tasks[$node.task.taskId] |time }} </span> - + <b>Total : {{getTotalPeriodTime($node,0,period) |time }} </b> </div> - <div class="td" ng-show="$node.task.isRoot()" > + <div class="td" ng-if="!$node.task.isRoot()" > <span class="spacer level{{$level}}"></span> - <b> Total : {{getTotalPeriodTime($node,0,period) |time }} </b> + <span>{{$node.task.name}} </span> + </div > + <div class="td" ng-show="!$node.task.isRoot() && periodTaskData[period][$node.task.taskId] && modal.showTime" > + <span class="spacer level{{$level}}"></span> + <span>{{tasks[$node.task.taskId] |time }} </span> + </div> </div> </div> </div> + Total: {{getTotalForAllPeriod(period)|time}} + <hr/> </div> </div> </span > - <span ng-if="!taskData"> + <span ng-if="!periodTaskData"> No timed task. </span> </alert> @@ -199,6 +218,5 @@ <div class="modal-footer"> - <button class="btn btn-primary" ng-click="generateReport()">Generate</button> <button class="btn btn-primary" ng-click="close()">Close</button> </div> \ No newline at end of file Modified: branches/ng-jtimer/src/main/webapp/partials/tasks.html =================================================================== --- branches/ng-jtimer/src/main/webapp/partials/tasks.html 2014-08-04 12:39:19 UTC (rev 3024) +++ branches/ng-jtimer/src/main/webapp/partials/tasks.html 2014-08-04 14:28:50 UTC (rev 3025) @@ -8,9 +8,10 @@ </span> - <!--Header partie droite --> + <!--Header partie droite--> <span class="right"> - <a class="glyphicon glyphicon-cog" ng-click="reportPopup()">Report </a> + <i class="glyphicon glyphicon-stop color_red" ng-show="currentTask" ng-click="timeTask(currentTask)">Stop </i> + <i class="glyphicon glyphicon-cog" ng-click="reportPopup()">Report </i> <a class="glyphicon glyphicon-plus-sign" ng-click="showMenu = !showMenu"></a> <ul class="dropdown-menu" ng-class="{'menu-show': showMenu}"> @@ -43,7 +44,7 @@ <span class="left">{{currentDate()}}</span> <span class="center"><i class="fa fa-html5"></i> <a>WebTimer</a></span> <!--<span class="right">{{tree.getTime().today |time}} | {{tree.getTime().global | time}}</span>--> - <span class="right">Last update : {{getLastMajDate()}}</span> + <span class="right">jTimer</span> </div> @@ -76,10 +77,7 @@ <i class="glyphicon glyphicon-ban-circle" ng-show="$state=='empty'"></i> <i class="glyphicon glyphicon-plus-sign" ng-click="$toggleState()" ng-show="$state=='close'"></i> <i class="glyphicon glyphicon-minus-sign" ng-click="$toggleState()" ng-show="$state=='open'"></i> - <img ng-class="{'no-alarm' : (currentTaskAlarmState =='no-alarm'), - 'alarmOk': (currentTaskAlarmState =='alarmOk'), - 'alarmInter' : (currentTaskAlarmState =='alarmInter'), - 'alarmDanger': (currentTaskAlarmState =='alarmDanger')}" src="partials/loading_timer.gif" height="20" width="20" ng-show="currentTask == $node.task"> + <img src="partials/loading_timer.gif" height="20" width="20" ng-show="currentTask == $node.task"> </span> @@ -102,6 +100,12 @@ <i class="glyphicon glyphicon-minus"></i> </a> + <a class="btn btn-default btn-xs" + ng-really-message="Voulez vous masquer cette tâche?" + ng-really-click="" ng-show="$node.task != currentTask"> + <i class="glyphicon glyphicon-eye-close"></i> + </a> + <a class="btn btn-default btn-xs" ng-click="optionPopup($node, $node.task.isRoot())"> <i class="glyphicon glyphicon-pencil" ></i> </a>