mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Working on the time tracker
This commit is contained in:
parent
57a6f0c053
commit
6a66000db7
@ -14,11 +14,13 @@
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
/*
|
||||
@media (max-width: 768px) {
|
||||
#formDiv {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
@media (max-width: 768px) {
|
||||
#clock,
|
||||
@ -124,6 +126,10 @@
|
||||
xpadding-bottom: 10px !important;
|
||||
}
|
||||
|
||||
.ui-timepicker-wrapper {
|
||||
width: 10em !important;
|
||||
}
|
||||
|
||||
.footer {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
@ -184,7 +190,7 @@
|
||||
|
||||
<!-- Task Form -->
|
||||
<div class="col-sm-7 col-sm-push-5">
|
||||
<div id="formDiv" class="panel panel-default affix" data-bind="visible: selectedTask" style="margin:20px; display:none;">
|
||||
<div id="formDiv" class="panel panel-default x-affix" data-bind="visible: selectedTask" style="margin:20px; display:none;">
|
||||
<div class="panel-body">
|
||||
<form id="taskForm">
|
||||
<span data-bind="event: { keypress: onFormKeyPress, change: onFormChange, input: onFormChange }">
|
||||
@ -214,21 +220,22 @@
|
||||
<tr data-bindx="event: { mouseover: showActions, mouseout: hideActions }">
|
||||
<td style="padding: 0 6px 10px 0">
|
||||
{!! Former::text('date')
|
||||
->data_bindx('timepicker: startTime')
|
||||
->data_bindx("")
|
||||
->raw() !!}
|
||||
</td>
|
||||
<td style="padding: 0 6px 10px 6px">
|
||||
{!! Former::text('start_time')
|
||||
->data_bind('timepicker: startTime')
|
||||
->data_bind("timepicker: startTime, timepickerOptions: {scrollDefault: 'now', timeFormat: '" . ($account->military_time ? 'H:i:s' : 'g:i:s A') . "'}")
|
||||
->raw() !!}
|
||||
</td>
|
||||
<td style="padding: 0 6px 10px 6px">
|
||||
{!! Former::text('end_time')
|
||||
->data_bind('timepicker: endTime')
|
||||
->data_bind("timepicker: endTime, timepickerOptions: {scrollDefault: 'now', timeFormat: '" . ($account->military_time ? 'H:i:s' : 'g:i:s A') . "'}")
|
||||
->raw() !!}
|
||||
</td>
|
||||
<td style="padding: 0 0 10px 6px">
|
||||
{!! Former::text('duration')
|
||||
->data_bind("timepicker: duration, timepickerOptions: {timeFormat: 'H:i:s', showAsDuration: true}")
|
||||
->raw() !!}
|
||||
</td>
|
||||
|
||||
@ -239,12 +246,6 @@
|
||||
class="form-control time-input time-input-start" placeholder="{{ trans('texts.start_time') }}"/>
|
||||
</div>
|
||||
</td>
|
||||
<td style="padding: 0px 12px 12px 0 !important">
|
||||
<div data-bind="css: { 'has-error': !isEndValid() }">
|
||||
<input type="text" data-bind="dateTimePicker: endTime.pretty, event:{ change: $root.refresh }"
|
||||
class="form-control time-input time-input-end" placeholder="{{ trans('texts.end_time') }}"/>
|
||||
</div>
|
||||
</td>
|
||||
<td style="padding: 0px 12px 12px 0 !important; width:100px">
|
||||
<input type="text" data-bind="value: duration.pretty, visible: !isEmpty()" class="form-control"></div>
|
||||
<a href="#" data-bind="click: function() { setNow(), $root.refresh() }, visible: isEmpty()">{{ trans('texts.set_now') }}</a>
|
||||
@ -455,38 +456,6 @@
|
||||
}, 1000 * 60 * 15);
|
||||
}
|
||||
|
||||
ko.bindingHandlers.timepicker = {
|
||||
init: function (element, valueAccessor, allBindingsAccessor) {
|
||||
var options = allBindingsAccessor().dropdownOptions|| {};
|
||||
var value = ko.utils.unwrapObservable(valueAccessor());
|
||||
var options = {
|
||||
scrollDefault: 'now',
|
||||
showDuration: true,
|
||||
step: 15,
|
||||
};
|
||||
$(element).timepicker(options);
|
||||
|
||||
ko.utils.registerEventHandler(element, "change", function () {
|
||||
var value = valueAccessor();
|
||||
value($(element).val());
|
||||
});
|
||||
|
||||
/*
|
||||
var id = (value && value.public_id) ? value.public_id() : (value && value.id) ? value.id() : value ? value : false;
|
||||
if (id) $(element).val(id);
|
||||
*/
|
||||
},
|
||||
update: function (element, valueAccessor) {
|
||||
var value = ko.utils.unwrapObservable(valueAccessor());
|
||||
var field = $(element).attr('name');
|
||||
if (field == 'start_time') {
|
||||
$input = $(element).closest('td').next('td').find('input').show();
|
||||
$input.timepicker('option', 'durationTime', $(element).val());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
$(function() {
|
||||
|
||||
// setup clients and project comboboxes
|
||||
|
@ -1,5 +1,63 @@
|
||||
<script type="text/javascript">
|
||||
|
||||
function intToTime(seconds)
|
||||
{
|
||||
if (seconds === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// calculate seconds, minutes, hours
|
||||
var duration = seconds*1000
|
||||
var milliseconds = parseInt((duration%1000)/100)
|
||||
, seconds = parseInt((duration/1000)%60)
|
||||
, minutes = parseInt((duration/(1000*60))%60)
|
||||
, hours = parseInt((duration/(1000*60*60))%24);
|
||||
|
||||
hours = (hours < 10) ? "0" + hours : hours;
|
||||
minutes = (minutes < 10) ? "0" + minutes : minutes;
|
||||
seconds = (seconds < 10) ? "0" + seconds : seconds;
|
||||
|
||||
return new Date(1970, 0, 1, hours, minutes, seconds, 0);
|
||||
}
|
||||
|
||||
ko.bindingHandlers.timepicker = {
|
||||
init: function (element, valueAccessor, allBindingsAccessor) {
|
||||
var options = allBindingsAccessor().timepickerOptions || {};
|
||||
$.extend(options, {
|
||||
wrapHours: false,
|
||||
showDuration: true,
|
||||
step: 15,
|
||||
});
|
||||
$(element).timepicker(options);
|
||||
|
||||
ko.utils.registerEventHandler(element, 'change', function () {
|
||||
var value = valueAccessor();
|
||||
var dateTime = $(element).timepicker('getTime');
|
||||
if (dateTime) {
|
||||
time = dateTime.getTime() / 1000;
|
||||
}
|
||||
value(time);
|
||||
});
|
||||
},
|
||||
update: function (element, valueAccessor) {
|
||||
var value = ko.utils.unwrapObservable(valueAccessor());
|
||||
var field = $(element).attr('name');
|
||||
|
||||
if (field == 'duration') {
|
||||
$(element).timepicker('setTime', intToTime(value));
|
||||
} else {
|
||||
$(element).timepicker('setTime', new Date(value * 1000));
|
||||
}
|
||||
|
||||
//console.log(field + ': ' + value);
|
||||
if (field == 'start_time') {
|
||||
$input = $(element).closest('td').next('td').find('input').show();
|
||||
$input.timepicker('option', 'durationTime', $(element).val());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function ViewModel() {
|
||||
var self = this;
|
||||
self.tasks = ko.observableArray();
|
||||
@ -881,7 +939,6 @@
|
||||
var self = this;
|
||||
self.startTime = ko.observable(0);
|
||||
self.endTime = ko.observable(0);
|
||||
self.duration = ko.observable(0);
|
||||
self.actionsVisible = ko.observable(false);
|
||||
self.isStartValid = ko.observable(true);
|
||||
self.isEndValid = ko.observable(true);
|
||||
@ -908,9 +965,17 @@
|
||||
return moment.unix(self.startTime()).fromNow();
|
||||
});
|
||||
|
||||
self.duration = ko.computed(function() {
|
||||
model.clock(); // bind to the clock
|
||||
return (self.endTime() || moment().unix()) - self.startTime();
|
||||
self.duration = ko.computed({
|
||||
read: function () {
|
||||
model.clock(); // bind to the clock
|
||||
var endTime = self.endTime() ? self.endTime() : moment().unix();
|
||||
//console.log('duration: ' + (endTime - self.startTime()));
|
||||
return endTime - self.startTime();
|
||||
},
|
||||
write: function(value) {
|
||||
console.log('duration: ' + value);
|
||||
//self.endTime(value);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user