Преглед изворни кода

Ticket #5425 - Tasks: Functionality improvements. Stage 2.

AntonLV пре 7 месеци
родитељ
комит
3ccf73312c

+ 38 - 0
modules/boonex/tasks/classes/BxTasksFormTime.php

@@ -33,6 +33,44 @@ class BxTasksFormTime extends BxTemplFormView
             }
             }
         }
         }
     }
     }
+    
+    public function initChecker ($aValues = [], $aSpecificValues = [])
+    {
+        if(($iContentId = $this->aInputs['object_id']['value'] ?? 0) && ($iProfileId = bx_get_logged_profile_id())) {
+            $aTimer = $this->_oModule->_oDb->getTimers([
+                'sample' => 'content_profile_ids', 
+                'content_id' => $iContentId, 
+                'profile_id' => $iProfileId
+            ]);
+
+            if($aTimer && is_array($aTimer) && ($iDuration = (int)$aTimer['duration']) && ($sKey = 'value') && isset($this->aInputs[$sKey])) {
+                list($iHours, $iMinutes) = $this->_oModule->_oConfig->timeI2A($iDuration, true);
+
+                foreach($this->aInputs[$sKey] as $mixedKey => $mixedValue) {
+                    if(!is_numeric($mixedKey) || !is_array($mixedValue))
+                        continue;
+
+                    switch($this->aInputs[$sKey][$mixedKey]['name']) {
+                        case 'value_h':
+                            $this->aInputs[$sKey][$mixedKey]['value'] = $iHours;
+                            break;
+
+                        case 'value_m':
+                            $this->aInputs[$sKey][$mixedKey]['value'] = $iMinutes + 1;
+                            break;
+                    }
+                }
+
+                $this->aInputs['timer_id'] = [
+                    'type' => 'hidden',
+                    'name' => 'timer_id',
+                    'value' => $aTimer['id']
+                ];
+            }
+        }
+
+        return parent::initChecker ($aValues, $aSpecificValues);
+    }
 }
 }
 
 
 /** @} */
 /** @} */

+ 132 - 0
modules/boonex/tasks/classes/BxTasksMenuTimer.php

