WIP timesheet timers: config to disable timers and overwrite of start&stop time

This commit is contained in:
ralf 2022-10-05 14:55:42 +02:00
parent 8fad43b705
commit 59da89fe8b
6 changed files with 66 additions and 28 deletions

View File

@ -97,30 +97,30 @@ egw.extend('timer', egw.MODULE_GLOBAL, function()
switch(_action) switch(_action)
{ {
case 'overall-start': case 'overall-start':
startTimer(overall); startTimer(overall, _time);
break; break;
case 'overall-pause': case 'overall-pause':
stopTimer(overall,true); stopTimer(overall,true, _time);
if (specific?.start) stopTimer(specific, true); if (specific?.start) stopTimer(specific, true, _time);
break; break;
case 'overall-stop': case 'overall-stop':
stopTimer(overall); stopTimer(overall, false, _time);
if (specific?.start) stopTimer(specific); if (specific?.start) stopTimer(specific, false, _time);
break; break;
case 'specific-start': case 'specific-start':
if (overall?.paused) startTimer(overall); if (overall?.paused) startTimer(overall, _time);
startTimer(specific); startTimer(specific, _time);
break; break;
case 'specific-pause': case 'specific-pause':
stopTimer(specific,true); stopTimer(specific,true, _time);
break; break;
case 'specific-stop': case 'specific-stop':
stopTimer(specific); stopTimer(specific, false, _time);
break; break;
} }
// persist state // persist state
@ -227,7 +227,7 @@ egw.extend('timer', egw.MODULE_GLOBAL, function()
* Start given timer * Start given timer
* *
* @param object _timer * @param object _timer
* @param string|undefined _start to initialise with time different from current time * @param string|Date|undefined _start to initialise with time different from current time
* @param number|undefined _offset to set an offset * @param number|undefined _offset to set an offset
*/ */
function startTimer(_timer, _start, _offset) function startTimer(_timer, _start, _offset)
@ -241,7 +241,7 @@ egw.extend('timer', egw.MODULE_GLOBAL, function()
{ {
_timer.start = new Date(); _timer.start = new Date();
} }
if (_offset || _timer.offset) if (_offset || _timer.offset && _timer.paused)
{ {
_timer.start.setMilliseconds(_timer.start.getMilliseconds()-(_offset || _timer.offset)); _timer.start.setMilliseconds(_timer.start.getMilliseconds()-(_offset || _timer.offset));
} }
@ -265,14 +265,16 @@ egw.extend('timer', egw.MODULE_GLOBAL, function()
* *
* @param object _timer * @param object _timer
* @param bool|undefined _pause true: pause, else: stop * @param bool|undefined _pause true: pause, else: stop
* @param string|Date|undefined _time stop-time, default current time
*/ */
function stopTimer(_timer, _pause) function stopTimer(_timer, _pause, _time)
{ {
const time = _time ? new Date(_time) : new Date();
// update _timer state object // update _timer state object
_timer.paused = _pause || false; _timer.paused = _pause || false;
if (_timer.start) if (_timer.start)
{ {
_timer.offset = (new Date()).valueOf() - _timer.start.valueOf(); _timer.offset = time.valueOf() - _timer.start.valueOf();
_timer.start = undefined; _timer.start = undefined;
} }
// update timer display // update timer display
@ -314,8 +316,10 @@ egw.extend('timer', egw.MODULE_GLOBAL, function()
// set state if given // set state if given
const timer = document.getElementById('topmenu_timer'); const timer = document.getElementById('topmenu_timer');
if (timer && timer.getAttribute('data-state')) { const state = timer && timer.getAttribute('data-state') ? JSON.parse(timer.getAttribute('data-state')) : undefined;
setState(JSON.parse(timer.getAttribute('data-state'))); if (timer && state)
{
setState(state);
} }
// bind click handler // bind click handler
@ -329,7 +333,9 @@ egw.extend('timer', egw.MODULE_GLOBAL, function()
callback: (button_id, value) => // return false to prevent dialog closing callback: (button_id, value) => // return false to prevent dialog closing
{ {
if (button_id !== 'close') { if (button_id !== 'close') {
timerAction(button_id.replace(/_([a-z]+)\[([a-z]+)\]/, '$1-$2'), value.time); timerAction(button_id.replace(/_([a-z]+)\[([a-z]+)\]/, '$1-$2'),
// eT2 operates in user-time, while timers here always operate in UTC
value.time ? new Date((new Date(value.time)).valueOf() + egw.getTimezoneOffset() * 60000) : undefined);
setButtonState(); setButtonState();
return false; return false;
} }
@ -342,7 +348,7 @@ egw.extend('timer', egw.MODULE_GLOBAL, function()
], ],
value: { value: {
content: { content: {
disable: 'overwrite' disable: state.disable.join(':')
}, },
sel_options: {} sel_options: {}
} }
@ -350,16 +356,12 @@ egw.extend('timer', egw.MODULE_GLOBAL, function()
// Add to DOM, dialog will auto-open // Add to DOM, dialog will auto-open
document.body.appendChild(dialog); document.body.appendChild(dialog);
dialog.getUpdateComplete().then(() => { dialog.getUpdateComplete().then(() => {
// add default content to timer-divs
dialog._overlayContentNode.querySelectorAll('div.timesheet_timer').forEach(timer => {
timer.textContent = '0:00';
});
// enable/disable buttons based on timer state // enable/disable buttons based on timer state
setButtonState(); setButtonState();
// update Timers // update timers in dialog
update(); update();
// set current time for overwrite time input // set current time for overwrite time input (eT2 operates in user-time!)
let now = new Date((new Date).valueOf() - egw.getTimezoneOffset() * 60000); //let now = new Date((new Date).valueOf() - egw.getTimezoneOffset() * 60000);
//dialog._overlayContentNode.querySelector('et2-date-time').value = now; //dialog._overlayContentNode.querySelector('et2-date-time').value = now;
}); });
}); });

View File

@ -218,8 +218,12 @@ class timesheet_hooks
public static function add_timer($data) public static function add_timer($data)
{ {
$state = Events::timerState(); $state = Events::timerState();
$GLOBALS['egw']->framework->_add_topmenu_info_item('<div id="topmenu_timer" title="'. // only send/display if at least one timer is not disabled
lang('Start & stop timer').'"'. if (array_diff(['specific', 'overall'], $state['disable']))
($state ? ' data-state="'.htmlspecialchars(json_encode($state)).'"' : '').'>0:00</div>', 'timer'); {
$GLOBALS['egw']->framework->_add_topmenu_info_item('<div id="topmenu_timer" title="'.
lang('Start & stop timer').'"'.
($state ? ' data-state="'.htmlspecialchars(json_encode($state)).'"' : '').'>0:00</div>', 'timer');
}
} }
} }

View File

@ -28,6 +28,7 @@ deleted timesheet de gelöscht
deletes this field timesheet de Dieses Feld löschen deletes this field timesheet de Dieses Feld löschen
determines the order the fields are displayed timesheet de verändert die Reihenfolge der angezeigten Felder determines the order the fields are displayed timesheet de verändert die Reihenfolge der angezeigten Felder
directory with documents to insert entries timesheet de Ordner mit Dokumenten zum Einfügen. directory with documents to insert entries timesheet de Ordner mit Dokumenten zum Einfügen.
disable timers timesheet de Zeitnehmer ausschalten
each value is a line like <id>[=<label>] timesheet de jeder Wert ist eine Zeile in dem Format <id>[=|label>] each value is a line like <id>[=<label>] timesheet de jeder Wert ist eine Zeile in dem Format <id>[=|label>]
edit status common de Status bearbeiten edit status common de Status bearbeiten
edit this entry timesheet de diesen Eintrag bearbeiten edit this entry timesheet de diesen Eintrag bearbeiten
@ -37,6 +38,7 @@ entry deleted timesheet de Eintrag gelöscht
entry saved timesheet de Eintrag gespeichert entry saved timesheet de Eintrag gespeichert
error deleting the entry!!! timesheet de Fehler beim Löschen des Eintrags!!! error deleting the entry!!! timesheet de Fehler beim Löschen des Eintrags!!!
error saving the entry!!! timesheet de Fehler beim Speichern des Eintrags!!! error saving the entry!!! timesheet de Fehler beim Speichern des Eintrags!!!
error storing working time timesheet de Fehler beim Speichern der Arbeitszeit
events timesheet de Ereignisse events timesheet de Ereignisse
example {{if n_prefix~mr~hello mr.~hello ms.}} - search the field "n_prefix", for "mr", if found, write hello mr., else write hello ms. timesheet de Beispiel: {{IF n_prefix~Herr~sehr geehrter Herr~sehr geehrte Frau}} - wenn im Feld 'n_prefix' 'Herr' steht wird 'sehr geehrter Herr' geschrieben, ansonsten 'sehr geehrte Frau'. example {{if n_prefix~mr~hello mr.~hello ms.}} - search the field "n_prefix", for "mr", if found, write hello mr., else write hello ms. timesheet de Beispiel: {{IF n_prefix~Herr~sehr geehrter Herr~sehr geehrte Frau}} - wenn im Feld 'n_prefix' 'Herr' steht wird 'sehr geehrter Herr' geschrieben, ansonsten 'sehr geehrte Frau'.
example {{letterprefixcustom n_prefix title n_family}} - example: mr dr. james miller timesheet de Beispiel: {{LETTERPREFIXCUSTOM n_prefix title n_family}} - Herr Dr. Müller example {{letterprefixcustom n_prefix title n_family}} - example: mr dr. james miller timesheet de Beispiel: {{LETTERPREFIXCUSTOM n_prefix title n_family}} - Herr Dr. Müller
@ -95,7 +97,10 @@ only admin admin de nur Administratoren
only admin can edit this status admin de nur Administratoren dürfen Stundenzettel mit diesen Status bearbeiten only admin can edit this status admin de nur Administratoren dürfen Stundenzettel mit diesen Status bearbeiten
or endtime timesheet de oder Endzeit or endtime timesheet de oder Endzeit
order timesheet de Reihenfolge order timesheet de Reihenfolge
overwrite common de Überschreiben
overwriting start or stop time timesheet de Überschreiben der Start- oder Stop-Zeit
parent admin de Übergeordnet parent admin de Übergeordnet
pause common de Pause
permission denied!!! timesheet de Zugriff verweigert!!! permission denied!!! timesheet de Zugriff verweigert!!!
permissions error - %1 could not %2 timesheet de Fehler in den Zugriffsberechtigungen - %1 nicht möglich %2 permissions error - %1 could not %2 timesheet de Fehler in den Zugriffsberechtigungen - %1 nicht möglich %2
prevent deleting admin de Verhindert Löschung prevent deleting admin de Verhindert Löschung
@ -128,6 +133,7 @@ status timesheet de Status
status deleted. timesheet de Status gelöscht status deleted. timesheet de Status gelöscht
status of created timesheets timesheet de Status für neue Stundenzettel status of created timesheets timesheet de Status für neue Stundenzettel
status updated. timesheet de Status geändert status updated. timesheet de Status geändert
stop common de Stop
sum %1: timesheet de Summe %1: sum %1: timesheet de Summe %1:
tag to mark positions for address labels timesheet de Platzhalter, um die Position der Adresslabels festzulegen tag to mark positions for address labels timesheet de Platzhalter, um die Position der Adresslabels festzulegen
the document can contain placeholder like {{%3}}, to be replaced with the data (%1full list of placeholder names%2). timesheet de Das Dokument kann Platzhalter wie {{%3}} beinhalten, die mit den entsprechenden Inhalten ersetzt werden (%1Liste der Platzhalter%2). the document can contain placeholder like {{%3}}, to be replaced with the data (%1full list of placeholder names%2). timesheet de Das Dokument kann Platzhalter wie {{%3}} beinhalten, die mit den entsprechenden Inhalten ersetzt werden (%1Liste der Platzhalter%2).
@ -138,6 +144,7 @@ this month timesheet de Diesen Monat
this week timesheet de Diese Woche this week timesheet de Diese Woche
this year timesheet de Dieses Jahr this year timesheet de Dieses Jahr
ticket modified by %1 at %2 timesheet de Ticket geändert von %1 am %2 ticket modified by %1 at %2 timesheet de Ticket geändert von %1 am %2
timer common de Zeitnehmer
timesheet common de Stundenzettel timesheet common de Stundenzettel
timesheet csv export timesheet de Export des Stundenzettels als CSV timesheet csv export timesheet de Export des Stundenzettels als CSV
timesheet csv import timesheet de Stundenzettels CSV Import timesheet csv import timesheet de Stundenzettels CSV Import
@ -162,6 +169,9 @@ what should be done with unknown values? timesheet de Was soll mit unbekannten W
when you merge entries into documents, they will be stored here. if no directory is provided, they will be stored in your home directory (/home/ralf) timesheet de Wenn Sie Einträge in Dokumente einfügen, werden diese hier gespeichert. Wenn kein Verzeichnis angegeben ist, werden sie in Ihrem Home Verzeichnis gespeichert. when you merge entries into documents, they will be stored here. if no directory is provided, they will be stored in your home directory (/home/ralf) timesheet de Wenn Sie Einträge in Dokumente einfügen, werden diese hier gespeichert. Wenn kein Verzeichnis angegeben ist, werden sie in Ihrem Home Verzeichnis gespeichert.
will be created when saving ... common de Wird beim Speichern angelegt ... will be created when saving ... common de Wird beim Speichern angelegt ...
working time common de Arbeitszeit working time common de Arbeitszeit
working time and timer timesheet de Arbeitszeit und Zeitnehmer
working time from %1 timesheet de Arbeitszeit vom %1
working time of %1 hours stored timesheet de Arbeitszeit von %1 Stunden gespeichert
yes, only admins can purge deleted items admin de Ja, nur Administratoren dürfen gelöschte Einträge endgültig löschen yes, only admins can purge deleted items admin de Ja, nur Administratoren dürfen gelöschte Einträge endgültig löschen
yes, users can purge their deleted items admin de Ja, Benutzer dürfen ihre gelöschten Einträge endgültig löschen yes, users can purge their deleted items admin de Ja, Benutzer dürfen ihre gelöschten Einträge endgültig löschen
yesterday timesheet de Gestern yesterday timesheet de Gestern

View File

@ -28,6 +28,7 @@ deleted timesheet en Deleted
deletes this field timesheet en Deletes this field deletes this field timesheet en Deletes this field
determines the order the fields are displayed timesheet en Determines the order the fields are displayed determines the order the fields are displayed timesheet en Determines the order the fields are displayed
directory with documents to insert entries timesheet en Directory with documents to insert entries directory with documents to insert entries timesheet en Directory with documents to insert entries
disable timers timesheet en Disable timers
each value is a line like <id>[=<label>] timesheet en Each value is a line like <id>[=<label>] each value is a line like <id>[=<label>] timesheet en Each value is a line like <id>[=<label>]
edit status common en Edit status edit status common en Edit status
edit this entry timesheet en Edit this entry edit this entry timesheet en Edit this entry
@ -37,6 +38,7 @@ entry deleted timesheet en Entry deleted.
entry saved timesheet en Entry saved. entry saved timesheet en Entry saved.
error deleting the entry!!! timesheet en Error deleting the entry! error deleting the entry!!! timesheet en Error deleting the entry!
error saving the entry!!! timesheet en Error saving the entry! error saving the entry!!! timesheet en Error saving the entry!
error storing working time timesheet en Error storing working time
events timesheet en Events events timesheet en Events
example {{if n_prefix~mr~hello mr.~hello ms.}} - search the field "n_prefix", for "mr", if found, write hello mr., else write hello ms. timesheet en Example {{IF n_prefix~Mr~Hello Mr.~Hello Ms.}} - search the field "n_prefix", for "Mr", if found, write Hello Mr., else write Hello Ms. example {{if n_prefix~mr~hello mr.~hello ms.}} - search the field "n_prefix", for "mr", if found, write hello mr., else write hello ms. timesheet en Example {{IF n_prefix~Mr~Hello Mr.~Hello Ms.}} - search the field "n_prefix", for "Mr", if found, write Hello Mr., else write Hello Ms.
example {{letterprefixcustom n_prefix title n_family}} - example: mr dr. james miller timesheet en Example {{LETTERPREFIXCUSTOM n_prefix title n_family}} - Example: Mr Dr. James Miller example {{letterprefixcustom n_prefix title n_family}} - example: mr dr. james miller timesheet en Example {{LETTERPREFIXCUSTOM n_prefix title n_family}} - Example: Mr Dr. James Miller
@ -95,7 +97,10 @@ only admin admin en Only admin
only admin can edit this status admin en Only admins can edit timesheets with this status only admin can edit this status admin en Only admins can edit timesheets with this status
or endtime timesheet en or end time or endtime timesheet en or end time
order timesheet en Order order timesheet en Order
overwrite common en Overwrite
overwriting start or stop time timesheet en Overwriting start or stop time
parent admin en Parent parent admin en Parent
pause common en Pause
permission denied!!! timesheet en Permission denied! permission denied!!! timesheet en Permission denied!
permissions error - %1 could not %2 timesheet en Permissions error - %1 could not %2 permissions error - %1 could not %2 timesheet en Permissions error - %1 could not %2
prevent deleting admin en Prevent deleting prevent deleting admin en Prevent deleting
@ -128,6 +133,7 @@ status timesheet en Status
status deleted. timesheet en Status deleted. status deleted. timesheet en Status deleted.
status of created timesheets timesheet en Status of created timesheets status of created timesheets timesheet en Status of created timesheets
status updated. timesheet en Status updated. status updated. timesheet en Status updated.
stop common en Stop
sum %1: timesheet en Sum %1: sum %1: timesheet en Sum %1:
tag to mark positions for address labels timesheet en Tag to mark positions for address labels tag to mark positions for address labels timesheet en Tag to mark positions for address labels
the document can contain placeholder like {{%3}}, to be replaced with the data (%1full list of placeholder names%2). timesheet en The document can contain placeholder like {{%3}}, to be replaced with the data (%1full list of placeholder names%2). the document can contain placeholder like {{%3}}, to be replaced with the data (%1full list of placeholder names%2). timesheet en The document can contain placeholder like {{%3}}, to be replaced with the data (%1full list of placeholder names%2).
@ -138,6 +144,7 @@ this month timesheet en This month
this week timesheet en This week this week timesheet en This week
this year timesheet en This year this year timesheet en This year
ticket modified by %1 at %2 timesheet en Ticket modified by %1 at %2 ticket modified by %1 at %2 timesheet en Ticket modified by %1 at %2
timer common en Timer
timesheet common en Time Sheet timesheet common en Time Sheet
timesheet csv export timesheet en TimeSheet CSV export timesheet csv export timesheet en TimeSheet CSV export
timesheet csv import timesheet en TimeSheet CSV import timesheet csv import timesheet en TimeSheet CSV import
@ -162,6 +169,9 @@ what should be done with unknown values? timesheet en What should be done with u
when you merge entries into documents, they will be stored here. if no directory is provided, they will be stored in your home directory (/home/ralf) timesheet en When you merge entries into documents, they will be stored here. If no directory is provided, they will be stored in your home directory (/home/ralf) when you merge entries into documents, they will be stored here. if no directory is provided, they will be stored in your home directory (/home/ralf) timesheet en When you merge entries into documents, they will be stored here. If no directory is provided, they will be stored in your home directory (/home/ralf)
will be created when saving ... common en Will be created when saving ... will be created when saving ... common en Will be created when saving ...
working time common en Working time working time common en Working time
working time and timer timesheet en Working time and timer
working time from %1 timesheet en Working time from %1
working time of %1 hours stored timesheet en Working time of %1 hours stored
yes, only admins can purge deleted items admin en Yes, only admins can purge deleted items yes, only admins can purge deleted items admin en Yes, only admins can purge deleted items
yes, users can purge their deleted items admin en Yes, users can purge their deleted items yes, users can purge their deleted items admin en Yes, users can purge their deleted items
yesterday timesheet en Yesterday yesterday timesheet en Yesterday

View File

@ -194,6 +194,10 @@ class Events extends Api\Storage\Base
$timer['start'] = (new Api\DateTime($timer['start'], new \DateTimeZone('UTC')))->format(Api\DateTime::ET2); $timer['start'] = (new Api\DateTime($timer['start'], new \DateTimeZone('UTC')))->format(Api\DateTime::ET2);
} }
} }
// send timer configuration to client-side
$config = Api\Config::read(self::APP);
$state['disable'] = $config['disable_timer'] ?? [];
return $state; return $state;
} }
catch (\Exception $e) { catch (\Exception $e) {

View File

@ -43,7 +43,15 @@
</select> </select>
</row> </row>
<row> <row>
<description value="Working time" span="all" class="subHeader"/> <description value="Working time and timer" span="all" class="subHeader"/>
</row>
<row>
<description value="Disable timers"/>
<select id="newsettings[disable_timer]" multiple="true">
<option value="overall">Working time</option>
<option value="specific">Timer</option>
<option value="overwrite">Overwriting start or stop time</option>
</select>
</row> </row>
<row> <row>
<description value="Category for 'Working time'"/> <description value="Category for 'Working time'"/>