diff --git a/api/js/jsapi/egw_timer.js b/api/js/jsapi/egw_timer.js index 5734364055..c3f3025ff8 100644 --- a/api/js/jsapi/egw_timer.js +++ b/api/js/jsapi/egw_timer.js @@ -93,9 +93,10 @@ egw.extend('timer', egw.MODULE_GLOBAL, function() * * @param {string} _action * @param {string} _time + * @param {string} _app_id * @throws string error-message */ - function timerAction(_action, _time) + function timerAction(_action, _time, _app_id) { switch(_action) { @@ -126,9 +127,14 @@ egw.extend('timer', egw.MODULE_GLOBAL, function() stopTimer(specific, false, _time); break; } + // set _app_id on timer, if specified + if (_app_id && _action.substring(0, 8) === 'specific') + { + specific.app_id = _app_id; + } // persist state egw.request('timesheet.EGroupware\\Timesheet\\Events.ajax_event', [getState(_action, _time)]).then((tse_id) => { - if (_action.substring(8) === 'specific') + if (_action.substring(0, 8) === 'specific') { specific.id = tse_id; } @@ -247,9 +253,8 @@ egw.extend('timer', egw.MODULE_GLOBAL, function() * @param object _timer * @param string|Date|undefined _start to initialise with time different from current time * @param number|undefined _offset to set an offset - * @param string|undefined _app_id */ - function startTimer(_timer, _start, _offset, _app_id) + function startTimer(_timer, _start, _offset) { // update _timer state object if (_start) @@ -266,7 +271,7 @@ egw.extend('timer', egw.MODULE_GLOBAL, function() } _timer.offset = 0; // it's now set in start-time _timer.paused = false; - _timer.app_id = _app_id; + _timer.app_id = undefined; // update now update(); @@ -350,7 +355,7 @@ egw.extend('timer', egw.MODULE_GLOBAL, function() { if (specific.paused) { - startTimer(specific, undefined, undefined, _senders[0].id); + timerAction('specific-start', undefined, _senders[0].id); } else { @@ -364,7 +369,7 @@ egw.extend('timer', egw.MODULE_GLOBAL, function() Et2Dialog.BUTTONS_OK_CANCEL, Et2Dialog.QUESTION_MESSAGE, undefined, egw); return; } - startTimer(specific, undefined, undefined, _senders[0].id); + timerAction('specific-start', undefined, _senders[0].id); }, /** diff --git a/calendar/inc/class.calendar_uilist.inc.php b/calendar/inc/class.calendar_uilist.inc.php index a7788c1914..1758a90871 100644 --- a/calendar/inc/class.calendar_uilist.inc.php +++ b/calendar/inc/class.calendar_uilist.inc.php @@ -1105,6 +1105,27 @@ class calendar_uilist extends calendar_ui 'allowOnMultiple' => 'only', 'hideOnDisabled' => true, // show only one timesheet action in context menu ); + // if specific timer is NOT disabled, allow to book further time on existing sheets + $config = Api\Config::read('timesheet'); + if (!in_array('specific', $config['disable_timer'] ?? [])) + { + $actions['timesheet'] = [ + 'icon' => 'timesheet/navbar', + 'caption' => 'Timesheet', + 'group' => $group, + 'children' => array_map(static function($child) { unset($child['group']); return $child; }, [ + 'timesheet-interactive' => ['caption' => 'Add']+$actions['timesheet'], + 'timesheet-add' => ['caption' => 'Add']+$actions['timesheet-add'], + 'timer' => [ + 'icon' => 'timesheet/navbar', + 'caption' => 'Start timer', + 'onExecute' => 'javaScript:app.timesheet.egw.start_timer', + 'allowOnMultiple' => false, + ], + ]), + ]; + unset($actions['timesheet-add']); + } } $actions['ical'] = array( 'icon' => 'ical', @@ -1140,4 +1161,4 @@ class calendar_uilist extends calendar_ui //_debug_array($actions); return $actions; } -} +} \ No newline at end of file diff --git a/infolog/inc/class.infolog_ui.inc.php b/infolog/inc/class.infolog_ui.inc.php index fd60d361d9..2ba951cb6e 100644 --- a/infolog/inc/class.infolog_ui.inc.php +++ b/infolog/inc/class.infolog_ui.inc.php @@ -1294,6 +1294,17 @@ class infolog_ui ) ) ); + // if specific timer is NOT disabled, allow to book further time on existing sheets + $config = Api\Config::read('timesheet'); + if (!in_array('specific', $config['disable_timer'] ?? [])) + { + $actions['timesheet']['children']['timer'] = array( + 'icon' => 'timesheet/navbar', + 'caption' => 'Start timer', + 'onExecute' => 'javaScript:app.timesheet.egw.start_timer', + 'allowOnMultiple' => false, + ); + } } if ($GLOBALS['egw_info']['user']['apps']['tracker']) { @@ -2723,4 +2734,4 @@ class infolog_ui } return $fields; } -} +} \ No newline at end of file diff --git a/timesheet/inc/class.timesheet_ui.inc.php b/timesheet/inc/class.timesheet_ui.inc.php index bdaff99e3f..61fdff8e9f 100644 --- a/timesheet/inc/class.timesheet_ui.inc.php +++ b/timesheet/inc/class.timesheet_ui.inc.php @@ -112,26 +112,11 @@ class timesheet_ui extends timesheet_bo { if (!empty($event['tse_app']) && $event['tse_app'] !== TIMESHEET_APP && !empty($event['tse_app_id'])) { - // existing timesheets can be directly linked (takes care to not link multiple times) - if ($this->data['ts_id']) + if (!isset($this->data['link_to']['to_id'])) { - Api\Link::link(TIMESHEET_APP, $this->data['ts_id'], $event['tse_app'], $event['tse_app_id']); - } - // new timesheets will be linked on saving (need to check to not add multiple times) - else - { - if (!isset($this->data['link_to']['to_id'])) - { - $this->data['link_to']['to_id'] = []; - } - if (!in_array($app_id = [ - 'to_app' => $event['tse_app'], - 'to_id' => $event['tse_app_id'], - ], $this->data['link_to']['to_id'])) - { - $this->data['link_to']['to_id'][] = $app_id; - } + $this->data['link_to']['to_id'] = $this->data['ts_id'] ?? []; } + Api\Link::link(TIMESHEET_APP, $this->data['link_to']['to_id'], $event['tse_app'], $event['tse_app_id']); } } } diff --git a/timesheet/lang/egw_de.lang b/timesheet/lang/egw_de.lang index c9676952dd..853b42e768 100644 --- a/timesheet/lang/egw_de.lang +++ b/timesheet/lang/egw_de.lang @@ -130,7 +130,7 @@ show a quantity sum (eg. to sum up negative overtime) admin de Zeige eine Mengen skip record timesheet de Eintrag überspringen start timesheet de Start start & stop timer common de Zeitnehmer starten & stoppen -start timer timesheet de Zeitnehmer starten +start timer common de Zeitnehmer starten starttime timesheet de Startzeit starttime has to be before endtime !!! timesheet de Startzeit muss vor der Endzeit liegen !!! status timesheet de Status diff --git a/timesheet/lang/egw_en.lang b/timesheet/lang/egw_en.lang index 78ec512d8b..673939e0e3 100644 --- a/timesheet/lang/egw_en.lang +++ b/timesheet/lang/egw_en.lang @@ -130,7 +130,7 @@ show a quantity sum (eg. to sum up negative overtime) admin en Show a quantity s skip record timesheet en Skip record start timesheet en Start start & stop timer common en Start & stop timer -start timer timesheet en Start timer +start timer common en Start timer starttime timesheet en Start time starttime has to be before endtime !!! timesheet en Start time has to be before endtime! status timesheet en Status diff --git a/timesheet/src/Events.php b/timesheet/src/Events.php index e9766ad2d8..5c067cbbac 100644 --- a/timesheet/src/Events.php +++ b/timesheet/src/Events.php @@ -94,9 +94,9 @@ class Events extends Api\Storage\Base ($action === 'start' ? self::START : ($action === 'stop' ? self::STOP : self::PAUSE)); $app = $id = $ts_id = null; - if ($timer === 'specific' && !empty($state['app_id'])) + if ($timer === 'specific' && !empty($state['specific']['app_id'])) { - list($app, $id) = explode('::', $state['app_id'], 2); + list($app, $id) = explode('::', $state['specific']['app_id'], 2); if ($app === self::APP) { $ts_id = $id; @@ -127,7 +127,8 @@ class Events extends Api\Storage\Base Api\Json\Response::get()->message(lang('Error storing working time').': '.$e->getMessage(), 'error'); } } - return $this->data['tse_id']; + // return (new) tse_id + Api\Json\Response::get()->data($this->data['tse_id']); } /**