@@ -0,0 +1,132 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT 
+ * @defgroup    Tasks Tasks
+ * @ingroup     UnaModules
+ *
+ * @{
+ */
+
+class BxTasksMenuTimer extends BxTemplMenuCustom
+{
+    protected $_sModule;
+    protected $_oModule;
+
+    protected $_iContentId;
+    protected $_iProfileId;
+
+    protected $_bShowAsButton;
+    protected $_bShowTitle;
+
+    public function __construct($aObject, $oTemplate = false)
+    {
+        parent::__construct($aObject, $oTemplate);
+
+        $this->_sModule = 'bx_tasks';
+        $this->_oModule = BxDolModule::getInstance($this->_sModule);
+
+        $this->_iContentId = 0;
+        $this->_iProfileId = 0;
+
+        $this->_bShowAsButton = true;
+        $this->_bShowTitle = true;
+    }
+
+    public function setParams($iContentId, $iProfileId)
+    {
+        $this->_iContentId = $iContentId;
+        $this->_iProfileId = $iProfileId;
+    }
+
+    protected function getMenuItemsRaw ()
+    {
+        $sPrefix = str_replace('_', '-', $this->_oModule->_oConfig->getName());
+        $sJsObject = $this->_oModule->_oConfig->getJsObject('timer');
+
+        $aTimer = $this->_oModule->_oDb->getTimers([
+            'sample' => 'content_profile_ids', 
+            'content_id' => $this->_iContentId, 
+            'profile_id' => $this->_iProfileId
+        ]);
+
+        $aItems = [];
+        if($aTimer && is_array($aTimer)) {
+            if((int)$aTimer['started'] > 0)
+                $aItems = [
+                    ['name' => 'stop', 'class' => '', 'link' => 'javascript:void(0)', 'onclick' => 'javascript:' . $sJsObject . '.stop(this, ' . $this->_iContentId . ', ' . $this->_iProfileId . ')', 'target' => '_self', 'title' => _t('_bx_tasks_txt_timer_stop')],
+                ];
+            else
+                $aItems = [
+                    ['name' => 'resume', 'class' => '', 'link' => 'javascript:void(0)', 'onclick' => 'javascript:' . $sJsObject . '.resume(this, ' . $this->_iContentId . ', ' . $this->_iProfileId . ')', 'target' => '_self', 'title' => _t('_bx_tasks_txt_timer_resume')],
+                    ['name' => 'clear', 'class' => '', 'link' => 'javascript:void(0)', 'onclick' => 'javascript:' . $sJsObject . '.clear(this, ' . $this->_iContentId . ', ' . $this->_iProfileId . ')', 'target' => '_self', 'title' => _t('_bx_tasks_txt_timer_clear')],
+                    ['name' => 'log', 'class' => '', 'link' => '', 'onclick' => '', 'target' => '', 'title' => ''],
+                ];
+        }
+        else {
+            $aItems = [
+                ['name' => 'start', 'class' => '', 'link' => 'javascript:void(0)', 'onclick' => 'javascript:' . $sJsObject . '.start(this, ' . $this->_iContentId . ', ' . $this->_iProfileId . ')', 'target' => '_self', 'title' => _t('_bx_tasks_txt_timer_start')],
+                ['name' => 'time', 'class' => '', 'link' => '', 'onclick' => '', 'target' => '', 'title' => ''],
+            ];
+        }
+
+        return $aItems;
+    }
+
+    protected function _getMenuItemTime($aItem, $aParams = [])
+    {
+        $CNF = &$this->_oModule->_oConfig->CNF;
+
+        $iId = $this->_iContentId;
+
+        $sObject = $CNF['OBJECT_REPORTS_TIME'];
+        $oObject = !empty($sObject) ? BxDolReport::getObjectInstance($sObject, $iId) : false;
+        if(!$oObject || !$oObject->isEnabled())
+            return '';
+
+        $aObjectOptions = [
+            'dynamic_mode' => $this->_bDynamicMode,
+            'show_do_report_as_button' => $this->_bShowAsButton,
+            'show_do_report_label' => $this->_bShowTitle,
+            'show_do_report_icon' => false,
+            'show_counter' => false
+        ];
+        if($aParams && is_array($aParams))
+            $aObjectOptions = array_merge($aObjectOptions, $aParams);
+
+        if($this->_bIsApi)
+            return [
+                'id' => $aItem['id'],
+                'name' => $aItem['name'],
+                'display_type' => 'element',
+                'data' => $oObject->getElementApi($aObjectOptions)
+            ];
+
+    	return $oObject->getElementBlock($aObjectOptions);
+    }
+
+    protected function _getMenuItemLog($aItem)
+    {
+        return $this->_getMenuItemTime($aItem, [
+            'do_report_label' => '_bx_tasks_txt_timer_log'
+        ]);
+    }
+
+    protected function _getMenuItemDefault($aItem)
+    {
+        if($this->_bIsApi)
+            return $aItem;
+
+        $aItem['class_wrp'] = 'bx-tasks-timer-action' . (!empty($aItem['class_wrp']) ? ' ' . $aItem['class_wrp'] : '');
+
+        if($this->_bShowAsButton)
+            $aItem['class_link'] = 'bx-btn' . (isset($aItem['primary']) && (int)$aItem['primary'] == 1 ? ' bx-btn-primary' : '') . (!empty($aItem['class_link']) ? ' ' . $aItem['class_link'] : '');
+
+        if(!$this->_bShowTitle)
+            $aItem['bx_if:title']['condition'] = false;
+
+        return parent::_getMenuItemDefault ($aItem);
+    }
+}
+
+/** @} */

+ 9 - 0
modules/boonex/tasks/classes/BxTasksModule.php

@@ -321,6 +321,15 @@ class BxTasksModule extends BxBaseModTextModule implements iBxDolCalendarService
                     $aResult = ['code' => 0];
                     $aResult = ['code' => 0];
                 break;
                 break;
 
 
+            case 'reload':
+                $aTimer = $this->getTimer($iContentId, $iProfileId);
+
+                $aResult = [
+                    'code' => 0,
+                    'started' => $aTimer && ($aTimer['started'] ?? 0) != 0
+                ];
+                break;
+
             case 'log':
             case 'log':
                 $aTimer = $this->getTimer($iContentId, $iProfileId);
                 $aTimer = $this->getTimer($iContentId, $iProfileId);
                 if(!$aTimer || !is_array($aTimer) || !$aTimer['duration'])
                 if(!$aTimer || !is_array($aTimer) || !$aTimer['duration'])

+ 8 - 24
modules/boonex/tasks/classes/BxTasksTemplate.php

@@ -8,9 +8,8 @@
  * @{
  * @{
  */
  */
 
 
-/*
- * Module representation.
- */
+require_once('BxTasksMenuTimer.php');
+
 class BxTasksTemplate extends BxBaseModTextTemplate
 class BxTasksTemplate extends BxBaseModTextTemplate
 {
 {
     public function __construct(&$oConfig, &$oDb)
     public function __construct(&$oConfig, &$oDb)
@@ -101,6 +100,7 @@ class BxTasksTemplate extends BxBaseModTextTemplate
 
 
     public function entryTimer ($iContentId, $iProfileId)
     public function entryTimer ($iContentId, $iProfileId)
     {
     {
+        $this->addCss(['timer.css']);
         $this->addJs(['timer.js']);
         $this->addJs(['timer.js']);
         return $this->getTimer($iContentId, $iProfileId) . $this->getJsCodeTimer('timer', [], [
         return $this->getTimer($iContentId, $iProfileId) . $this->getJsCodeTimer('timer', [], [
             'content_id' => $iContentId,
             'content_id' => $iContentId,
@@ -176,7 +176,6 @@ class BxTasksTemplate extends BxBaseModTextTemplate
         $bTimer = $aTimer && is_array($aTimer);
         $bTimer = $aTimer && is_array($aTimer);
         $bStarted = $bTimer && (int)$aTimer['started'] > 0;
         $bStarted = $bTimer && (int)$aTimer['started'] > 0;
 
 
-        $aActions = [];
         $iHours = $iMinutes = $iSeconds = 0;
         $iHours = $iMinutes = $iSeconds = 0;
         if($bTimer) {
         if($bTimer) {
             $iDuration = (int)$aTimer['duration'];
             $iDuration = (int)$aTimer['duration'];
@@ -184,30 +183,15 @@ class BxTasksTemplate extends BxBaseModTextTemplate
                 $iDuration += time() - (int)$aTimer['started'];
                 $iDuration += time() - (int)$aTimer['started'];
 
 
             list($iHours, $iMinutes, $iSeconds) = $this->_oConfig->timeI2A($iDuration, true);
             list($iHours, $iMinutes, $iSeconds) = $this->_oConfig->timeI2A($iDuration, true);
-
-            $aActions = [];
-            if($bStarted)
-                $aActions = [
-                    ['id' => $sPrefix . '-stop', 'name' => $sPrefix . '-stop', 'class' => '', 'link' => 'javascript:void(0)', 'onclick' => 'javascript:' . $sJsObject . '.stop(this, ' . $iContentId . ', ' . $iProfileId . ')', 'target' => '_self', 'title' => _t('_bx_tasks_txt_timer_stop')],
-                ];
-            else
-                $aActions = [
-                    ['id' => $sPrefix . '-resume', 'name' => $sPrefix . '-resume', 'class' => '', 'link' => 'javascript:void(0)', 'onclick' => 'javascript:' . $sJsObject . '.resume(this, ' . $iContentId . ', ' . $iProfileId . ')', 'target' => '_self', 'title' => _t('_bx_tasks_txt_timer_resume')],
-                    ['id' => $sPrefix . '-clear', 'name' => $sPrefix . '-clear', 'class' => '', 'link' => 'javascript:void(0)', 'onclick' => 'javascript:' . $sJsObject . '.clear(this, ' . $iContentId . ', ' . $iProfileId . ')', 'target' => '_self', 'title' => _t('_bx_tasks_txt_timer_clear')],
-                    ['id' => $sPrefix . '-log', 'name' => $sPrefix . '-log', 'class' => '', 'link' => 'javascript:void(0)', 'onclick' => 'javascript:' . $sJsObject . '.log(this, ' . $iContentId . ', ' . $iProfileId . ')', 'target' => '_self', 'title' => _t('_bx_tasks_txt_timer_log')],
-                ];
-        }
-        else {
-            $aActions = [
-                ['id' => $sPrefix . '-start', 'name' => $sPrefix . '-start', 'class' => '', 'link' => 'javascript:void(0)', 'onclick' => 'javascript:' . $sJsObject . '.start(this, ' . $iContentId . ', ' . $iProfileId . ')', 'target' => '_self', 'title' => _t('_bx_tasks_txt_timer_start')],
-            ];
         }
         }
 
 
-        $oActions = new BxTemplMenu([
-            'template' => 'menu_buttons_hor.html', 
+        $oActions = new BxTasksMenuTimer([
+            'object' => $sPrefix . '_timer',
+            'template' => 'menu_custom_hor.html', 
             'menu_id' => $this->_oConfig->getHtmlIds('timer_actions'), 
             'menu_id' => $this->_oConfig->getHtmlIds('timer_actions'), 
-            'menu_items' => $aActions
+            'persistent' => 0
         ]);
         ]);
+        $oActions->setParams($iContentId, $iProfileId);
 
 
         return $this->parseHtmlByName('entry-timer.html', [
         return $this->parseHtmlByName('entry-timer.html', [
             'html_id' => $this->_oConfig->getHtmlIds('timer') . $iContentId . '-' . $iProfileId,
             'html_id' => $this->_oConfig->getHtmlIds('timer') . $iContentId . '-' . $iProfileId,

+ 23 - 1
modules/boonex/tasks/classes/BxTasksTime.php

@@ -147,6 +147,25 @@ class BxTasksTime extends BxTemplReport
             if(($oSockets = BxDolSockets::getInstance()) && $oSockets->isEnabled())
             if(($oSockets = BxDolSockets::getInstance()) && $oSockets->isEnabled())
                 $oSockets->sendEvent($this->getSocketName(), $iObjectId, 'reported', json_encode($this->_returnReportDataForSocket($aResult)));
                 $oSockets->sendEvent($this->getSocketName(), $iObjectId, 'reported', json_encode($this->_returnReportDataForSocket($aResult)));
 
 
+            /*
+             * If timer is attached, clear it and initiate reloading.
+             */
+            if(($iTimerId = (int)$oForm->getCleanValue('timer_id'))) {
+                $aTimer = $this->_oModule->_oDb->getTimers([
+                    'sample' => 'id', 
+                    'id' => $iTimerId
+                ]);
+
+                if($aTimer && ($iContentId = $aTimer['content_id'] ?? 0) && ($iProfileId = $aTimer['profile_id'] ?? 0)) {
+                    $this->_oModule->serviceProcessTimer('clear', $iContentId, $iProfileId);
+
+                    $aResult = array_merge($aResult, [
+                        'label_title' => _t('_bx_tasks_txt_timer_log'),
+                        'eval' => $aResult['eval'] . '; ' . $this->_oModule->_oConfig->getJsObject('timer'). '.reload(this, ' . $iContentId . ', ' . $iProfileId . ');'
+                    ]);
+                } 
+            }
+
             return $aResult;
             return $aResult;
         }
         }
 
 
@@ -196,8 +215,11 @@ class BxTasksTime extends BxTemplReport
     	return $bPerformed && $this->isUndo() ? 'stopwatch' : 'stopwatch';
     	return $bPerformed && $this->isUndo() ? 'stopwatch' : 'stopwatch';
     }
     }
 
 
-    protected function _getTitleDoReport($bPerformed)
+    protected function _getTitleDoReport($bPerformed, $aParams = [])
     {
     {
+        if(($sTitle = $aParams['do_report_label'] ?? false))
+            return [$sTitle];
+
         return ['_bx_tasks_report_time_do_' . ($bPerformed && $this->isUndo() ? 'un' : '') . 'report'];
         return ['_bx_tasks_report_time_do_' . ($bPerformed && $this->isUndo() ? 'un' : '') . 'report'];
     }
     }
 }
 }

+ 1 - 4
modules/boonex/tasks/install/sql/enable.sql

@@ -138,7 +138,6 @@ INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title_system`, `t
 ('bx_tasks_timers', 1, 'bx_tasks', '_bx_tasks_page_block_title_system_timers', '_bx_tasks_page_block_title_timers', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:8:"bx_tasks";s:6:"method";s:16:"get_block_timers";}', 0, 1, 0);
 ('bx_tasks_timers', 1, 'bx_tasks', '_bx_tasks_page_block_title_system_timers', '_bx_tasks_page_block_title_timers', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:8:"bx_tasks";s:6:"method";s:16:"get_block_timers";}', 0, 1, 0);
 
 
 
 
-
 -- MENU: add to site menu
 -- MENU: add to site menu
 SET @iSiteMenuOrder = (SELECT `order` FROM `sys_menu_items` WHERE `set_name` = 'sys_site' AND `active` = 1 AND `order` < 9999 ORDER BY `order` DESC LIMIT 1);
 SET @iSiteMenuOrder = (SELECT `order` FROM `sys_menu_items` WHERE `set_name` = 'sys_site' AND `active` = 1 AND `order` < 9999 ORDER BY `order` DESC LIMIT 1);
 INSERT INTO `sys_menu_items` (`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
 INSERT INTO `sys_menu_items` (`set_name`, `module`, `name`, `title_system`, `title`, `link`, `onclick`, `target`, `icon`, `submenu_object`, `visible_for_levels`, `active`, `copyable`, `order`) VALUES 
@@ -161,7 +160,6 @@ INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `titl
 ('bx_tasks_entry_attachments', 'bx_tasks', 'file_html5', '_bx_tasks_menu_item_title_system_cpa_file_html5', '_bx_tasks_menu_item_title_cpa_file_html5', 'javascript:void(0)', 'javascript:{js_object_uploader_files_html5}.showUploaderForm();', '_self', 'file', '', '', 2147483647, '', 1, 0, 1, 7);
 ('bx_tasks_entry_attachments', 'bx_tasks', 'file_html5', '_bx_tasks_menu_item_title_system_cpa_file_html5', '_bx_tasks_menu_item_title_cpa_file_html5', 'javascript:void(0)', 'javascript:{js_object_uploader_files_html5}.showUploaderForm();', '_self', 'file', '', '', 2147483647, '', 1, 0, 1, 7);
 
 
 -- MENU: actions menu for view entry 
 -- MENU: actions menu for view entry 
-
 INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
 INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
 ('bx_tasks_view', '_bx_tasks_menu_title_view_entry', 'bx_tasks_view', 'bx_tasks', 9, 0, 1, 'BxTasksMenuView', 'modules/boonex/tasks/classes/BxTasksMenuView.php');
 ('bx_tasks_view', '_bx_tasks_menu_title_view_entry', 'bx_tasks_view', 'bx_tasks', 9, 0, 1, 'BxTasksMenuView', 'modules/boonex/tasks/classes/BxTasksMenuView.php');
 
 
@@ -176,7 +174,6 @@ INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `titl
 
 
 
 
 -- MENU: all actions menu for view entry 
 -- MENU: all actions menu for view entry 
-
 INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
 INSERT INTO `sys_objects_menu`(`object`, `title`, `set_name`, `module`, `template_id`, `deletable`, `active`, `override_class_name`, `override_class_file`) VALUES 
 ('bx_tasks_view_actions', '_sys_menu_title_view_actions', 'bx_tasks_view_actions', 'bx_tasks', 15, 0, 1, 'BxTasksMenuViewActions', 'modules/boonex/tasks/classes/BxTasksMenuViewActions.php');
 ('bx_tasks_view_actions', '_sys_menu_title_view_actions', 'bx_tasks_view_actions', 'bx_tasks', 15, 0, 1, 'BxTasksMenuViewActions', 'modules/boonex/tasks/classes/BxTasksMenuViewActions.php');
 
 
@@ -187,7 +184,7 @@ INSERT INTO `sys_menu_items`(`set_name`, `module`, `name`, `title_system`, `titl
 ('bx_tasks_view_actions', 'bx_tasks', 'edit-task', '_bx_tasks_menu_item_title_system_edit_entry', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 10),
 ('bx_tasks_view_actions', 'bx_tasks', 'edit-task', '_bx_tasks_menu_item_title_system_edit_entry', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 10),
 ('bx_tasks_view_actions', 'bx_tasks', 'edit-task-state', '_bx_tasks_menu_item_title_system_edit_entry_state', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 12),
 ('bx_tasks_view_actions', 'bx_tasks', 'edit-task-state', '_bx_tasks_menu_item_title_system_edit_entry_state', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 12),
 ('bx_tasks_view_actions', 'bx_tasks', 'delete-task', '_bx_tasks_menu_item_title_system_delete_entry', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 20),
 ('bx_tasks_view_actions', 'bx_tasks', 'delete-task', '_bx_tasks_menu_item_title_system_delete_entry', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 20),
-('bx_tasks_view_actions', 'bx_tasks', 'report-time', '_bx_tasks_menu_item_title_system_report_time', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 25),
+('bx_tasks_view_actions', 'bx_tasks', 'report-time', '_bx_tasks_menu_item_title_system_report_time', '', '', '', '', '', '', '', 0, 2147483647, '', 0, 0, 25),
 ('bx_tasks_view_actions', 'bx_tasks', 'set-completed', '_bx_tasks_menu_item_title_system_set_completed', '_bx_tasks_menu_item_title_set_completed', 'javascript:void(0)', 'javascript:{js_object}.setCompletedByMenu({content_id}, 1, this);', '', 'check', '', '', 0, 2147483647, 'a:3:{s:6:"module";s:8:"bx_tasks";s:6:"method";s:22:"check_allowed_complete";s:6:"params";a:1:{i:0;s:12:"{content_id}";}}', 1, 0, 30),
 ('bx_tasks_view_actions', 'bx_tasks', 'set-completed', '_bx_tasks_menu_item_title_system_set_completed', '_bx_tasks_menu_item_title_set_completed', 'javascript:void(0)', 'javascript:{js_object}.setCompletedByMenu({content_id}, 1, this);', '', 'check', '', '', 0, 2147483647, 'a:3:{s:6:"module";s:8:"bx_tasks";s:6:"method";s:22:"check_allowed_complete";s:6:"params";a:1:{i:0;s:12:"{content_id}";}}', 1, 0, 30),
 ('bx_tasks_view_actions', 'bx_tasks', 'set-uncompleted', '_bx_tasks_menu_item_title_system_set_uncompleted', '_bx_tasks_menu_item_title_set_uncompleted', 'javascript:void(0)', 'javascript:{js_object}.setCompletedByMenu({content_id}, 0, this);', '', 'circle', '', '', 0, 2147483647, 'a:3:{s:6:"module";s:8:"bx_tasks";s:6:"method";s:24:"check_allowed_uncomplete";s:6:"params";a:1:{i:0;s:12:"{content_id}";}}', 1, 0, 35),
 ('bx_tasks_view_actions', 'bx_tasks', 'set-uncompleted', '_bx_tasks_menu_item_title_system_set_uncompleted', '_bx_tasks_menu_item_title_set_uncompleted', 'javascript:void(0)', 'javascript:{js_object}.setCompletedByMenu({content_id}, 0, this);', '', 'circle', '', '', 0, 2147483647, 'a:3:{s:6:"module";s:8:"bx_tasks";s:6:"method";s:24:"check_allowed_uncomplete";s:6:"params";a:1:{i:0;s:12:"{content_id}";}}', 1, 0, 35),
 ('bx_tasks_view_actions', 'bx_tasks', 'approve', '_sys_menu_item_title_system_va_approve', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 40),
 ('bx_tasks_view_actions', 'bx_tasks', 'approve', '_sys_menu_item_title_system_va_approve', '', '', '', '', '', '', '', 0, 2147483647, '', 1, 0, 40),

+ 17 - 0
modules/boonex/tasks/js/timer.js

@@ -68,6 +68,12 @@ BxTasksTimer.prototype.resume = function (oSource, iContentId, iProfileId) {
     this._performAction(oSource, 'resume', iContentId, iProfileId);
     this._performAction(oSource, 'resume', iContentId, iProfileId);
 };
 };
 
 
+BxTasksTimer.prototype.reload = function (oSource, iContentId, iProfileId) {
+    this._clearTimer(iContentId, iProfileId);
+
+    this._performAction(oSource, 'reload', iContentId, iProfileId);
+};
+
 BxTasksTimer.prototype.log = function (oSource, iContentId, iProfileId) {
 BxTasksTimer.prototype.log = function (oSource, iContentId, iProfileId) {
     this._clearTimer(iContentId, iProfileId);
     this._clearTimer(iContentId, iProfileId);
 
 
@@ -87,15 +93,26 @@ BxTasksTimer.prototype.clear = function (oSource, iContentId, iProfileId) {
 BxTasksTimer.prototype.onPerformActionStart = function(oData) {
 BxTasksTimer.prototype.onPerformActionStart = function(oData) {
     this._onPerformActionAndSet(oData);
     this._onPerformActionAndSet(oData);
 };
 };
+
 BxTasksTimer.prototype.onPerformActionStop = function(oData) {
 BxTasksTimer.prototype.onPerformActionStop = function(oData) {
     this._onPerformAction(oData);
     this._onPerformAction(oData);
 };
 };
+
 BxTasksTimer.prototype.onPerformActionResume = function(oData) {
 BxTasksTimer.prototype.onPerformActionResume = function(oData) {
     this._onPerformActionAndSet(oData);
     this._onPerformActionAndSet(oData);
 };
 };
+
+BxTasksTimer.prototype.onPerformActionReload = function(oData) {
+    if(oData && oData.started)
+        this._onPerformActionAndSet(oData);
+    else
+        this._onPerformAction(oData);
+};
+
 BxTasksTimer.prototype.onPerformActionLog = function(oData) {
 BxTasksTimer.prototype.onPerformActionLog = function(oData) {
     this._onPerformAction(oData);
     this._onPerformAction(oData);
 };
 };
+
 BxTasksTimer.prototype.onPerformActionClear = function(oData) {
 BxTasksTimer.prototype.onPerformActionClear = function(oData) {
     this._onPerformAction(oData);
     this._onPerformAction(oData);
 };
 };

+ 15 - 0
modules/boonex/tasks/template/css/timer.css

@@ -0,0 +1,15 @@
+.bx-tasks-actions .bx-menu-custom {
+    justify-content: center;
+}
+
+.bx-tasks-actions .bx-menu-custom li {
+    margin-left: 1.0rem;
+}
+.bx-tasks-actions .bx-menu-custom li:first-child {
+    margin-left: 0;
+}
+
+.bx-tasks-actions .bx-menu-custom li a {
+    padding-left: 1.5rem;
+    padding-right: 1.5rem;
+}