瀏覽代碼

Ticket #5186 - Tasks: Functionality improvements. Point 2.

AntonLV 1 年之前
父節點
當前提交
0288b84aa7

+ 35 - 23
inc/js/classes/BxDolReport.js

@@ -68,7 +68,8 @@ BxDolReport.prototype.onReport = function(oData, oElement)
         if(oData && oData.code != 0)
             return;
 
-        $(oElement).toggleClass('bx-report-reported');
+        if(oData && oData.reported != undefined)
+            $(oElement).toggleClass('bx-report-reported', oData.reported);
 
         if(oData && oData.disabled)
             $(oElement).removeAttr('onclick').addClass($(oElement).hasClass('bx-btn') ? 'bx-btn-disabled' : 'bx-report-disabled');
@@ -96,28 +97,39 @@ BxDolReport.prototype.onReport = function(oData, oElement)
 };
 
 BxDolReport.prototype.processJson = function(oData, oElement) {
-	oElement = oElement != undefined ? oElement : this._oParent;
-
-	var fContinue = function() {
-		//--- Show Popup
-	    if(oData && oData.popup != undefined) {
-	    	$('#' + oData.popup_id).remove();
-
-	    	$(oData.popup).hide().prependTo('body').dolPopup({
-	    		pointer: {
-	    			el: oElement
-	    		},
-	            fog: {
-					color: '#fff',
-					opacity: .7
-	            }
-	        });
-	    }
-
-	    //--- Evaluate JS code
-	    if (oData && oData.eval != undefined)
-	        eval(oData.eval);
-	};
+    oElement = oElement != undefined ? oElement : this._oParent;
+
+    var fContinue = function() {
+        //--- Show Popup
+        if(oData && oData.popup != undefined) {
+            $('#' + oData.popup_id).remove();
+
+            var oPopup = null;
+            var oOptions = {
+                pointer: {
+                    el: oElement
+                },
+                fog: {
+                    color: '#fff',
+                    opacity: .7
+                },
+                closeOnOuterClick: false
+            };
+
+            if(typeof(oData.popup) == 'object') {
+                oOptions = $.extend({}, oOptions, oData.popup.options);
+                oPopup = $(oData.popup.html);
+            }
+            else 
+                oPopup = $(oData.popup);
+
+            oPopup.hide().prependTo('body').dolPopup(oOptions);
+        }
+
+        //--- Evaluate JS code
+        if (oData && oData.eval != undefined)
+            eval(oData.eval);
+    };
 
     //--- Show Message
     if(oData && oData.message != undefined)

+ 14 - 3
modules/boonex/russian/data/langs/bx_tasks/ru.xml

@@ -105,8 +105,17 @@
     <string name="_bx_tasks_form_time_input_sys_action"><![CDATA[Действие]]></string>
     <string name="_bx_tasks_form_time_input_sys_submit"><![CDATA[Выполнить]]></string>
     <string name="_bx_tasks_form_time_input_submit"><![CDATA[Выполнить]]></string>
+    <string name="_bx_tasks_form_time_input_sys_cancel"><![CDATA[Отменить]]></string>
+    <string name="_bx_tasks_form_time_input_cancel"><![CDATA[Отменить]]></string>
+    <string name="_bx_tasks_form_time_input_sys_controls"><![CDATA[Управление]]></string>
     <string name="_bx_tasks_form_time_input_sys_value"><![CDATA[Время]]></string>
     <string name="_bx_tasks_form_time_input_value"><![CDATA[Время]]></string>
+    <string name="_bx_tasks_form_time_input_value_err"><![CDATA[Если Вы хотите внести временя, заполните это поле.]]></string>
+    <string name="_bx_tasks_form_time_input_sys_value_date"><![CDATA[Дата]]></string>
+    <string name="_bx_tasks_form_time_input_value_date"><![CDATA[Дата]]></string>
+    <string name="_bx_tasks_form_time_input_value_date_inf"><![CDATA[Оставьте поле пустым, чтобы использовать сегодняшнюю дату.]]></string>
+    <string name="_bx_tasks_form_time_input_sys_text"><![CDATA[Примечание]]></string>
+    <string name="_bx_tasks_form_time_input_text"><![CDATA[Примечание]]></string>
     <string name="_bx_tasks_popup_title_time_add"><![CDATA[Добавить время]]></string>
     <string name="_bx_tasks_popup_title_time_edit"><![CDATA[Редактировать время]]></string>
 
@@ -309,7 +318,7 @@
     <string name="_bx_tasks_grid_column_title_tm_object_id"><![CDATA[Задание]]></string>
     <string name="_bx_tasks_grid_column_title_tm_text"><![CDATA[Примечание]]></string>
     <string name="_bx_tasks_grid_column_title_tm_value"><![CDATA[Время]]></string>
-    <string name="_bx_tasks_grid_column_title_tm_date"><![CDATA[Добавлено]]></string>
+    <string name="_bx_tasks_grid_column_title_tm_value_date"><![CDATA[Дата]]></string>
     <string name="_bx_tasks_grid_action_title_tm_add"><![CDATA[Добавить]]></string>
     <string name="_bx_tasks_grid_action_title_tm_edit"><![CDATA[Редактировать]]></string>
     <string name="_bx_tasks_grid_action_title_tm_delete"><![CDATA[Удалить]]></string>
@@ -397,12 +406,14 @@
     <string name="_bx_tasks_txt_filter_all"><![CDATA[Все Задания]]></string>
     <string name="_bx_tasks_txt_filter_completed"><![CDATA[Завершенные Задания]]></string>
     <string name="_bx_tasks_txt_filter_uncompleted"><![CDATA[Незавершенные Задания]]></string>
-    <string name="_bx_tasks_txt_err_cannot_perform_action"><![CDATA[Невозможно выполнить действие. Пожалуйста, оповестите нас об этой проблеме.]]></string>
-    <string name="_bx_tasks_confirm_tasklist_deletion"><![CDATA[Вы удалите все задания, которые содержатся в этом списке заданий. Вы уверены?]]></string>
+    <string name="_bx_tasks_txt_total"><![CDATA[Total: {0}]]></string>
+    <string name="_bx_tasks_txt_estimate"><![CDATA[Estimate: {0}]]></string>
 
+    <string name="_bx_tasks_txt_err_cannot_perform_action"><![CDATA[Невозможно выполнить действие. Пожалуйста, оповестите нас об этой проблеме.]]></string>
     <string name="_bx_tasks_txt_err_cannot_perform_action"><![CDATA[Невозможно выполнить действие. Пожалуйста, оповестите нас об этой проблеме.]]></string>
     <string name="_bx_tasks_txt_msg_status_hidden"><![CDATA[Данное задание было скрыто.]]></string>
     <string name="_bx_tasks_txt_msg_status_pending"><![CDATA[Данное задание ожидает утверждения.]]></string>
+    <string name="_bx_tasks_txt_msg_confirm_tasklist_deletion"><![CDATA[Вы удалите все задания, которые содержатся в этом списке заданий. Вы уверены?]]></string>
 
     <!-- Notifications -->
     <string name="_bx_tasks_alert_action_completed_personal"><![CDATA[Задание завершено]]></string>

+ 1 - 1
modules/boonex/tasks/classes/BxTasksDb.php

@@ -13,7 +13,7 @@
  */
 class BxTasksDb extends BxBaseModTextDb
 {
-    function __construct(&$oConfig)
+    public function __construct(&$oConfig)
     {
         parent::__construct($oConfig);
     }

+ 3 - 1
modules/boonex/tasks/classes/BxTasksGridTime.php

@@ -28,11 +28,13 @@ class BxTasksGridTime extends BxTasksGridTimeAdministration
         $oForm = $this->_getFormObject($sAction);
         $oForm->initChecker();
         if($oForm->isSubmittedAndValid()) {
+            $iNow = time();
             $aValsToAdd = [
                 'author_id' => $this->_iLogged,
                 'author_nip' => bx_get_ip_hash(getVisitorIP()),
                 'value' => $this->_oModule->_oConfig->timeS2I($oForm->getCleanValue('value')),
-                'date' => time()
+                'value_date' => $oForm->getCleanValue('value_date') ?: $iNow,
+                'date' => $iNow
             ];
 
             $iTrackId = $oForm->insert($aValsToAdd);

+ 6 - 6
modules/boonex/tasks/classes/BxTasksGridTimeAdministration.php

@@ -144,13 +144,13 @@ class BxTasksGridTimeAdministration extends BxTemplGrid
     {
         return parent::_getCellDefault($this->_oModule->_oConfig->timeI2S($mixedValue), $sKey, $aField, $aRow);
     }
-    
-    protected function _getCellDate($mixedValue, $sKey, $aField, $aRow)
-    {
-        if($this->_bIsApi)
-            return ['type' => 'time', 'data' => $mixedValue];
 
-        return parent::_getCellDefault(bx_time_js($mixedValue, BX_FORMAT_DATE, true), $sKey, $aField, $aRow);
+    protected function _getCellValueDate($mixedValue, $sKey, $aField, $aRow)
+    {
+        return $this->_bIsApi ? [
+            'type' => 'time', 
+            'data' => $mixedValue
+        ] : parent::_getCellDefault($mixedValue ? bx_time_js($mixedValue, BX_FORMAT_DATE, true) : '', $sKey, $aField, $aRow);
     }
 
     protected function _getActionEdit($sType, $sKey, $a, $isSmall = false, $isDisabled = false, $aRow = [])

+ 38 - 37
modules/boonex/tasks/classes/BxTasksTemplate.php

@@ -48,7 +48,7 @@ class BxTasksTemplate extends BxBaseModTextTemplate
         $aPriorities = BxDolFormQuery::getDataItems($CNF['OBJECT_PRE_LIST_PRIORITIES']);
         $aStates = BxDolFormQuery::getDataItems($CNF['OBJECT_PRE_LIST_STATES']);
 
-        $aFilterValues = array();
+        $aFilterValues = [];
         if(isset($_COOKIE[$CNF['COOKIE_SETTING_KEY']]))
             $aFilterValues = json_decode($_COOKIE[$CNF['COOKIE_SETTING_KEY']], true);
 
@@ -66,20 +66,20 @@ class BxTasksTemplate extends BxBaseModTextTemplate
 
             $aTmplVarsTasks = [];
             foreach($aTasks as $aTask) {
-                $sState = $aStates[$aTask[$CNF['FIELD_STATE']]] ?? '';
-                if(!empty($aTask['time']))
-                    $sState .= ' ' . $this->_oConfig->timeI2S($aTask['time']);
-                if($bAllowManage && !empty($aTask['time_total']))
-                    $sState .= ' (' . $this->_oConfig->timeI2S($aTask['time_total']) . ')';
+                $sTime = '';
+                if(!empty($aTask['time_total']))
+                    $sTime = _t('_bx_tasks_txt_total', $this->_oConfig->timeI2S($aTask['time_total']) . (!empty($aTask['time']) ? ' (' . $this->_oConfig->timeI2S($aTask['time']) . ')' : ''));
+                if(!empty($aTask['estimate']))
+                    $sTime .= ' ' . _t('_bx_tasks_txt_estimate', $this->_oConfig->timeI2S(60 * (int)$aTask['estimate']));
 
                 $aMembers = $oConnection->getConnectedInitiators($aTask[$CNF['FIELD_ID']]);
 
                 $aTmplVarsMembers = [];
                 foreach($aMembers as $iMember)
                     if(($oProfile = BxDolProfile::getInstance($iMember)) !== false && !($oProfile instanceof BxDolProfileUndefined))
-                        $aTmplVarsMembers[] = array('info' => $oProfile->getUnit(0, array('template' => 'unit_wo_info')));
+                        $aTmplVarsMembers[] = ['info' => $oProfile->getUnit(0, ['template' => 'unit_wo_info'])];
 
-                $aTmplVarsTasks[] = array(
+                $aTmplVarsTasks[] = [
                     'id' => $aTask[$CNF['FIELD_ID']],
                     'title' => bx_process_output($aTask[$CNF['FIELD_TITLE']]),
                     'created' => bx_time_js($aTask[$CNF['FIELD_ADDED']]),
@@ -87,27 +87,28 @@ class BxTasksTemplate extends BxBaseModTextTemplate
                     'due' => $aTask[$CNF['FIELD_DUEDATE']] > 0 ? bx_time_js($aTask[$CNF['FIELD_DUEDATE']]) : '',
                     'type' => $aTypes[$aTask[$CNF['FIELD_TYPE']]] ?? '',
                     'priority' => $aPriorities[$aTask[$CNF['FIELD_PRIORITY']]] ?? '',
-                    'state' => $sState,
+                    'state' => $aStates[$aTask[$CNF['FIELD_STATE']]] ?? '',
+                    'time' => $sTime,
                     'bx_repeat:members' => $aTmplVarsMembers,
                     'badges' => $oModule->serviceGetBadges($aTask[$CNF['FIELD_ID']], true),
                     'url' => bx_absolute_url($oPermalinks->permalink('page.php?i=' . $CNF['URI_VIEW_ENTRY'] . '&id=' . $aTask[$CNF['FIELD_ID']])),
                     'object' => $this->_oConfig->getJsObject('tasks'),
-                    'bx_if:allow_manage' => array(
+                    'bx_if:allow_manage' => [
                         'condition' => $bAllowManage,
-                        'content' => array(
+                        'content' => [
                             'id' => $aTask[$CNF['FIELD_ID']],
                             'object' => $this->_oConfig->getJsObject('tasks'),
                             'checked' => $aTask[$CNF['FIELD_COMPLETED']] == 1 ? 'checked' : '',
-                        )
-                    ),
-                    'bx_if:deny_manage' => array(
+                        ]
+                    ],
+                    'bx_if:deny_manage' => [
                         'condition' => !$bAllowManage,
-                        'content' => array(
+                        'content' => [
                             'id' => $aTask[$CNF['FIELD_ID']],
                             'checked' => $aTask[$CNF['FIELD_COMPLETED']] == 1 ? 'checked' : '',
-                        )
-                    ),
-                );
+                        ]
+                    ]
+                ];
             }
 
             $sClass = $sCompleted = $sAll = "";
@@ -119,38 +120,38 @@ class BxTasksTemplate extends BxBaseModTextTemplate
                     $sAll = 'selected';
             }
 
-            $aTmplVarsLists[] = array(
-                'bx_if:allow_edit_list' => array(
+            $aTmplVarsLists[] = [
+                'bx_if:allow_edit_list' => [
                     'condition' => $bAllowAdd,
-                    'content' => array(
+                    'content' => [
                         'title' => $aList[$CNF['FIELD_TITLE']],
                         'context_id' => $iContextId,
                         'list_id' => $aList[$CNF['FIELD_ID']],
                         'object' => $this->_oConfig->getJsObject('tasks'),
-                    )
-                ),
-                'bx_if:allow_add' => array(
+                    ]
+                ],
+                'bx_if:allow_add' => [
                     'condition' => $bAllowAdd,
-                    'content' => array(
+                    'content' => [
                         'context_id' => $iContextId,
                         'list_id' => $aList[$CNF['FIELD_ID']],
                         'object' => $this->_oConfig->getJsObject('tasks'),
-                    )
-                ),
-                'bx_if:allow_delete_list' => array(
+                    ]
+                ],
+                'bx_if:allow_delete_list' => [
                     'condition' => $bAllowManage,
-                    'content' => array(
+                    'content' => [
                         'context_id' => $iContextId,
                         'list_id' => $aList[$CNF['FIELD_ID']],
                         'object' => $this->_oConfig->getJsObject('tasks'),
-                    )
-                ),
-                'bx_if:deny_edit_list' => array(
+                    ]
+                ],
+                'bx_if:deny_edit_list' => [
                     'condition' => !$bAllowAdd,
-                    'content' => array(
+                    'content' => [
                         'title' => $aList[$CNF['FIELD_TITLE']],
-                    )
-                ),
+                    ]
+                ],
                 'id' => $aList['id'],
                 'bx_repeat:tasks' =>  $aTmplVarsTasks,
                 'context_id' => $iContextId,
@@ -159,7 +160,7 @@ class BxTasksTemplate extends BxBaseModTextTemplate
                 'class' => $sClass,
                 'completed' => $sCompleted,
                 'all' => $sAll,
-            );
+            ];
         }
 
         $this->addCssJs();
@@ -169,7 +170,7 @@ class BxTasksTemplate extends BxBaseModTextTemplate
             'modules/base/general/js/|forms.js'
         ]);
 
