Skip to content

Instantly share code, notes, and snippets.

@quangdaist01
Last active March 20, 2023 07:19
Show Gist options
  • Save quangdaist01/cf11c355d0ecd5678edf7cb946178fba to your computer and use it in GitHub Desktop.
Save quangdaist01/cf11c355d0ecd5678edf7cb946178fba to your computer and use it in GitHub Desktop.
Easy Timesheet For FSSers
// ==UserScript==
// @name Easy Timesheet For FSSers
// @namespace http://tampermonkey.net/
// @version 0.1
// @description Press ` to add -> Type descripton -> Press Ctrl + Enter to finish. No more tedious mouse movements.
// @author Dai.Nguyen.HCM
// @match https://ts.fss.com.vn/core/kimai.php
// @icon https://www.google.com/s2/favicons?sz=64&domain=tampermonkey.net
// @grant none
// ==/UserScript==
const getNextWork = date => {
let day = date.getDay();
let add = 1;
if (day === 6)
add = 2;
else if (day === 5)
add = 3;
date.setDate(date.getDate() + add); // will correctly handle 31+1 > 32 > 1st next month
return date;
};
async function addNewLog(e) {
'use strict';
if (e.key === "`") {
let latestDateStr = document.querySelector('.date.break_day').innerText;
let latestStartTimeStr = document.querySelector('.from.break_day').innerText;
let day = latestDateStr.split(".")[0];
let month = latestDateStr.split(".")[1];
let year = latestDateStr.split(".")[2];
// Calculate next day and time
let newDateStr = '';
let newStartTimeStr = '';
let newEndTimeStr = '';
let newDuration;
let latestDate;
let nextWorkDate;
if (latestStartTimeStr === '08:30') {
// Use the latest Date
newDateStr = latestDateStr;
newStartTimeStr = '13:00:00';
newEndTimeStr = '17:30:00';
newDuration = '04:30:00';
} else if (latestStartTimeStr === '13:00') {
// Use the tomorrow Date
latestDate = new Date(year, month - 1, day); // month starts from 0
nextWorkDate = getNextWork(latestDate);
newDateStr = [nextWorkDate.getDate(), nextWorkDate.getMonth() + 1, nextWorkDate.getFullYear()].join('.'); // month starts from 0
newStartTimeStr = '08:30:00';
newEndTimeStr = '12:00:00';
newDuration = '03:30:00';
}
// Find the button by its ID or class name
let button = document.querySelector("#timeSheet_head > div > a");
if (!button) {
button = document.getElementsByClassName('button-class')[0];
}
// Click the button
if (button) {
button.click();
}
// Wait untill the floater is visible
const sleep = ms => new Promise(r => setTimeout(r, ms));
while (document.querySelector('#floater').style.display === 'none') {
await sleep(200);
console.log('No');
}
console.log('OK');
await sleep(500);
// Fill in the form
document.querySelector('input#start_day').value = newDateStr;
document.querySelector('input#end_day').value = newDateStr;
document.querySelector('input#start_time').value = newStartTimeStr;
document.querySelector('input#end_time').value = newEndTimeStr;
document.querySelector('input#duration').value = newDuration;
document.querySelector('textarea#description').focus();
}
}
function click_OK(e) {
if (e.ctrlKey && e.key === "Enter") {
document.querySelector('div#formbuttons > .btn_ok').click();
}
}
document.addEventListener("keyup", addNewLog, false);
document.addEventListener("keyup", click_OK, false);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment