timer in timesheet
This commit is contained in:
parent
35397a1033
commit
1cfd28d50d
122
erpnext/projects/doctype/timesheet/timesheet.css
Normal file
122
erpnext/projects/doctype/timesheet/timesheet.css
Normal file
@ -0,0 +1,122 @@
|
||||
@import 'https://fonts.googleapis.com/css?family=Open+Sans:300,600,800';
|
||||
/*html,
|
||||
body {
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-o-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}*/
|
||||
|
||||
.stopwatch {
|
||||
height: 50%;
|
||||
width: 100%;
|
||||
display: inline-flex;
|
||||
transition: all .5s ease;
|
||||
-moz-transition: all .5s ease;
|
||||
-ms-transition: all .5s ease;
|
||||
-webkit-transition: all .5s ease;
|
||||
-o-transition: all .5s ease;
|
||||
}
|
||||
|
||||
.stopwatch span {
|
||||
display: table-cell;
|
||||
width: 33%;
|
||||
font-size: 5em;
|
||||
font-family: 'Open Sans', sans serif;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
transition: all .5s ease;
|
||||
-moz-transition: all .5s ease;
|
||||
-ms-transition: all .5s ease;
|
||||
-webkit-transition: all .5s ease;
|
||||
-o-transition: all .5s ease;
|
||||
}
|
||||
|
||||
.stopwatch .hours {
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.stopwatch .minutes {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.stopwatch .seconds {
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
.stopcontrols {
|
||||
height: 50%;
|
||||
width: 100%;
|
||||
display: table;
|
||||
transition: all .5s ease;
|
||||
-moz-transition: all .5s ease;
|
||||
-ms-transition: all .5s ease;
|
||||
-webkit-transition: all .5s ease;
|
||||
-o-transition: all .5s ease;
|
||||
}
|
||||
|
||||
.stopcontrols div {
|
||||
display: table-cell;
|
||||
width: 50%;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.playpause {
|
||||
border-right: 1px dashed #fff;
|
||||
border-bottom: 1px dashed #fff;
|
||||
}
|
||||
|
||||
.playpause .play {
|
||||
display: inline-block;
|
||||
border-top: 28px solid transparent;
|
||||
border-left: 37px solid #000;
|
||||
border-bottom: 28px solid transparent;
|
||||
}
|
||||
|
||||
.playpause .pause {
|
||||
border-right: 5px solid #000;
|
||||
border-left: 5px solid #000;
|
||||
padding: 20px 10px;
|
||||
}
|
||||
|
||||
.stop {
|
||||
border-bottom: 1px dashed #fff;
|
||||
}
|
||||
|
||||
.stop span {
|
||||
display: inline-block;
|
||||
background-color: #e74c3c;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
.stopwatch span {
|
||||
font-size: 6em;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 390px) {
|
||||
.stopwatch {
|
||||
height: 75%;
|
||||
display: block;
|
||||
}
|
||||
.stopcontrols {
|
||||
height: 25%;
|
||||
}
|
||||
.stopwatch span {
|
||||
width: 100%;
|
||||
height: 33%;
|
||||
display: block;
|
||||
}
|
||||
}
|
13
erpnext/projects/doctype/timesheet/timesheet.html
Normal file
13
erpnext/projects/doctype/timesheet/timesheet.html
Normal file
@ -0,0 +1,13 @@
|
||||
<div class="stopcontrols">
|
||||
<div class="playpause">
|
||||
<span class="play"></span>
|
||||
</div>
|
||||
<div class="stop">
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="stopwatch">
|
||||
<span class="hours">00</span>
|
||||
<span class="minutes">00</span>
|
||||
<span class="seconds">00</span>
|
||||
</div>
|
@ -50,12 +50,127 @@ frappe.ui.form.on("Timesheet", {
|
||||
}
|
||||
}
|
||||
|
||||
if (frm.doc.total_hours) {
|
||||
frm.add_custom_button(__('Start Timer'), function() {
|
||||
frm.trigger("timer")
|
||||
}).addClass("btn-primary");
|
||||
}
|
||||
|
||||
if(frm.doc.per_billed > 0) {
|
||||
frm.fields_dict["time_logs"].grid.toggle_enable("billing_hours", false);
|
||||
frm.fields_dict["time_logs"].grid.toggle_enable("billable", false);
|
||||
}
|
||||
},
|
||||
|
||||
timer: function(frm) {
|
||||
let dialog = new frappe.ui.Dialog({
|
||||
title: __("Timer"),
|
||||
fields: [
|
||||
{"fieldtype": "Select", "label": __("Activity"),
|
||||
"fieldname": "activity",
|
||||
"options": frm.doc.time_logs.map(d => d.activity_type),
|
||||
"reqd": 1 },
|
||||
{"fieldtype": "Select", "label": __("Project"),
|
||||
"fieldname": "project",
|
||||
"options": frm.doc.time_logs.map(d => d.project)},
|
||||
{"fieldtype": "Select", "label": __("Hours"),
|
||||
"fieldname": "hours",
|
||||
"options": frm.doc.time_logs.map(d => d.hours)}
|
||||
]
|
||||
});
|
||||
|
||||
dialog.wrapper.append(frappe.render_template("timesheet"));
|
||||
frm.trigger("control_timer");
|
||||
dialog.show();
|
||||
},
|
||||
|
||||
control_timer: function() {
|
||||
var interval = null;
|
||||
var currentIncrement = 0;
|
||||
var isPaused = false;
|
||||
var initialised = false;
|
||||
var clicked = false;
|
||||
var paused_time = 0;
|
||||
|
||||
$(".playpause").click(function(e) {
|
||||
if (clicked) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!initialised) {
|
||||
initialised = true;
|
||||
isPaused = false;
|
||||
$(".playpause span").removeClass();
|
||||
$(".playpause span").addClass("pause");
|
||||
initialiseTimer();
|
||||
}
|
||||
else {
|
||||
$(".playpause span").removeClass();
|
||||
if (isPaused) {
|
||||
isPaused = false;
|
||||
$(".playpause span").addClass("pause");
|
||||
}
|
||||
else {
|
||||
isPaused = true;
|
||||
$(".playpause span").addClass("play");
|
||||
paused_time = currentIncrement;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(".stop").click(function() {
|
||||
reset();
|
||||
});
|
||||
|
||||
function initialiseTimer() {
|
||||
interval = setInterval(function() {
|
||||
if (isPaused) return;
|
||||
var current = setCurrentIncrement();
|
||||
updateStopwatch(current);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
function updateStopwatch(increment) {
|
||||
var hours = Math.floor(increment / 3600);
|
||||
var minutes = Math.floor((increment - (hours * 3600)) / 60);
|
||||
var seconds = increment - (hours * 3600) - (minutes * 60);
|
||||
// if(!$('modal-open:visible')){
|
||||
// reset();
|
||||
// }
|
||||
if (!$('.modal-dialog').is(':visible')) {
|
||||
reset();
|
||||
}
|
||||
if(hours > 99)
|
||||
reset();
|
||||
if(cur_dialog && cur_dialog.get_value('hours') == hours) {
|
||||
isPaused = true;
|
||||
initialised = false;
|
||||
frappe.msgprint(__("Timer exceeded the given hours"));
|
||||
}
|
||||
$(".hours").text(hours < 10 ? ("0" + hours.toString()) : hours.toString());
|
||||
$(".minutes").text(minutes < 10 ? ("0" + minutes.toString()) : minutes.toString());
|
||||
$(".seconds").text(seconds < 10 ? ("0" + seconds.toString()) : seconds.toString());
|
||||
}
|
||||
|
||||
function setCurrentIncrement() {
|
||||
currentIncrement += 1;
|
||||
return currentIncrement;
|
||||
}
|
||||
|
||||
function reset() {
|
||||
currentIncrement = 0;
|
||||
isPaused = true;
|
||||
initialised = false;
|
||||
clearInterval(interval);
|
||||
$(".hours").text("00");
|
||||
$(".minutes").text("00");
|
||||
$(".seconds").text("00");
|
||||
$(".playpause span").removeClass();
|
||||
$(".playpause span").addClass("play");
|
||||
}
|
||||
},
|
||||
|
||||
make_invoice: function(frm) {
|
||||
let dialog = new frappe.ui.Dialog({
|
||||
title: __("Select Item (optional)"),
|
||||
|
Loading…
x
Reference in New Issue
Block a user