-        return $this->getJsCode('tasks', ['t_confirm_block_deletion' => _t('_bx_tasks_confirm_tasklist_deletion')]) . $this->parseHtmlByName('browse_tasks.html', [
+        return $this->getJsCode('tasks', ['t_confirm_block_deletion' => _t('_bx_tasks_txt_msg_confirm_tasklist_deletion')]) . $this->parseHtmlByName('browse_tasks.html', [
             'bx_repeat:task_lists' => $aTmplVarsLists,
             'bx_if:allow_add_list' => [
                 'condition' => $bAllowAdd,

+ 15 - 0
modules/boonex/tasks/classes/BxTasksTime.php

@@ -36,6 +36,18 @@ class BxTasksTime extends BxTemplReport
         });
     }
 
+    public function report($aParams = [])
+    {
+        $mixedResult = parent::report($aParams);
+        if(!empty($mixedResult) && is_array($mixedResult) && isset($mixedResult['popup'], $mixedResult['popup_id']))
+            $mixedResult['popup'] = [
+                'html' => $mixedResult['popup'], 
+                'options' => ['closeOnOuterClick' => false]
+            ];
+
+        return $mixedResult;
+    }
+
     /**
      * Should always return false to allow any number of time reports per user.
      */
@@ -53,6 +65,9 @@ class BxTasksTime extends BxTemplReport
         if(empty($aTrack) || !is_array($aTrack))
             return false;
 
+        if(!$bUndo && empty($aTrack['value_date']) && !$this->_oQuery->updateTrack(['value_date' => time()], ['id' => $aTrack['id']]))
+            return false;
+
         if(!$this->_oQuery->updateReport($iObjectId, $aTrack['value'], $bUndo))
             return false;
 

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

@@ -15,6 +15,15 @@ class BxTasksTimeQuery extends BxDolReportQuery
         parent::__construct($oModule);
     }
 
+    public function updateTrack($aParamsSet, $aParamsWhere)
+    {
+        if(empty($aParamsSet) || empty($aParamsWhere))
+            return false;
+
+        $sSql = "UPDATE `{$this->_sTableTrack}` SET " . $this->arrayToSQL($aParamsSet) . " WHERE " . $this->arrayToSQL($aParamsWhere, " AND ");
+        return $this->query($sSql);
+    }
+
     public function getReport($iObjectId)
     {
         $aResult = $this->getRow("SELECT `count` as `count`, `sum` AS `sum` FROM `{$this->_sTable}` WHERE `object_id` = :object_id LIMIT 1", ['object_id' => $iObjectId]);

+ 15 - 5
modules/boonex/tasks/install/langs/en.xml

@@ -105,8 +105,15 @@
     <string name="_bx_tasks_form_time_input_sys_action"><![CDATA[Action]]></string>
     <string name="_bx_tasks_form_time_input_sys_submit"><![CDATA[Submit]]></string>
     <string name="_bx_tasks_form_time_input_submit"><![CDATA[Submit]]></string>
+    <string name="_bx_tasks_form_time_input_sys_cancel"><![CDATA[Cancel]]></string>
+    <string name="_bx_tasks_form_time_input_cancel"><![CDATA[Cancel]]></string>
+    <string name="_bx_tasks_form_time_input_sys_controls"><![CDATA[Controls]]></string>
     <string name="_bx_tasks_form_time_input_sys_value"><![CDATA[Time]]></string>
     <string name="_bx_tasks_form_time_input_value"><![CDATA[Time]]></string>
+    <string name="_bx_tasks_form_time_input_value_err"><![CDATA[If you want to log some time fill this field in.]]></string>
+    <string name="_bx_tasks_form_time_input_sys_value_date"><![CDATA[Date]]></string>
+    <string name="_bx_tasks_form_time_input_value_date"><![CDATA[Date]]></string>
+    <string name="_bx_tasks_form_time_input_value_date_inf"><![CDATA[Leave empty to use today date.]]></string>
     <string name="_bx_tasks_form_time_input_sys_text"><![CDATA[Note]]></string>
     <string name="_bx_tasks_form_time_input_text"><![CDATA[Note]]></string>
     <string name="_bx_tasks_popup_title_time_add"><![CDATA[Add Time]]></string>
@@ -220,9 +227,9 @@
     <string name="_bx_tasks_page_block_title_calendar_in_context"><![CDATA[Calendar]]></string>
     <string name="_bx_tasks_page_block_title_sys_calendar_of_author"><![CDATA[Calendar]]></string>
     <string name="_bx_tasks_page_block_title_calendar_of_author"><![CDATA[Calendar]]></string>
-    <string name="_bx_tasks_page_title_sys_entries_time_in_context"><![CDATA[My time in context]]></string>
+    <string name="_bx_tasks_page_title_sys_entries_time_in_context"><![CDATA[Time in context: My]]></string>
     <string name="_bx_tasks_page_title_entries_time_in_context"><![CDATA[My time in {display_name}]]></string>
-    <string name="_bx_tasks_page_title_sys_entries_time_in_context_administration"><![CDATA[All time in context]]></string>
+    <string name="_bx_tasks_page_title_sys_entries_time_in_context_administration"><![CDATA[Time in context: All]]></string>
     <string name="_bx_tasks_page_title_entries_time_in_context_administration"><![CDATA[All time in {display_name}]]></string>
     <string name="_bx_tasks_page_block_title_sys_menu_in_context"><![CDATA[View context menu]]></string>
     <string name="_bx_tasks_page_block_title_menu_in_context"><![CDATA[Menu]]></string>
@@ -313,7 +320,7 @@
     <string name="_bx_tasks_grid_column_title_tm_object_id"><![CDATA[Task]]></string>
     <string name="_bx_tasks_grid_column_title_tm_text"><![CDATA[Note]]></string>
     <string name="_bx_tasks_grid_column_title_tm_value"><![CDATA[Time]]></string>
-    <string name="_bx_tasks_grid_column_title_tm_date"><![CDATA[Added]]></string>
+    <string name="_bx_tasks_grid_column_title_tm_value_date"><![CDATA[Date]]></string>
     <string name="_bx_tasks_grid_action_title_tm_add"><![CDATA[Add]]></string>
     <string name="_bx_tasks_grid_action_title_tm_edit"><![CDATA[Edit]]></string>
     <string name="_bx_tasks_grid_action_title_tm_delete"><![CDATA[Remove]]></string>
@@ -401,12 +408,15 @@
     <string name="_bx_tasks_txt_filter_all"><![CDATA[All Tasks]]></string>
     <string name="_bx_tasks_txt_filter_completed"><![CDATA[Completed Tasks]]></string>
     <string name="_bx_tasks_txt_filter_uncompleted"><![CDATA[Uncompleted Tasks]]></string>
+    <string name="_bx_tasks_txt_total"><![CDATA[Total: {0}]]></string>
+    <string name="_bx_tasks_txt_estimate"><![CDATA[Estimate: {0}]]></string>
+
     <string name="_bx_tasks_txt_err_cannot_perform_action"><![CDATA[Cannot perform action. Please report.]]></string>
-    <string name="_bx_tasks_confirm_tasklist_deletion"><![CDATA[You will delete all tasks that are contained in this tasklist. Are you sure?]]></string>
-  
     <string name="_bx_tasks_txt_err_cannot_perform_action"><![CDATA[Cannot perform action. Please report.]]></string>
     <string name="_bx_tasks_txt_msg_status_hidden"><![CDATA[This task was hidden.]]></string>
     <string name="_bx_tasks_txt_msg_status_pending"><![CDATA[This task is pending approval.]]></string>
+    <string name="_bx_tasks_txt_msg_confirm_tasklist_deletion"><![CDATA[You will delete all tasks that are contained in this tasklist. Are you sure?]]></string>
+    
 
     <!-- Notifications -->
     <string name="_bx_tasks_alert_action_completed_personal"><![CDATA[Complete task]]></string>

+ 2 - 2
modules/boonex/tasks/install/sql/enable.sql

@@ -308,13 +308,13 @@ INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable
 ('bx_tasks_time_administration', 'object_id', '_bx_tasks_grid_column_title_tm_object_id', '30%', 0, 0, '', 3),
 ('bx_tasks_time_administration', 'text', '_bx_tasks_grid_column_title_tm_text', '15%', 0, 16, '', 4),
 ('bx_tasks_time_administration', 'value', '_bx_tasks_grid_column_title_tm_value', '10%', 0, 0, '', 5),
-('bx_tasks_time_administration', 'date', '_bx_tasks_grid_column_title_tm_date', '15%', 0, 0, '', 6),
+('bx_tasks_time_administration', 'value_date', '_bx_tasks_grid_column_title_tm_value_date', '15%', 0, 0, '', 6),
 
 ('bx_tasks_time', 'checkbox', '_sys_select', '2%', 0, 0, '', 1),
 ('bx_tasks_time', 'object_id', '_bx_tasks_grid_column_title_tm_object_id', '30%', 0, 0, '', 2),
 ('bx_tasks_time', 'text', '_bx_tasks_grid_column_title_tm_text', '25%', 0, 32, '', 3),
 ('bx_tasks_time', 'value', '_bx_tasks_grid_column_title_tm_value', '10%', 0, 0, '', 4),
-('bx_tasks_time', 'date', '_bx_tasks_grid_column_title_tm_date', '15%', 0, 0, '', 5),
+('bx_tasks_time', 'value_date', '_bx_tasks_grid_column_title_tm_value_date', '15%', 0, 0, '', 5),
 ('bx_tasks_time', 'actions', '', '18%', 0, '', '', 6);
 
 INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES

+ 17 - 7
modules/boonex/tasks/install/sql/install.sql

@@ -310,6 +310,7 @@ CREATE TABLE IF NOT EXISTS `bx_tasks_time_track` (
   `author_id` int(11) NOT NULL default '0',
   `author_nip` int(11) unsigned NOT NULL default '0',
   `value` int(11) NOT NULL default '0',
+  `value_date` int(11) NOT NULL default '0',
   `text` text NOT NULL default '',
   `date` int(11) NOT NULL default '0',
   PRIMARY KEY (`id`)
@@ -445,7 +446,7 @@ INSERT INTO `sys_form_inputs`(`object`, `module`, `name`, `value`, `values`, `ch
 ('bx_tasks', 'bx_tasks', 'published', '', '', 0, 'datetime', '_bx_tasks_form_entry_input_sys_date_published', '_bx_tasks_form_entry_input_date_published', '_bx_tasks_form_entry_input_date_published_info', 0, 0, 0, '', '', '', '', '', '', 'DateTimeTs', '', 1, 0),
 ('bx_tasks', 'bx_tasks', 'initial_members', '', '', 0, 'custom', '_bx_tasks_form_entry_input_sys_initial_members', '_bx_tasks_form_entry_input_initial_members', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 1),
 ('bx_tasks', 'bx_tasks', 'estimate', '', '', 0, 'text', '_bx_tasks_form_entry_input_sys_estimate', '_bx_tasks_form_entry_input_estimate', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 1, 0),
-('bx_tasks', 'bx_tasks', 'due_date', '', '', 0, 'datetime', '_bx_tasks_form_entry_input_sys_date_due_date', '_bx_tasks_form_entry_input_date_due_date', '', 0, 0, 0, '', '', '', '', '', '', 'DateTimeTs', '', 1, 0),
+('bx_tasks', 'bx_tasks', 'due_date', '', '', 0, 'datetime', '_bx_tasks_form_entry_input_sys_date_due_date', '_bx_tasks_form_entry_input_date_due_date', '', 0, 0, 0, '', '', '', '', '', '', 'DateTimeUtc', '', 1, 0),
 ('bx_tasks', 'bx_tasks', 'attachments', '', '', 0, 'custom', '_bx_tasks_form_entry_input_sys_attachments', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
 ('bx_tasks', 'bx_tasks', 'labels', '', '', 0, 'custom', '_sys_form_input_sys_labels', '_sys_form_input_labels', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
 ('bx_tasks', 'bx_tasks', 'anonymous', '', '', 0, 'switcher', '_sys_form_input_sys_anonymous', '_sys_form_input_anonymous', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0),
@@ -535,21 +536,30 @@ INSERT INTO `sys_form_inputs` (`object`, `module`, `name`, `value`, `values`, `c
 ('bx_tasks_time', 'bx_tasks', 'sys', '', '', 0, 'hidden', '_bx_tasks_form_time_input_sys_sys', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
 ('bx_tasks_time', 'bx_tasks', 'object_id', '', '', 0, 'hidden', '_bx_tasks_form_time_input_sys_object_id', '_bx_tasks_form_time_input_object_id', '', 0, 0, 0, '', '', '', '', '', '', 'Int', '', 0, 0),
 ('bx_tasks_time', 'bx_tasks', 'action', '', '', 0, 'hidden', '_bx_tasks_form_time_input_sys_action', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
-('bx_tasks_time', 'bx_tasks', 'value', '', '', 0, 'time', '_bx_tasks_form_time_input_sys_value', '_bx_tasks_form_time_input_value', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
+('bx_tasks_time', 'bx_tasks', 'value', '', '', 0, 'time', '_bx_tasks_form_time_input_sys_value', '_bx_tasks_form_time_input_value', '', 1, 0, 0, '', '', '', 'Avail', '', '_bx_tasks_form_time_input_value_err', 'Xss', '', 1, 0),
+('bx_tasks_time', 'bx_tasks', 'value_date', '', '', 0, 'datepicker', '_bx_tasks_form_time_input_sys_value_date', '_bx_tasks_form_time_input_value_date', '_bx_tasks_form_time_input_value_date_inf', 0, 0, 0, '', '', '', '', '', '', 'DateUtc', '', 1, 0),
 ('bx_tasks_time', 'bx_tasks', 'text', '', '', 0, 'textarea', '_bx_tasks_form_time_input_sys_text', '_bx_tasks_form_time_input_text', '', 0, 0, 0, '', '', '', '', '', '', 'Xss', '', 1, 0),
-('bx_tasks_time', 'bx_tasks', 'submit', '_bx_tasks_form_time_input_submit', '', 0, 'submit', '_bx_tasks_form_time_input_sys_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0);
+('bx_tasks_time', 'bx_tasks', 'submit', '_bx_tasks_form_time_input_submit', '', 0, 'submit', '_bx_tasks_form_time_input_sys_submit', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 0, 0),
+('bx_tasks_time', 'bx_tasks', 'cancel', '_bx_tasks_form_time_input_cancel', '', 0, 'button', '_bx_tasks_form_time_input_sys_cancel', '', '', 0, 0, 0, 'a:2:{s:7:"onclick";s:45:"$(''.bx-popup-applied:visible'').dolPopupHide()";s:5:"class";s:22:"bx-def-margin-sec-left";}', '', '', '', '', '', '', '', 1, 0),
+('bx_tasks_time', 'bx_tasks', 'controls', '', 'submit,cancel', 0, 'input_set', '_bx_tasks_form_time_input_sys_controls', '', '', 0, 0, 0, '', '', '', '', '', '', '', '', 1, 0);
 
 INSERT INTO `sys_form_display_inputs` (`display_name`, `input_name`, `visible_for_levels`, `active`, `order`) VALUES
 ('bx_tasks_time_add', 'sys', 2147483647, 1, 1),
 ('bx_tasks_time_add', 'object_id', 2147483647, 1, 2),
 ('bx_tasks_time_add', 'action', 2147483647, 1, 3),
 ('bx_tasks_time_add', 'value', 2147483647, 1, 4),
-('bx_tasks_time_add', 'text', 2147483647, 1, 5),
-('bx_tasks_time_add', 'submit', 2147483647, 1, 6),
+('bx_tasks_time_add', 'value_date', 2147483647, 1, 5),
+('bx_tasks_time_add', 'text', 2147483647, 1, 6),
+('bx_tasks_time_add', 'controls', 2147483647, 1, 7),
+('bx_tasks_time_add', 'submit', 2147483647, 1, 8),
+('bx_tasks_time_add', 'cancel', 2147483647, 1, 9),
 
 ('bx_tasks_time_edit', 'value', 2147483647, 1, 1),
-('bx_tasks_time_edit', 'text', 2147483647, 1, 2),
-('bx_tasks_time_edit', 'submit', 2147483647, 1, 3);
+('bx_tasks_time_edit', 'value_date', 2147483647, 1, 2),
+('bx_tasks_time_edit', 'text', 2147483647, 1, 3),
+('bx_tasks_time_edit', 'controls', 2147483647, 1, 4),
+('bx_tasks_time_edit', 'submit', 2147483647, 1, 5),
+('bx_tasks_time_edit', 'cancel', 2147483647, 1, 6);
 
 
 -- PRE-VALUES

+ 1 - 0
modules/boonex/tasks/template/browse_tasks.html

@@ -48,6 +48,7 @@
                     <span class="bx-def-font-small col-green1 pr-2">__priority__</span>
                     <span class="bx-task-due-date bx-def-font-small col-red1 pr-2">__due__</span>
                     <span class="bx-task-state bx-def-font-small bx-def-font-grayed pr-2">__state__</span>
+                    <span class="bx-task-time bx-def-font-small bx-def-font-grayed pr-2">__time__</span>
                     <div class="bx-tasks-members">
                         <bx_repeat:members>
                             __info__

+ 90 - 90
template/scripts/BxBaseReport.php

@@ -140,96 +140,6 @@ class BxBaseReport extends BxDolReport
         return ['popup' => $sPopupContent, 'popup_id' => $sPopupId];
     }
 
-    protected function _report($bPerformed, $aParams, &$oForm)
-    {
-        $iAuthorId = $this->_getAuthorId();
-        $iAuthorNip = bx_get_ip_hash($this->_getAuthorIp());
-
-        $iObjectId = $this->_bApi ? $this->_iId : $oForm->getCleanValue('object_id');
-        $iObjectAuthorId = $this->_oQuery->getObjectAuthorId($iObjectId);
-
-        if(!$this->isAllowedReport(true))
-            return ['code' => 2, 'message' => $this->msgErrAllowedReport()];
-
-        $sType = $this->_bApi ? $aParams['type'] : $oForm->getCleanValue('type');
-        if(!in_array($sType, $this->_aTypes)) 
-            return ['code' => 5, 'message' => _t('_report_err_wrong_type')];
-
-        $sText = $this->_bApi ? $aParams['text'] : $oForm->getCleanValue('text');
-        $sText = bx_process_input($sText, BX_DATA_TEXT_MULTILINE);
-
-        $iId = (int)$oForm->insert(['object_id' => $iObjectId, 'author_id' => $iAuthorId, 'author_nip' => $iAuthorNip, 'type' => $sType, 'text' => $sText,  'date' => time()]);
-        if($iId != 0 && $this->_oQuery->putReport($iObjectId, $iAuthorId)) {
-            if(!empty($this->_sObjectCmts) && ($oCmts = BxDolCmts::getObjectInstance($this->_sObjectCmts, $this->getId()))) {
-                $sCmtText = '_report_comment';
-                if(!empty($sText))
-                    $sCmtText = '_report_comment_with_note';
-
-                $aTypes = BxDolForm::getDataItems('sys_report_types');
-
-                $oCmts->add([
-                    'cmt_author_id' => $iAuthorId,
-                    'cmt_parent_id' => 0,
-                    'cmt_text' => _t($sCmtText, $aTypes[$sType], $sText)
-                ]);
-            }
-
-            $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate('t_Reported', [
-                'report_type' => $sType,
-                'report_text' => $sText,
-                'report_url' => $this->getBaseUrl(),
-            ]);
-            if($aTemplate)
-                sendMail(getParam('site_email'), $aTemplate['Subject'], $aTemplate['Body']);
-
-            if(($mixedParams = $this->_prepareAuditParams($iObjectId, ['type' => $sType, 'text' => $sText]))) {
-                $iAuditObjectId = (int)$mixedParams['object_id'];
-                $sAuditActionName = $mixedParams['action_name'];
-                unset($mixedParams['object_id'], $mixedParams['action_name']);
-
-                bx_audit($iAuditObjectId, $this->_sSystem, $sAuditActionName, $mixedParams);
-            }
-
-            $aReport = $this->_getReport($iObjectId, true);
-
-            $iBlockContentAfter = (int)getParam('sys_security_block_content_after_n_reports');
-            if ($iBlockContentAfter > 0 && $aReport['count'] >= $iBlockContentAfter){
-                $oModule = BxDolModule::getInstance($this->_aSystem['module_name']);
-                if($oModule)
-                    $oModule->_oDb->updateStatusAdmin($iObjectId, false);
-            }
-
-            $this->_trigger();
-
-            bx_alert($this->_sSystem, 'doReport', $iObjectId, $iAuthorId, ['report_id' => $iId, 'report_author_id' => $iAuthorId, 'object_author_id' => $iObjectAuthorId, 'type' => $sType, 'text' => $sText]);
-            /**
-             * @hooks
-             * @hookdef hook-report-do 'report', 'do' - hook on create new report 
-             * - $unit_name - equals `report`
-             * - $action - equals `do` 
-             * - $object_id - report id 
-             * - $sender_id - profile_id for report's author
-             * - $extra_params - array of additional params with the following array keys:
-             *      - `object_system` - [string] system name, ex: bx_posts
-             *      - `object_id` - [int] reported object id 
-             *      - `object_author_id` - [int] author's profile_id for reported object_id 
-             *      - `type` - [string] report type
-             *      - `text` - [bool] report text
-             * @hook @ref hook-report-do
-             */
-            bx_alert('report', 'do', $iId, $iAuthorId, ['object_system' => $this->_sSystem, 'object_id' => $iObjectId, 'object_author_id' => $iObjectAuthorId, 'type' => $sType, 'text' => $sText]);
-
-            $aResult = $this->_returnReportData($iObjectId, $iAuthorId, $iId, $aReport, !$bPerformed);
-
-            if(($oSockets = BxDolSockets::getInstance()) && $oSockets->isEnabled())
-                $oSockets->sendEvent($this->getSocketName(), $iObjectId, 'reported', json_encode($this->_returnReportDataForSocket($aResult)));
-
-            return $aResult;
-        }
-
-        return ['code' => 3, 'message' => _t('_report_err_cannot_perform_action')];
-    }
-
     public function getJsObjectName()
     {
         return $this->_sJsObjName;
@@ -452,6 +362,96 @@ class BxBaseReport extends BxDolReport
     /**
      * Internal methods.
      */
+    protected function _report($bPerformed, $aParams, &$oForm)
+    {
+        $iAuthorId = $this->_getAuthorId();
+        $iAuthorNip = bx_get_ip_hash($this->_getAuthorIp());
+
+        $iObjectId = $this->_bApi ? $this->_iId : $oForm->getCleanValue('object_id');
+        $iObjectAuthorId = $this->_oQuery->getObjectAuthorId($iObjectId);
+
+        if(!$this->isAllowedReport(true))
+            return ['code' => 2, 'message' => $this->msgErrAllowedReport()];
+
+        $sType = $this->_bApi ? $aParams['type'] : $oForm->getCleanValue('type');
+        if(!in_array($sType, $this->_aTypes)) 
+            return ['code' => 5, 'message' => _t('_report_err_wrong_type')];
+
+        $sText = $this->_bApi ? $aParams['text'] : $oForm->getCleanValue('text');
+        $sText = bx_process_input($sText, BX_DATA_TEXT_MULTILINE);
+
+        $iId = (int)$oForm->insert(['object_id' => $iObjectId, 'author_id' => $iAuthorId, 'author_nip' => $iAuthorNip, 'type' => $sType, 'text' => $sText,  'date' => time()]);
+        if($iId != 0 && $this->_oQuery->putReport($iObjectId, $iAuthorId)) {
+            if(!empty($this->_sObjectCmts) && ($oCmts = BxDolCmts::getObjectInstance($this->_sObjectCmts, $this->getId()))) {
+                $sCmtText = '_report_comment';
+                if(!empty($sText))
+                    $sCmtText = '_report_comment_with_note';
+
+                $aTypes = BxDolForm::getDataItems('sys_report_types');
+
+                $oCmts->add([
+                    'cmt_author_id' => $iAuthorId,
+                    'cmt_parent_id' => 0,
+                    'cmt_text' => _t($sCmtText, $aTypes[$sType], $sText)
+                ]);
+            }
+
+            $aTemplate = BxDolEmailTemplates::getInstance()->parseTemplate('t_Reported', [
+                'report_type' => $sType,
+                'report_text' => $sText,
+                'report_url' => $this->getBaseUrl(),
+            ]);
+            if($aTemplate)
+                sendMail(getParam('site_email'), $aTemplate['Subject'], $aTemplate['Body']);
+
+            if(($mixedParams = $this->_prepareAuditParams($iObjectId, ['type' => $sType, 'text' => $sText]))) {
+                $iAuditObjectId = (int)$mixedParams['object_id'];
+                $sAuditActionName = $mixedParams['action_name'];
+                unset($mixedParams['object_id'], $mixedParams['action_name']);
+
+                bx_audit($iAuditObjectId, $this->_sSystem, $sAuditActionName, $mixedParams);
+            }
+
+            $aReport = $this->_getReport($iObjectId, true);
+
+            $iBlockContentAfter = (int)getParam('sys_security_block_content_after_n_reports');
+            if ($iBlockContentAfter > 0 && $aReport['count'] >= $iBlockContentAfter){
+                $oModule = BxDolModule::getInstance($this->_aSystem['module_name']);
+                if($oModule)
+                    $oModule->_oDb->updateStatusAdmin($iObjectId, false);
+            }
+
+            $this->_trigger();
+
+            bx_alert($this->_sSystem, 'doReport', $iObjectId, $iAuthorId, ['report_id' => $iId, 'report_author_id' => $iAuthorId, 'object_author_id' => $iObjectAuthorId, 'type' => $sType, 'text' => $sText]);
+            /**
+             * @hooks
+             * @hookdef hook-report-do 'report', 'do' - hook on create new report 
+             * - $unit_name - equals `report`
+             * - $action - equals `do` 
+             * - $object_id - report id 
+             * - $sender_id - profile_id for report's author
+             * - $extra_params - array of additional params with the following array keys:
+             *      - `object_system` - [string] system name, ex: bx_posts
+             *      - `object_id` - [int] reported object id 
+             *      - `object_author_id` - [int] author's profile_id for reported object_id 
+             *      - `type` - [string] report type
+             *      - `text` - [bool] report text
+             * @hook @ref hook-report-do
+             */
+            bx_alert('report', 'do', $iId, $iAuthorId, ['object_system' => $this->_sSystem, 'object_id' => $iObjectId, 'object_author_id' => $iObjectAuthorId, 'type' => $sType, 'text' => $sText]);
+
+            $aResult = $this->_returnReportData($iObjectId, $iAuthorId, $iId, $aReport, !$bPerformed);
+
+            if(($oSockets = BxDolSockets::getInstance()) && $oSockets->isEnabled())
+                $oSockets->sendEvent($this->getSocketName(), $iObjectId, 'reported', json_encode($this->_returnReportDataForSocket($aResult)));
+
+            return $aResult;
+        }
+
+        return ['code' => 3, 'message' => _t('_report_err_cannot_perform_action')];
+    }
+
     protected function _getDoReport($aParams = array())
     {
     	$bReported = isset($aParams['is_reported']) && $aParams['is_reported'] === true;