diff --git a/module/kanban/model.php b/module/kanban/model.php index a6dc806486..9b0a96bdaa 100644 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -531,12 +531,13 @@ class kanbanModel extends model $this->loadModel('branch'); $this->loadModel('productplan'); - $kanbanData = new stdclass(); - $lanes = array(); - $columns = array(); - $branches = array(); - $colorIndex = 0; - $laneOrder = 1; + $kanbanData = new stdclass(); + $lanes = array(); + $columns = array(); + $branches = array(); + $colorIndex = 0; + $laneOrder = 1; + $cardActions = array('view'); if($product->type == 'normal') { @@ -566,6 +567,14 @@ class kanbanModel extends model { if(empty($plan) or $plan->parent == -1) continue; if(!isset($planList[$plan->status])) $planList[$plan->status] = array(); + + $plan->title = htmlspecialchars_decode($plan->title); + $plan->desc = strip_tags(htmlspecialchars_decode($plan->desc)); + $plan->actions = array(); + foreach($cardActions as $action) + { + if(common::hasPriv('productplan', $action)) $plan->actions[] = $action; + } $planList[$plan->status][] = $plan; } diff --git a/module/product/control.php b/module/product/control.php index 0ed61baa9f..10649e1888 100644 --- a/module/product/control.php +++ b/module/product/control.php @@ -1001,11 +1001,11 @@ class product extends control */ public function ajaxGetPlans($productID, $branch = 0, $planID = 0, $fieldID = '', $needCreate = false, $expired = '', $param = '') { - $param = strtolower($param); - $plans = $this->loadModel('productplan')->getPairs($productID, $branch, $expired, strpos($param, 'skipparent') !== false); - $field = $fieldID ? "plans[$fieldID]" : 'plan'; - $output = ''; - $output .= html::select($field, $plans, $planID, "class='form-control chosen'"); + $param = strtolower($param); + $plans = $this->loadModel('productplan')->getPairs($productID, $branch, $expired, strpos($param, 'skipparent') !== false); + $field = $fieldID ? "plans[$fieldID]" : 'plan'; + $output = ''; + $output .= html::select($field, $plans, $planID, "class='form-control chosen'"); if(count($plans) == 1 and $needCreate and $needCreate !== 'false') { $output .= "
"; diff --git a/module/productplan/js/browse.js b/module/productplan/js/browse.js index 787408f0ee..9bc95dee80 100644 --- a/module/productplan/js/browse.js +++ b/module/productplan/js/browse.js @@ -42,7 +42,6 @@ $(function() var viewType = $(this).attr('data-type'); $.cookie('viewType', viewType, {expires:config.cookieLife, path:config.webRoot}); window.location.reload(); - if(viewType == 'kanban') initKanban(); }); $('#branch').change(function() @@ -55,33 +54,30 @@ $(function() if(viewType == 'kanban') { $('#branch_chosen .chosen-single span').prepend(''); - initKanban(); + $('#kanban').kanban( + { + data: kanbanData, + minColWidth: 290, + maxColWidth: 290, + maxColHeight: 460, + minColHeight: 190, + itemRender: renderKanbanItem, + virtualize: true, + droppable: + { + target: findDropColumns, + finish: handleFinishDrop, + mouseButton: 'left' + } + }); + + $('#kanban').on('scroll', function() + { + $.zui.ContextMenu.hide(); + }); } }); -function initKanban() -{ - $('#kanban').kanban( - { - data: kanbanData, - minColWidth: 290, - maxColWidth: 290, - itemRender: renderKanbanItem, - virtualize: true, - droppable: - { - target: findDropColumns, - finish: handleFinishDrop, - mouseButton: 'left' - } - }); - - $('#kanban').on('scroll', function() - { - $.zui.ContextMenu.hide(); - }); -} - $(document).on('click', 'td.content .more', function(e) { var $toggle = $(this); @@ -171,7 +167,63 @@ function changeCardColType(card, fromColType, toColType, kanbanID) */ function renderKanbanItem(item, $item) { - var $title = $item.children('.title'); + var privs = item.actions; + var $titleBox = $item.children('.titleBox'); + + /* Output header information. */ + if(!$titleBox.length) $titleBox = $( + [ + '
', + '
' + ].join('')).appendTo($item); + + /* Print plan name. */ + var $title = $titleBox.children('.title'); + if(!$title.length) + { + if(privs.includes('view')) $title = $('').appendTo($titleBox).attr('href', createLink('productplan', 'view', 'cardID=' + item.id)); + if(!privs.includes('view')) $title = $('

').appendTo($titleBox); + } + $title.text(item.title).attr('title', item.title); + + /* Determine whether to print an expired label. */ + var today = new Date(); + var begin = $.zui.createDate(item.begin); + var end = $.zui.createDate(item.end); + if(end.toLocaleDateString() < today.toLocaleDateString()) + { + $expired = $titleBox.children('.expired'); + if(!$expired.length) + { + $('' + productplanLang.expired + '').appendTo($titleBox); + } + } + + /* Output plan date information. */ + var $dateBox = $item.children('.dateBox'); + if(!$dateBox.length) $dateBox = $( + [ + '
', + '', + '
' + ].join('')).appendTo($item); + + var $time = $dateBox.children('.time'); + if(item.begin != '2030-01-01' && item.end != '2030-01-01') + { + $time.text($.zui.formatDate(begin, 'MM-dd') + ' ' + productplanLang.to + ' ' + $.zui.formatDate(end, 'MM-dd')).attr('title', $.zui.formatDate(begin, 'yyyy-MM-dd') + productplanLang.to + $.zui.formatDate(end, 'yyyy-MM-dd')).show(); + } + else + { + $time.text(productplanLang.future).attr('title', productplanLang.future).show(); + } + + /* Output plan desc information. */ + var $desc = $item.children('.desc'); + if(!$desc.length) + { + $("
" + item.desc + '
').appendTo($item); + } } /** diff --git a/module/productplan/lang/en.php b/module/productplan/lang/en.php index a0ef357eb9..93d7bcbde9 100644 --- a/module/productplan/lang/en.php +++ b/module/productplan/lang/en.php @@ -30,6 +30,7 @@ $lang->productplan->batchEdit = 'Batch Edit'; $lang->productplan->project = 'Project'; $lang->productplan->plan = 'Plan'; $lang->productplan->allAB = 'All'; +$lang->productplan->to = 'To'; $lang->productplan->batchUnlink = "Batch Unlink"; $lang->productplan->unlinkAB = "Unlink"; diff --git a/module/productplan/lang/zh-cn.php b/module/productplan/lang/zh-cn.php index 30f2fd3a82..b1da22b2d2 100644 --- a/module/productplan/lang/zh-cn.php +++ b/module/productplan/lang/zh-cn.php @@ -31,6 +31,7 @@ $lang->productplan->batchEdit = '批量编辑'; $lang->productplan->project = '项目'; $lang->productplan->plan = '计划'; $lang->productplan->allAB = '所有'; +$lang->productplan->to = '至'; $lang->productplan->batchUnlink = "批量移除"; $lang->productplan->unlinkAB = "移除"; diff --git a/module/productplan/view/browsebykanban.html.php b/module/productplan/view/browsebykanban.html.php index 36cdfec870..267561190c 100644 --- a/module/productplan/view/browsebykanban.html.php +++ b/module/productplan/view/browsebykanban.html.php @@ -18,8 +18,16 @@ #branchBox {width: 120px;} #branch_chosen .icon-delay {padding-right: 10px; font-size: 15px;} #kanbanContainer {padding-bottom: 0; margin-bottom: 0;} +.kanban-card {height: 80px !important;} +.kanban-card .titleBox {width: 100%; display: flex;} +.kanban-card .titleBox > span {flex: none;} +.kanban-card .title {white-space: nowrap; overflow: hidden;} +.kanban-card .expired {margin-left: 2px;} +.kanban-card .dateBox {padding-top: 5px;} +.kanban-card .desc {overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #838a9d; padding-top: 5px;} +productplan);?>