diff --git a/openslides/agenda/static/js/agenda/csv.js b/openslides/agenda/static/js/agenda/csv.js index 3af602796..807c0dd67 100644 --- a/openslides/agenda/static/js/agenda/csv.js +++ b/openslides/agenda/static/js/agenda/csv.js @@ -5,16 +5,20 @@ angular.module('OpenSlidesApp.agenda.csv', []) .factory('AgendaCsvExport', [ - function () { + 'HumanTimeConverter', + function (HumanTimeConverter) { return function (element, agenda) { var csvRows = [ ['title', 'text', 'duration', 'comment', 'is_hidden'], ]; _.forEach(agenda, function (item) { var row = []; + var duration = item.duration ? HumanTimeConverter.secondsToHumanTime(item.duration*60, + { seconds: 'disabled', + hours: 'enabled' }) : ''; row.push('"' + (item.title || '') + '"'); row.push('"' + (item.text || '') + '"'); - row.push('"' + (item.duration || '') + '"'); + row.push('"' + duration + '"'); row.push('"' + (item.comment || '') + '"'); row.push('"' + (item.is_hidden ? '1' : '') + '"'); csvRows.push(row); diff --git a/openslides/agenda/static/js/agenda/site.js b/openslides/agenda/static/js/agenda/site.js index de8fd82f8..0421eabda 100644 --- a/openslides/agenda/static/js/agenda/site.js +++ b/openslides/agenda/static/js/agenda/site.js @@ -692,30 +692,6 @@ angular.module('OpenSlidesApp.agenda.site', [ } ]) -.factory('AgendaCsvExport', [ - function () { - return function (element, agenda) { - var csvRows = [ - ['title', 'text', 'duration', 'comment', 'is_hidden'], - ]; - _.forEach(agenda, function (item) { - var row = []; - row.push('"' + (item.title || '') + '"'); - row.push('"' + (item.text || '') + '"'); - row.push('"' + (item.duration || '') + '"'); - row.push('"' + (item.comment || '') + '"'); - row.push('"' + (item.is_hidden ? '1' : '') + '"'); - csvRows.push(row); - }); - - var csvString = csvRows.join("%0A"); - element.href = 'data:text/csv;charset=utf-8,' + csvString; - element.download = 'agenda-export.csv'; - element.target = '_blank'; - }; - } -]) - //mark all agenda config strings for translation with Javascript .config([ 'gettext', diff --git a/openslides/core/static/js/core/base.js b/openslides/core/static/js/core/base.js index f45c22e02..a6b2ac8f5 100644 --- a/openslides/core/static/js/core/base.js +++ b/openslides/core/static/js/core/base.js @@ -852,48 +852,105 @@ angular.module('OpenSlidesApp.core', [ } ]) +/* Two functions to convert between time duration in seconds <-> human readable time span. + * E.g. 90 sec <-> 1:30 (min), 3661 sec <-> 1:01:01 (h) + * + * secondsToHumanTime: Expects seconds and give [h*:]mm[:ss]. The minutes part is always given, the hours + * and minutes could be controlled. The default are forced seconds and hours just if it is not 0. + * - seconds ('enabled', 'auto', 'disabled'): Whether to show seconds (Default 'enabled') + * - hours ('enabled', 'auto', 'disabled'): Whether to show hours (Default 'auto') + * + * humanTimeToSeconds: Expects [h*:]m*[:s*] with each part could have a variable length. The parsed time is + * in seconds. Minutes have to be given and hours and seconds are optional. One have to set 'seconds' or + * 'hours' to true toparse these. + * + * params could be an object with the given settings, e.g. {ignoreHours: true} + */ +.factory('HumanTimeConverter', [ + function () { + return { + secondsToHumanTime: function (seconds, params) { + if (!params) { + params = {seconds: 'enabled', hours: 'auto'}; + } + if (!params.seconds) { + params.seconds = 'enabled'; + + } + if (!params.hours) { + params.hours = 'auto'; + } + var time; + // floor returns the largest integer of the absolut value of seconds + var total = Math.floor(Math.abs(seconds)); + var h = Math.floor(total / 3600); + var m = Math.floor(total % 3600 / 60); + var s = Math.floor(total % 60); + // Add leading "0" for double digit values + time = ('0'+m).slice(-2); //minutes + if ((params.seconds == 'auto' && s > 0) || params.seconds == 'enabled') { + s = ('0'+s).slice(-2); + time = time + ':' + s; + } + if ((params.hours == 'auto' && h > 0) || params.hours == 'enabled') { + time = h + ':' + time; + } + if (seconds < 0) { + time = '-'+time; + } + return time; + }, + humanTimeToSeconds: function (data, params) { + if (!params) { + params = {seconds: false, hours: false}; + } + var minLength = 1; + if (params.seconds) { + minLength++; + } + if (params.hours){ + minLength++; + } + + var negative = data.charAt(0) == '-'; + var time = data.split(':'); + data = 0; + if (time.length >= minLength) { + for (var i = 0; i < minLength; i++) { + data = data*60 + (+time[i]); + } + if (!params.seconds) { // the last field was minutes (e.g. h:mm) + data *= 60; + } + if (negative) { + data = -data; + } + } + return data; + }, + }; + } +]) + /* Converts number of seconds into string "h:mm:ss" or "mm:ss" */ .filter('osSecondsToTime', [ - function () { - return function (totalseconds) { - var time; - // floor returns the largest integer of the absolut value of totalseconds - var total = Math.floor(Math.abs(totalseconds)); - var h = Math.floor(total / 3600); - var mm = Math.floor(total % 3600 / 60); - var ss = Math.floor(total % 60); - var zero = "0"; - // Add leading "0" for double digit values - mm = (zero+mm).slice(-2); - ss = (zero+ss).slice(-2); - if (h == "0") - time = mm + ':' + ss; - else - time = h + ":" + mm + ":" + ss; - if (totalseconds < 0) - time = "-"+time; - return time; + 'HumanTimeConverter', + function (HumanTimeConverter) { + return function (seconds) { + return HumanTimeConverter.secondsToHumanTime(seconds); }; } ]) /* Converts number of minutes into string "h:mm" or "hh:mm" */ .filter('osMinutesToTime', [ - function () { - return function (totalminutes) { - var time = ''; - if (totalminutes) { - if (totalminutes < 0) { - time = "-"; - totalminutes = -totalminutes; - } - var hh = Math.floor(totalminutes / 60); - var mm = Math.floor(totalminutes % 60); - // Add leading "0" for double digit values - mm = ("0" + mm).slice(-2); - time += hh + ":" + mm; - } - return time; + 'HumanTimeConverter', + function (HumanTimeConverter) { + return function (minutes) { + return HumanTimeConverter.secondsToHumanTime(minutes*60, + { seconds: 'disabled', + hours: 'enabled' } + ); }; } ]) diff --git a/openslides/core/static/js/core/site.js b/openslides/core/static/js/core/site.js index ff8763ca3..e0b1a33a8 100644 --- a/openslides/core/static/js/core/site.js +++ b/openslides/core/static/js/core/site.js @@ -1338,40 +1338,19 @@ angular.module('OpenSlidesApp.core.site', [ // format time string for model ("s") and view format ("h:mm:ss" or "mm:ss") .directive('minSecFormat', [ - function () { + 'HumanTimeConverter', + function (HumanTimeConverter) { return { require: 'ngModel', link: function(scope, element, attrs, ngModelController) { ngModelController.$parsers.push(function(data) { //convert data from view format (mm:ss) to model format (s) - var time = data.split(':'); - if (time.length > 1) { - data = (+time[0]) * 60 + (+time[1]); - if (data < 0) { - data = "-"+data; - } - } - return data; + return HumanTimeConverter.humanTimeToSeconds(data, {seconds: true}); }); ngModelController.$formatters.push(function(data) { //convert data from model format (s) to view format (mm:ss) - var time; - // floor returns the largest integer of the absolut value of totalseconds - var total = Math.floor(Math.abs(data)); - var mm = Math.floor(total / 60); - var ss = Math.floor(total % 60); - var zero = "0"; - // Add leading "0" for double digit values - if (mm.length < 2) { - mm = (zero+mm).slice(-2); - } - ss = (zero+ss).slice(-2); - time = mm + ':' + ss; - if (data < 0) { - time = "-"+time; - } - return time; + return HumanTimeConverter.secondsToHumanTime(data); }); } }; @@ -1380,38 +1359,22 @@ angular.module('OpenSlidesApp.core.site', [ // format time string for model ("m") and view format ("h:mm" or "hh:mm") .directive('hourMinFormat', [ - function () { + 'HumanTimeConverter', + function (HumanTimeConverter) { return { require: 'ngModel', link: function(scope, element, attrs, ngModelController) { ngModelController.$parsers.push(function(data) { //convert data from view format (hh:mm) to model format (m) - var time = data.split(':'); - if (time.length > 1 && !isNaN(time[0]) && !isNaN(time[1])) { - data = (+time[0]) * 60 + (+time[1]); - if (data < 0) { - data = "-"+data; - } - } - if (data === '') { - data = 0; - } - return data; + return HumanTimeConverter.humanTimeToSeconds(data, {hours: true})/60; }); - ngModelController.$formatters.push(function(totalminutes) { + ngModelController.$formatters.push(function(data) { //convert data from model format (m) to view format (hh:mm) - var time = ""; - if (totalminutes < 0) { - time = "-"; - totalminutes = -totalminutes; - } - var hh = Math.floor(totalminutes / 60); - var mm = Math.floor(totalminutes % 60); - // Add leading "0" for double digit values - mm = ("0"+mm).slice(-2); - time += hh + ":" + mm; - return time; + return HumanTimeConverter.secondsToHumanTime(data*60, + { seconds: 'disabled', + hours: 'enabled' } + ); }); } }; diff --git a/openslides/topics/static/js/topics/site.js b/openslides/topics/static/js/topics/site.js index ba4621364..c04f27d88 100644 --- a/openslides/topics/static/js/topics/site.js +++ b/openslides/topics/static/js/topics/site.js @@ -271,7 +271,8 @@ angular.module('OpenSlidesApp.topics.site', ['OpenSlidesApp.topics']) 'gettext', 'Agenda', 'Topic', - function($scope, gettext, Agenda, Topic) { + 'HumanTimeConverter', + function($scope, gettext, Agenda, Topic, HumanTimeConverter) { // Big TODO: Change wording from "item" to "topic". // import from textarea $scope.importByLine = function () { @@ -342,22 +343,13 @@ angular.module('OpenSlidesApp.topics.site', ['OpenSlidesApp.topics']) } // duration if (item.duration) { - var time = item.duration.replace(quotionRe, '$1').split(':'), - len = time.length, - data = ''; - if (len > 1 && !isNaN(time[len-2]) && !isNaN(time[len-1])) { // minutes and hours - // e.g.: [sl:1000:]10:34 (the [] will not be parsed) - data = (+time[len-2]) * 60 + (+time[len-1]); - } else if (len == 1) { // just interpret minutes - data = (+time[0]); - } else { - data = null; - } + var time = item.duration.replace(quotionRe, '$1'); + time = HumanTimeConverter.humanTimeToSeconds(time, {hours: true})/60; - if (data < 0 || data === '') { - data = null; // no negative duration + if (time <= 0) { // null instead of 0 or negative duration + time = null; } - item.duration = data; + item.duration = time; } else { item.duration = null; }