diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php index 1df83f794f..5e9a4885be 100755 --- a/module/common/lang/zh-cn.php +++ b/module/common/lang/zh-cn.php @@ -123,7 +123,7 @@ $lang->common->common = '公有模块'; $lang->mainNav = new stdclass(); $lang->mainNav->my = ' 地盘|my|index|'; $lang->mainNav->program = ' 项目集|program|pgmindex|'; -$lang->mainNav->product = ' 产品|product|all|'; +$lang->mainNav->product = ' 产品|product|productlist|'; $lang->mainNav->project = ' 项目|program|prjbrowse|'; $lang->mainNav->system = ' 组织|custom|estimate|'; $lang->mainNav->admin = ' 后台|admin|index|'; diff --git a/module/product/control.php b/module/product/control.php index 33600f8155..b25e469808 100644 --- a/module/product/control.php +++ b/module/product/control.php @@ -30,8 +30,8 @@ class product extends control $this->loadModel('user'); /* Get all products, if no, goto the create page. */ - $this->products = $this->product->getPairs('nocode', $this->session->PRJ); - if(empty($this->products) and strpos(',create,index,showerrornone,', $this->methodName) === false and $this->app->getViewType() != 'mhtml') $this->locate($this->createLink('product', 'create')); + $this->products = $this->product->getPairs('nocode', $this->session->program); + if(empty($this->products) and strpos(',productlist,create,index,showerrornone,', $this->methodName) === false and $this->app->getViewType() != 'mhtml') $this->locate($this->createLink('product', 'create')); $this->view->products = $this->products; } @@ -871,4 +871,42 @@ class product extends control $this->session->set('product', (int)$productID); $this->send(array('result' => 'success', 'productID' => $this->session->product)); } + + /** + * Products under project set. + * + * @param int $programID + * @param string $browseType + * @param int $param + * @param string $orderBy + * @param int $recTotal + * @param int $recPerPage + * @param int $pageID + * @access public + * @return void + */ + public function productList($programID = 0, $browseType = 'all', $param = 0, $orderBy = 'order_desc', $recTotal = 0, $recPerPage = 15, $pageID = 1) + { + $this->session->set('program', $programID); + $this->loadModel('program'); + + /* Load pager and get tasks. */ + $this->app->loadClass('pager', $static = true); + $pager = new pager($recTotal, $recPerPage, $pageID); + + $program = $programID ? $this->program->getPGMByID($programID) : 0; + + $this->view->title = $this->lang->product->common; + $this->view->position[] = $this->lang->product->common; + + $this->view->productStats = $this->product->getStats($orderBy, $pager, $browseType); + $this->view->lines = array('') + $this->tree->getLinePairs(); + $this->view->orderBy = $orderBy; + $this->view->pager = $pager; + $this->view->programTree = $this->program->getPGMTreeMenu($programID, true); + $this->view->programID = $programID; + $this->view->program = $program; + $this->view->browseType = $browseType; + $this->display(); + } } diff --git a/module/product/css/productlist.css b/module/product/css/productlist.css new file mode 100644 index 0000000000..eb3cf03202 --- /dev/null +++ b/module/product/css/productlist.css @@ -0,0 +1,35 @@ +.side-col .detail-content{padding-left: 10px; margin-top: 0px} +.tree li.has-list.open:before {border-left: none;} +#programTree li {padding: 0 0 0 8px;} +#programTree li.has-list {padding-left: 20px;} +#programTree li > a {display: block; padding: 5px 0; border-radius: 2px; padding-left: 6px; height: 30px;} +#programTree li > a > span {display: inline-block;} +#programTree li > a > span + span {margin-left: 8px;} +#programTree li.selected > a {background-color: #E8F3FC;} +#programTree li.selected > a > span.title {color: #006AF1;} +#programTree .label-id {border-color: #cbd0db; color: #7d8599} +#programTree .label.label-type {background: #fff; border: 1px solid #7d8599; color:#7d8599} + +#programTree li > a > span.title {color: #3C4353; white-space: nowrap; max-width: 60%; overflow: hidden; text-overflow: ellipsis; vertical-align: middle;} +#programTree li > a > span.user {color: #838a9d;} +#programTree li > a > span.user > .icon-person {font-size: 14px; position: relative; top: -1px; color: #a6aab8} + +#programTree li > .list-toggle {transform: rotate(0deg); width: 16px; height: 16px; border: 4px solid #a6aab8; border-radius: 2px; top: 7px;} +#programTree li > .list-toggle:before {content: ' '; display: block; position: absolute; border: 1px solid #a6aab8; top: 2px; left: -3px; right: -3px; bottom: 2px; min-width: 0; transition: all .2s;} +#programTree li > .list-toggle:hover:before, +#programTree li > .list-toggle:hover {border-color: #006AF1;} +#programTree li.open > .list-toggle {width: 12px; height: 12px; top: 9px; background-color: #a6aab8; border-width: 3px; left: 3px;} +#programTree li.open > .list-toggle:before {border: none; height: 2px; width: 6px; left: 0; top: 2px; background: #fff;} +#programTree li.open > .list-toggle:hover {background: #006AF1;} + +#programTree ul > li:after {display: block; position: absolute; content: ' '; border-top: 2px solid #cbd0db; top: 14px; left: -12px; z-index: 1; width: 10px;} +#programTree ul > li:before, +#programTree ul > li.has-list:before {background: none; content: ' '; display: block; position: absolute; width: auto; height: auto; border: none; border-left: 2px solid #cbd0db; top: -13px; bottom: 12px; left: -12px;} +#programTree ul > li:last-child:before {bottom: auto; height: 29px;} +#programTree ul > li:first-child:before {top: -9px;} +#programTree ul > li.has-list:first-child:before {top: -13px;} +#programTree ul > li.tree-single-item:before {height: 23px;} +#programTree ul > li.has-list:after {width: 14px;} +#programTree ul > li.item-meas a.selected{color: #0c64eb;} +.side-col {padding-right: 20px; width: 18%} +#sidebar>.cell {width: 100%;} diff --git a/module/product/js/productlist.js b/module/product/js/productlist.js new file mode 100644 index 0000000000..3fca145aad --- /dev/null +++ b/module/product/js/productlist.js @@ -0,0 +1,13 @@ +$("#" + browseType + "Tab").addClass('btn-active-text'); +$('#programTree').tree(); +$('#program' + programID).addClass('active'); +$(".tree .active").parent('li').addClass('active'); +$(function() +{ + $('#productTableList').on('sort.sortable', function(e, data) + { + var list = ''; + for(i = 0; i < data.list.length; i++) list += $(data.list[i].item).attr('data-id') + ','; + $.post(createLink('product', 'updateOrder'), {'products' : list, 'orderBy' : orderBy}); + }); +}); diff --git a/module/product/lang/zh-cn.php b/module/product/lang/zh-cn.php index 5d55d37cd4..007cecde83 100644 --- a/module/product/lang/zh-cn.php +++ b/module/product/lang/zh-cn.php @@ -30,8 +30,6 @@ $lang->product->orderAction = "{$lang->productCommon}排序"; $lang->product->all = "所有{$lang->productCommon}"; $lang->product->export = '导出数据'; $lang->product->exportAction = "导出{$lang->productCommon}"; -$lang->product->stack = '项目集'; -$lang->product->createstack = '创建项目集'; $lang->product->basicInfo = '基本信息'; $lang->product->otherInfo = '其他信息'; diff --git a/module/product/model.php b/module/product/model.php index 5fe566e874..d3a0eb1e7e 100644 --- a/module/product/model.php +++ b/module/product/model.php @@ -912,7 +912,7 @@ class productModel extends model $this->loadModel('story'); $this->loadModel('bug'); - $products = $this->getList($this->session->PRJ, $status, $limit = 0, $line); + $products = $this->getList($this->session->program, $status, $limit = 0, $line); $products = $this->dao->select('*')->from(TABLE_PRODUCT) ->where('id')->in(array_keys($products)) ->orderBy($orderBy) @@ -965,6 +965,7 @@ class productModel extends model ->andWhere('product')->in(array_keys($products)) ->groupBy('product') ->fetchPairs(); + $unResolved = $this->dao->select('product,count(*) AS count') ->from(TABLE_BUG) ->where('deleted')->eq(0) @@ -972,6 +973,7 @@ class productModel extends model ->andWhere('product')->in(array_keys($products)) ->groupBy('product') ->fetchPairs(); + $assignToNull = $this->dao->select('product,count(*) AS count') ->from(TABLE_BUG) ->where('deleted')->eq(0) diff --git a/module/product/view/productlist.html.php b/module/product/view/productlist.html.php new file mode 100644 index 0000000000..38fb270506 --- /dev/null +++ b/module/product/view/productlist.html.php @@ -0,0 +1,112 @@ + + * @package ZenTaoPMS + * @version $Id + */ +?> + + + +
+ +
+
'> + + + + recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + idAB);?> +
product->name);?>product->line);?>product->activeStories;?>product->changedStories;?>product->draftStories;?>product->closedStories;?>product->plans;?>product->releases;?>product->unResolvedBugs;?>product->assignToNullBugs;?>product->updateOrder);?>
+ + id => sprintf('%03d', $product->id)));?> + + id);?> + + createLink('product', 'view', 'product=' . $product->id), $product->name);?>'>line, '');?>stories['active'];?>stories['changed'];?>stories['draft'];?>stories['closed'];?>plans;?>releases;?>unResolved;?>assignToNull;?>
+ + + +
+
+
+ + + + diff --git a/module/program/model.php b/module/program/model.php index 931e5b95dd..19eb2ded78 100644 --- a/module/program/model.php +++ b/module/program/model.php @@ -712,11 +712,12 @@ class programModel extends model /** * Get the treemenu of program. * - * @param int $programID + * @param int $programID + * @param int $productList * @access public * @return string */ - public function getPGMTreeMenu($programID = 0) + public function getPGMTreeMenu($programID = 0, $productList = false) { $programMenu = array(); $query = $this->dao->select('*')->from(TABLE_PROJECT) @@ -727,7 +728,9 @@ class programModel extends model while($program = $stmt->fetch()) { - $linkHtml = html::a(helper::createLink('program', 'pgmview', "programID=$program->id", '', '', $program->id), " " . $program->name); + $link = helper::createLink('program', 'pgmview', "programID=$program->id", '', '', $program->id); + if($productList) $link = helper::createLink('product', 'productlist', "programID=$program->id", '', '', $program->id); + $linkHtml = html::a($link, " " . $program->name, '', "id='program$program->id'"); if(isset($programMenu[$program->id]) and !empty($programMenu[$program->id])) { @@ -1084,7 +1087,8 @@ class programModel extends model if($program) $path = $program->path; return $this->dao->select('*')->from(TABLE_PROJECT) - ->beginIF($projectID > 0)->where('path')->like($path . '%')->fi() + ->where('type')->in('project,program') + ->beginIF($projectID > 0)->andWhere('path')->like($path . '%')->fi() ->orderBy('grade desc, `order`') ->get(); }