timetracking_app/app.js

347 строки
9.0 KiB
JavaScript
Исходник Обычный вид История

2014-04-11 05:09:27 +04:00
(function() {
'use_strict';
return {
requests: {
fetchAudits: function() {
return {
url: helpers.fmt(
'/api/v2/tickets/%@/audits.json?include=users',
this.ticket().id()
)
};
}
},
2014-04-11 05:09:27 +04:00
events: {
'app.activated' : 'onAppActivated',
'app.deactivated' : 'onAppFocusOut',
'app.willDestroy' : 'onAppWillDestroy',
'ticket.save' : 'onTicketSave',
'ticket.form.id.changed' : 'onTicketFormChanged',
'fetchAudits.done' : 'onFetchAuditsDone',
2014-04-11 05:09:27 +04:00
'click .pause' : 'onPauseClicked',
2014-04-28 18:59:03 +04:00
'click .play' : 'onPlayClicked',
2014-04-11 05:09:27 +04:00
'click .reset' : 'onResetClicked',
'click .modal-save' : 'onModalSaveClicked',
'click a.timelogs-opener:not([disabled])' : 'onTimeLogsContainerClicked',
2014-04-11 05:09:27 +04:00
'shown .modal' : 'onModalShown',
2014-04-28 18:59:03 +04:00
'hidden .modal' : 'onModalHidden',
'click .expand-bar' : 'onTimelogsClicked'
2014-04-11 05:09:27 +04:00
},
/*
*
* EVENT CALLBACKS
*
*/
onAppActivated: function(app) {
if (app.firstLoad) {
_.defer(this.initialize.bind(this));
if (this.ticket().id() && this.setting('display_timelogs')) {
this.ajax('fetchAudits');
}
2014-04-11 05:09:27 +04:00
} else {
this.onAppFocusIn();
}
},
onAppWillDestroy: function() {
clearInterval(this.timeLoopID);
},
onAppFocusOut: function() {
if (this.setting('auto_pause_resume')) {
this.autoPause();
}
},
onAppFocusIn: function() {
if (this.setting('auto_pause_resume') &&
!this.manuallyPaused) {
this.autoResume();
}
},
onTicketFormChanged: function() {
_.defer(this.hideFields.bind(this));
},
onTicketSave: function() {
if (this.setting('time_submission')) {
return this.promise(function(done, fail) {
this.saveHookPromiseDone = done;
this.saveHookPromiseFail = fail;
this.renderTimeModal();
}.bind(this));
} else {
this.updateTime(this.elapsedTime);
return true;
}
},
onFetchAuditsDone: function(data) {
2014-04-28 18:59:03 +04:00
var status = "",
timelogs = _.reduce(data.audits, function(memo, audit) {
var newStatus = _.find(audit.events, function(event) {
return event.field_name == 'status';
}, this),
event = _.find(audit.events, function(event) {
return event.field_name == this.setting('time_field_id');
}, this);
if (newStatus){
status = newStatus.value;
}
if (event) {
memo.push({
time: this.TimeHelper.secondsToTimeString(parseInt(event.value, 0)),
date: new Date(audit.created_at).toLocaleString(),
status: status,
localized_status: this.I18n.t(helpers.fmt('statuses.%@', status)),
user: _.find(data.users, function(user) {
return user.id === audit.author_id;
})
});
}
return memo;
}, [], this);
this.renderTimelogs(timelogs.reverse());
},
2014-04-11 05:09:27 +04:00
onPauseClicked: function(e) {
var $el = this.$(e.currentTarget);
2014-04-28 18:59:03 +04:00
$el.find('i').addClass('active');
this.$('.play i').removeClass('active');
2014-04-11 05:09:27 +04:00
this.manuallyPaused = this.paused = true;
},
2014-04-28 18:59:03 +04:00
onPlayClicked: function(e) {
2014-04-11 05:09:27 +04:00
var $el = this.$(e.currentTarget);
2014-04-28 18:59:03 +04:00
$el.find('i').addClass('active');
this.$('.pause i').removeClass('active');
2014-04-11 05:09:27 +04:00
this.manuallyPaused = this.paused = false;
},
onResetClicked: function() {
this.elapsedTime = 0;
},
2014-04-28 18:59:03 +04:00
onTimelogsClicked: function() {
this.$('.timelogs-container').slideToggle();
2014-04-11 05:09:27 +04:00
},
onModalSaveClicked: function() {
var timeString = this.$('.modal-time').val();
try {
this.updateTime(this.TimeHelper.timeStringToSeconds(timeString));
2014-04-11 05:09:27 +04:00
this.saveHookPromiseIsDone = true; // Flag that saveHookPromiseDone is gonna be called after hiding the modal
this.$('.modal').modal('hide');
this.saveHookPromiseDone();
} catch (e) {
if (e.message == 'bad_time_format') {
services.notify(this.I18n.t('errors.bad_time_format'), alert);
} else {
throw e;
}
}
},
onModalShown: function() {
var timeout = 15,
$timeout = this.$('span.modal-timer'),
$modal = this.$('.modal');
this.modalTimeoutID = setInterval(function() {
timeout -= 1;
$timeout.html(timeout);
if (timeout === 0) {
$modal.modal('hide');
}
}.bind(this), 1000);
},
onModalHidden: function() {
clearInterval(this.modalTimeoutID);
if (!this.saveHookPromiseIsDone) {
this.saveHookPromiseFail(this.I18n.t('errors.save_hook'));
}
},
/*
*
* METHODS
*
*/
initialize: function() {
this.hideFields();
this.timeLoopID = this.setTimeLoop();
this.switchTo('main', {
manual_pause_resume: this.setting('manual_pause_resume'),
display_reset: this.setting('reset'),
display_timer: this.setting('display_timer')
2014-04-11 05:09:27 +04:00
});
this.$('tr').tooltip({ placement: 'left', html: true });
},
updateMainView: function(time) {
this.$('.live-timer').html(this.TimeHelper.secondsToTimeString(time));
this.$('.live-totaltimer').html(this.TimeHelper.secondsToTimeString(
this.totalTime() + time
2014-04-11 05:09:27 +04:00
));
},
renderTimelogs: function(timelogs) {
this.$('.timelogs-container')
.html(this.renderTemplate('timelogs', {
timelogs: timelogs,
csv_filename: helpers.fmt('ticket-timelogs-%@',
this.ticket().id()),
csv_string: encodeURI(this.timelogsToCsvString(timelogs))
}));
2014-04-25 19:10:54 +04:00
this.$('tr').tooltip({ placement: 'left', html: true });
this.$('.timelogs-opener')
.removeAttr('disabled')
.removeClass('disabled');
},
2014-04-11 05:09:27 +04:00
hideFields: function() {
_.each([this.timeFieldLabel(), this.totalTimeFieldLabel()], function(f) {
2014-04-11 05:09:27 +04:00
var field = this.ticketFields(f);
if (field) {
field.hide();
}
}, this);
},
/*
* TIME RELATED
*/
setTimeLoop: function() {
this.elapsedTime = 0;
return setInterval(function() {
if (!this.paused) {
// Update elapsed time by 1 second
this.elapsedTime += 1;
2014-04-11 05:09:27 +04:00
this.updateMainView(this.elapsedTime);
}
}.bind(this), 1000);
2014-04-11 05:09:27 +04:00
},
updateTime: function(time) {
this.time(time);
this.totalTime(this.totalTime() + time);
2014-04-11 05:09:27 +04:00
},
autoResume: function() {
this.paused = false;
},
autoPause: function() {
this.paused = true;
},
renderTimeModal: function() {
this.$('.modal-time').val(this.TimeHelper.secondsToTimeString(this.elapsedTime));
2014-04-11 05:09:27 +04:00
this.$('.modal').modal('show');
},
/*
*
* HELPERS
*
*/
time: function(time) {
return this.getOrSetField(this.timeFieldLabel(), time);
2014-04-11 05:09:27 +04:00
},
totalTime: function(time) {
return this.getOrSetField(this.totalTimeFieldLabel(), time);
2014-04-11 05:09:27 +04:00
},
totalTimeFieldLabel: function() {
return this.buidFieldLabel(this.setting('total_time_field_id'));
2014-04-11 05:09:27 +04:00
},
timeFieldLabel: function() {
return this.buidFieldLabel(this.setting('time_field_id'));
},
buidFieldLabel: function(id) {
return helpers.fmt('custom_field_%@', id);
},
getOrSetField: function(fieldLabel, value) {
if (value) {
return this.ticket().customField(fieldLabel, value);
}
2014-04-11 05:09:27 +04:00
return parseInt((this.ticket().customField(fieldLabel) || 0), 0);
},
2014-04-11 05:09:27 +04:00
timelogsToCsvString: function(timelogs) {
return _.reduce(timelogs, function(memo, timelog) {
return memo + helpers.fmt('%@\n', [ timelog.time, timelog.user.name, timelog.date].join());
}, 'Time,Submitter,Submitted At\n', this);
},
TimeHelper: {
secondsToTimeString: function(seconds) {
var hours = Math.floor(seconds / 3600),
2014-04-25 19:10:54 +04:00
minutes = Math.floor((seconds - (hours * 3600)) / 60),
secs = seconds - (hours * 3600) - (minutes * 60);
2014-04-11 05:09:27 +04:00
return helpers.fmt('%@:%@:%@',
this.addInsignificantZero(hours),
this.addInsignificantZero(minutes),
this.addInsignificantZero(secs));
2014-04-11 05:09:27 +04:00
},
timeStringToSeconds: function(timeString) {
2014-04-11 05:09:27 +04:00
var re = /^([\d]{2}):([\d]{2}):([\d]{2})$/,
result = re.exec(timeString);
2014-04-11 05:09:27 +04:00
if (!result ||
result.length != 4) {
throw { message: 'bad_time_format' };
} else {
return (parseInt(result[1], 10) * 3600) +
(parseInt(result[2], 10) * 60) +
(parseInt(result[3], 10));
2014-04-11 05:09:27 +04:00
}
},
addInsignificantZero: function(n) {
return ( n < 10 ? '0' : '') + n;
}
}
};
}());