* bump version * fix translation ids * added css classes to modify form with custom css * improve export pdf file names * respect financial year in new report * added new InvoiceCalculator: price * upgrade packages and node-sass to v7 * title pattern for customer, project and activity via API * support negative money without currency * fix sub-locale in print export template * fix overbooking validation for monthly budget * fix copying entities with different set of custom-fields compared to the current configuration
79 lines
2.4 KiB
JavaScript
79 lines
2.4 KiB
JavaScript
/*
|
|
* This file is part of the Kimai time-tracking app.
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
/*!
|
|
* [KIMAI] KimaiActiveRecordsDuration: activate the updates for all active timesheet records on this page
|
|
*/
|
|
|
|
import KimaiPlugin from '../KimaiPlugin';
|
|
|
|
export default class KimaiActiveRecordsDuration extends KimaiPlugin {
|
|
|
|
getId() {
|
|
return 'timesheet-duration';
|
|
}
|
|
|
|
init() {
|
|
this.updateBrowserTitle = !!this.getConfiguration('updateBrowserTitle');
|
|
this.updateRecords();
|
|
const self = this;
|
|
const handle = function() { self.updateRecords(); };
|
|
this._updatesHandler = setInterval(handle, 10000);
|
|
// this will probably not work as expected, as other event-handler might need longer to update the DOM
|
|
document.addEventListener('kimai.timesheetUpdate', handle);
|
|
}
|
|
|
|
unregisterUpdates() {
|
|
clearInterval(this._updatesHandler);
|
|
}
|
|
|
|
updateRecords() {
|
|
let durations = [];
|
|
const activeRecords = document.querySelectorAll('[data-since]:not([data-since=""])');
|
|
|
|
if (activeRecords.length === 0) {
|
|
if (this.updateBrowserTitle) {
|
|
if (document.body.dataset['title'] === undefined) {
|
|
this.updateBrowserTitle = false;
|
|
} else {
|
|
document.title = document.body.dataset['title'];
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
|
|
const DATE = this.getPlugin('date');
|
|
|
|
for (let record of activeRecords) {
|
|
const since = record.dataset['since'];
|
|
const duration = DATE.formatDuration(since);
|
|
// only use the ones from the menu for the title
|
|
if (record.dataset['replacer'] !== undefined && record.dataset['title'] !== null && duration !== '?') {
|
|
durations.push(duration);
|
|
}
|
|
// but update all on the page (running entries in list pages)
|
|
record.textContent = duration;
|
|
}
|
|
|
|
if (durations.length === 0) {
|
|
return;
|
|
}
|
|
|
|
if (!this.updateBrowserTitle) {
|
|
return;
|
|
}
|
|
|
|
let title = durations.shift();
|
|
let prefix = ' | ';
|
|
|
|
for (let duration of durations.slice(0, 2)) {
|
|
title += prefix + duration;
|
|
}
|
|
document.title = title;
|
|
}
|
|
}
|