diff --git a/module/todo/ui/view.html.php b/module/todo/ui/view.html.php index a1abe4010f..78dae0c294 100644 --- a/module/todo/ui/view.html.php +++ b/module/todo/ui/view.html.php @@ -16,29 +16,295 @@ jsVar('todoID', $todo->id); $isInModal = isAjaxRequest('modal'); -detailHeader -( - $isInModal ? to::prefix('') : '', - to::title - ( - entityLabel - ( - set::entityID(17), - set::level(1), - set::text($todo->name) - ) - ), -); - -$fromItem = ''; -$fromItemData = ''; -if(in_array($todo->type, array('story', 'task', 'bug')) && !empty($todo->object)) +/* Generate title suffix for bug,task,story type. */ +$fnGenerateTitleSuffix = function() use($todo) { + if($todo->type == 'bug') return btn(set::url(createLink('bug', 'view', "id={$todo->objectID}")), set::text(' BUG#' . $todo->objectID), setClass('ghost')); + if($todo->type == 'task') return btn(set::url(createLink('task', 'view', "id={$todo->objectID}")), set::text(' TASK#' . $todo->objectID), setClass('ghost')); + if($todo->type == 'story') return btn(set::url(createLink('story', 'view', "id={$todo->objectID}")), set::text(' STORY#' . $todo->objectID), setClass('ghost')); +}; + +/* Generate action buttons and related menus within float toolbar. */ +$fnGenerateFloatToolbarBtns = function() use ($lang, $config, $todo, $executions, $projects, $projectProducts) +{ + $actionList = array(); + + if($todo->deleted) return $actionList; + + if($todo->status == 'wait' && common::hasPriv('todo', 'start')) + { + $actionList[] = array + ( + 'icon' => 'play', + 'url' => createLink('todo', 'start', "todoID={$todo->id}"), + 'text' => $lang->todo->abbr->start + ); + } + if(($todo->status == 'done' || $todo->status == 'closed') && common::hasPriv('todo', 'activate')) + { + $actionList[] = array + ( + 'icon' => 'magic', + 'url' => createLink('todo', 'activate', "todoID={$todo->id}"), + 'text' => $lang->activate + ); + } + if($todo->status == 'done' && common::hasPriv('todo', 'close')) + { + $actionList[] = array + ( + 'icon' => 'off', + 'url' => createLink('todo', 'close', "todoID={$todo->id}"), + 'text' => $lang->close + ); + } + if(common::hasPriv('todo', 'edit')) + { + $actionList[] = array + ( + 'icon' => 'edit', + 'url' => createLink('todo', 'edit', "todoID={$todo->id}"), + 'text' => $lang->edit + ); + } + if(common::hasPriv('todo', 'delete')) + { + $actionList[] = array + ( + 'icon' => 'trash', + 'url' => createLink('todo', 'delete', "todoID={$todo->id}"), + 'text' => $lang->delete + ); + } + if($todo->status != 'done' && $todo->status != 'closed') + { + $actionList[] = array + ( + 'icon' => 'checked', + 'url' => createLink('todo', 'finish', "todoID={$todo->id}"), + 'text' => $lang->todo->abbr->finish + ); + $createStoryPriv = common::hasPriv('story', 'create'); + $createTaskPriv = common::hasPriv('task', 'create'); + $createBugPriv = common::hasPriv('bug', 'create'); + $printBtn = $config->vision == 'lite' && empty($projects); + if($printBtn && ($createStoryPriv || $createTaskPriv || $createBugPriv)) + { + $actionList[] = array + ( + 'url' => '#navActions', + 'text' => $lang->more, + 'data-toggle' => 'dropdown', + 'data-placement' => 'top-end', + ); + } + $storyTarget = $createStoryPriv && $config->vision == 'lite' ? '#projectModal' : '#productModal'; + menu + ( + set::id('navActions'), + setClass('menu dropdown-menu'), + set::items(array + ( + array('text' => $lang->todo->reasonList['story'], 'id' => 'toStoryLink', 'data-url' => '###', 'data-toggle' => 'modal', 'data-target' => $storyTarget, 'data-backdrop' => false, 'data-moveable' => true, 'data-position' => 'center'), + array('text' => $lang->todo->reasonList['task'], 'id' => 'toTaskLink', 'data-url' => '###', 'data-toggle' => 'modal', 'data-target' => '#executionModal', 'data-backdrop' => false, 'data-moveable' => true, 'data-position' => 'center'), + array('text' => $lang->todo->reasonList['bug'], 'id' => 'toBugLink', 'data-url' => '###', 'data-toggle' => 'modal', 'data-target' => '#projectProductModal', 'data-backdrop' => false, 'data-moveable' => true, 'data-position' => 'center'), + )) + ); + modal + ( + setID('productModal'), + set::modalProps(array('title' => $lang->product->select)), + empty($products) ? div + ( + setClass('text-center', 'pb-8'), + span($lang->product->noProduct), + btn + ( + $lang->product->create, + set + ( + array( + 'url' => createLink('product', 'create'), + 'id' => 'createProduct', + 'class' => 'secondary-pale', + 'icon' => 'plus' + ) + ) + ) + ) : form + ( + formGroup + ( + inputGroup + ( + select + ( + on::change('getProgramByProduct(this)'), + set + ( + array( + 'id' => 'product', + 'class' => 'form-control', + 'name' => 'product', + 'items' => $products, + 'required' => true + ) + ) + ), + input + ( + set::type('hidden'), + set::name('productProgram'), + set::value(0) + ), + btn + ( + on::click('toStory'), + set + ( + array( + 'id' => 'toStoryButton', + 'class' => 'primary', + 'text' => $lang->todo->reasonList['story'] + ) + ) + ) + ) + ), + set::actions(array()), + setClass('pb-6') + ), + ); + modal + ( + setID('executionModal'), + set::modalProps(array('title' => $lang->execution->selectExecution)), + form + ( + setClass('text-center', 'pb-4'), + set::actions(array()), + formGroup + ( + set::label($lang->todo->project), + select + ( + on::change('getExecutionByProject(this)'), + set + ( + array( + 'id' => 'project', + 'name' => 'project', + 'items' => $projects, + 'required' => true + ) + ) + ) + ), + formGroup + ( + set::label($lang->todo->execution), + select + ( + set + ( + array( + 'id' => 'execution', + 'name' => 'execution', + 'items' => $executions, + 'required' => true + ) + ) + ) + ), + btn + ( + $lang->todo->reasonList['task'], + on::click('toTask'), + set + ( + array( + 'id' => 'toTaskButton', + 'class' => array('primary', 'text-center') + ) + ) + ) + ) + ); + + modal + ( + setID('projectProductModal'), + set::modalProps(array('title' => $lang->product->select)), + form + ( + setClass('text-center', 'pb-4'), + set::actions(array()), + formGroup + ( + set::label($lang->todo->project), + select + ( + on::change('getProductByProject(this)'), + set + ( + array( + 'id' => 'bugProject', + 'name' => 'bugProject', + 'items' => $projects, + 'required' => true + ) + ) + ) + ), + formGroup + ( + set::label($lang->todo->product), + select + ( + set + ( + array( + 'id' => 'bugProduct', + 'name' => 'bugProduct', + 'items' => $projectProducts, + 'required' => true + ) + ) + ) + ), + btn + ( + $lang->todo->reasonList['bug'], + on::click('toBug'), + set + ( + array( + 'id' => 'toBugButton', + 'class' => array('primary', 'text-center'), + // 'data-backdrop' => false, + 'data-toggle' => 'modal', + // 'data-type' => 'html', + ) + ) + ) + ) + ); + } + + return $actionList; +}; +$actionList = $fnGenerateFloatToolbarBtns(); + +/* Generate from data and item. */ +$fnGenerateFrom = function() use ($app, $lang, $config, $todo) +{ + if(!in_array($todo->type, array('story', 'task', 'bug')) || empty($todo->object)) return array(null, null); + + /* Generate from data. */ $app->loadLang($todo->type); $objectData = array(); foreach($config->todo->related[$todo->type]['title'] as $index => $relatedTitle) { - $title = $lang->{$todo->type}->{$relatedTitle}; $content = zget($todo->object, $config->todo->related[$todo->type]['content'][$index], ''); $objectData[] = item ( @@ -46,6 +312,7 @@ if(in_array($todo->type, array('story', 'task', 'bug')) && !empty($todo->object) empty($content) ? $lang->noData : html($content), ); } + $fromItemData = section ( set::title(zget($lang->todo->fromList, $todo->type)), @@ -59,6 +326,8 @@ if(in_array($todo->type, array('story', 'task', 'bug')) && !empty($todo->object) $objectData, ), ); + + /* Generate from item. */ $fromItem = item ( set::name(zget($lang->todo->fromList, $todo->type)), @@ -71,268 +340,26 @@ if(in_array($todo->type, array('story', 'task', 'bug')) && !empty($todo->object) $todo->name, ), ); -} -$actionList = array(); -if($todo->status == 'wait' && common::hasPriv('todo', 'start')) -{ - $actionList[] = array + return array($fromItem, $fromItemData); +}; +list($fromItem, $fromItemData) = $fnGenerateFrom(); + +/* ZIN: layout. */ +detailHeader +( + $isInModal ? to::prefix('') : '', + to::title ( - 'icon' => 'play', - 'url' => createLink('todo', 'start', "todoID={$todo->id}"), - 'text' => $lang->todo->abbr->start - ); -} -if(($todo->status == 'done' || $todo->status == 'closed') && common::hasPriv('todo', 'activate')) -{ - $actionList[] = array - ( - 'icon' => 'magic', - 'url' => createLink('todo', 'activate', "todoID={$todo->id}"), - 'text' => $lang->activate - ); -} -if($todo->status == 'done' && common::hasPriv('todo', 'close')) -{ - $actionList[] = array - ( - 'icon' => 'off', - 'url' => createLink('todo', 'close', "todoID={$todo->id}"), - 'text' => $lang->close - ); -} -if(common::hasPriv('todo', 'edit')) -{ - $actionList[] = array - ( - 'icon' => 'edit', - 'url' => createLink('todo', 'edit', "todoID={$todo->id}"), - 'text' => $lang->edit - ); -} -if(common::hasPriv('todo', 'delete')) -{ - $actionList[] = array - ( - 'icon' => 'trash', - 'url' => createLink('todo', 'delete', "todoID={$todo->id}"), - 'text' => $lang->delete - ); -} -if($todo->status != 'done' && $todo->status != 'closed') -{ - $actionList[] = array - ( - 'icon' => 'checked', - 'url' => createLink('todo', 'finish', "todoID={$todo->id}"), - 'text' => $lang->todo->abbr->finish - ); - $createStoryPriv = common::hasPriv('story', 'create'); - $createTaskPriv = common::hasPriv('task', 'create'); - $createBugPriv = common::hasPriv('bug', 'create'); - $printBtn = $config->vision == 'lite' && empty($projects); - if($printBtn && ($createStoryPriv || $createTaskPriv || $createBugPriv)) - { - $actionList[] = array + entityLabel ( - 'url' => '#navActions', - 'text' => $lang->more, - 'data-toggle' => 'dropdown', - 'data-placement' => 'top-end', - ); - } - $storyTarget = $createStoryPriv && $config->vision == 'lite' ? '#projectModal' : '#productModal'; - menu - ( - set::id('navActions'), - setClass('menu dropdown-menu'), - set::items(array - ( - array('text' => $lang->todo->reasonList['story'], 'id' => 'toStoryLink', 'data-url' => '###', 'data-toggle' => 'modal', 'data-target' => $storyTarget, 'data-backdrop' => false, 'data-moveable' => true, 'data-position' => 'center'), - array('text' => $lang->todo->reasonList['task'], 'id' => 'toTaskLink', 'data-url' => '###', 'data-toggle' => 'modal', 'data-target' => '#executionModal', 'data-backdrop' => false, 'data-moveable' => true, 'data-position' => 'center'), - array('text' => $lang->todo->reasonList['bug'], 'id' => 'toBugLink', 'data-url' => '###', 'data-toggle' => 'modal', 'data-target' => '#projectProductModal', 'data-backdrop' => false, 'data-moveable' => true, 'data-position' => 'center'), - )) - ); - modal - ( - setID('productModal'), - set::modalProps(array('title' => $lang->product->select)), - empty($products) ? div - ( - setClass('text-center', 'pb-8'), - span($lang->product->noProduct), - btn - ( - $lang->product->create, - set - ( - array( - 'url' => createLink('product', 'create'), - 'id' => 'createProduct', - 'class' => 'secondary-pale', - 'icon' => 'plus' - ) - ) - ) - ) : form - ( - formGroup - ( - inputGroup - ( - select - ( - on::change('getProgramByProduct(this)'), - set - ( - array( - 'id' => 'product', - 'class' => 'form-control', - 'name' => 'product', - 'items' => $products, - 'required' => true - ) - ) - ), - input - ( - set::type('hidden'), - set::name('productProgram'), - set::value(0) - ), - btn - ( - on::click('toStory'), - set - ( - array( - 'id' => 'toStoryButton', - 'class' => 'primary', - 'text' => $lang->todo->reasonList['story'] - ) - ) - ) - ) - ), - set::actions(array()), - setClass('pb-6') + set::entityID($todo->id), + set::level(1), + set::text($todo->name) ), - ); - modal - ( - setID('executionModal'), - set::modalProps(array('title' => $lang->execution->selectExecution)), - form - ( - setClass('text-center', 'pb-4'), - set::actions(array()), - formGroup - ( - set::label($lang->todo->project), - select - ( - on::change('getExecutionByProject(this)'), - set - ( - array( - 'id' => 'project', - 'name' => 'project', - 'items' => $projects, - 'required' => true - ) - ) - ) - ), - formGroup - ( - set::label($lang->todo->execution), - select - ( - set - ( - array( - 'id' => 'execution', - 'name' => 'execution', - 'items' => $executions, - 'required' => true - ) - ) - ) - ), - btn - ( - $lang->todo->reasonList['task'], - on::click('toTask'), - set - ( - array( - 'id' => 'toTaskButton', - 'class' => array('primary', 'text-center') - ) - ) - ) - ) - ); - - modal - ( - setID('projectProductModal'), - set::modalProps(array('title' => $lang->product->select)), - form - ( - setClass('text-center', 'pb-4'), - set::actions(array()), - formGroup - ( - set::label($lang->todo->project), - select - ( - on::change('getProductByProject(this)'), - set - ( - array( - 'id' => 'bugProject', - 'name' => 'bugProject', - 'items' => $projects, - 'required' => true - ) - ) - ) - ), - formGroup - ( - set::label($lang->todo->product), - select - ( - set - ( - array( - 'id' => 'bugProduct', - 'name' => 'bugProduct', - 'items' => $projectProducts, - 'required' => true - ) - ) - ) - ), - btn - ( - $lang->todo->reasonList['bug'], - on::click('toBug'), - set - ( - array( - 'id' => 'toBugButton', - 'class' => array('primary', 'text-center'), - // 'data-backdrop' => false, - 'data-toggle' => 'modal', - // 'data-type' => 'html', - ) - ) - ) - ) - ); -} + $todo->deleted ? span(setClass('label danger circle'), $lang->todo->deleted) : null + ), +); detailBody ( @@ -341,18 +368,18 @@ detailBody section ( set::title($lang->todo->desc), + to::actions($fnGenerateTitleSuffix()), set::content(nl2br($todo->desc)), set::useHtml(true), ), $fromItemData, - history(), + history(set::commentUrl(createLink('action', 'comment', "objectType=todo&objectID=$todo->id"))), + + /* Render float toolbar. */ center ( - floatToolbar - ( - set::main($actionList), - ), - ), + $actionList ? floatToolbar(set::main($actionList)) : null + ) ), detailSide ( @@ -414,4 +441,3 @@ detailBody ); render(); -