diff --git a/db/update15.0.sql b/db/update15.0.sql index 6bdefddd2b..e5c22331ef 100644 --- a/db/update15.0.sql +++ b/db/update15.0.sql @@ -68,7 +68,7 @@ ALTER TABLE `zt_user` ADD `analysis` text NOT NULL AFTER `nature`; ALTER TABLE `zt_user` ADD `strategy` text NOT NULL AFTER `analysis`; ALTER TABLE `zt_user` CHANGE `avatar` `avatar` text NOT NULL AFTER `commiter`; -REPLACE INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'custom', '', 'URSR', '6'); +REPLACE INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'custom', '', 'URSR', '2'); REPLACE INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'project', '', 'unitList', 'CNY,USD'); REPLACE INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'project', '', 'defaultCurrency', 'CNY'); diff --git a/db/zentao.sql b/db/zentao.sql index ef21a26c0f..86fd568450 100644 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -4146,6 +4146,6 @@ REPLACE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `system`) V INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'custom', '', 'hourPoint', '1'); INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'common', '', 'CRProduct', '1'); INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'common', '', 'CRExecution', '1'); -INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'custom', '', 'URSR', '6'); +INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'custom', '', 'URSR', '2'); INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'project', '', 'unitList', 'CNY,USD'); INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'project', '', 'defaultCurrency', 'CNY'); diff --git a/module/block/view/projectstatisticblock.html.php b/module/block/view/projectstatisticblock.html.php index c118d0de53..de636fab14 100644 --- a/module/block/view/projectstatisticblock.html.php +++ b/module/block/view/projectstatisticblock.html.php @@ -62,7 +62,7 @@ html[lang="en"] .product-info .type-info {color: #A6AAB8; text-align: center; po .block-statistic .data {width: 40%; text-align: left; padding: 10px 0px; font-size: 14px; font-weight: 700;} .block-statistic .dataTitle {width: 60%; text-align: right; padding: 10px 0px; font-size: 14px;} -.block-statistic .executionName {padding-top: 2px; font-size: 14px;} +.block-statistic .executionName {padding: 2px 10px; font-size: 14px;} .block-statistic .lastIteration {padding-top: 6px;} .block-statistic .progress-text-left {margin-right: 90px} .block-statistic .progress-text-left .progress-text {padding-top: 2px; font-size: 14px; padding-right:5px;} @@ -134,70 +134,70 @@ $(function()
- model == 'scrum'):?> -
-
-

block->story;?>

-
-
project->allStories . ":";?>
-
allStories;?>
+ model == 'scrum'):?> +
+
+

block->story;?>

+
+
project->allStories . ":";?>
+
allStories;?>
+
+
+
project->doneStories . ":";?>
+
doneStories;?>
+
+
+
block->left . ":";?>
+
leftStories;?>
+
-
-
project->doneStories . ":";?>
-
doneStories;?>
+
+

block->investment;?>

+
+
block->totalPeople . ":";?>
+
teamCount;?>
+
+
+
block->estimate . ":";?>
+
estimate;?>
+
+
+
block->consumedHours . ":";?>
+
consumed;?>
+
-
-
block->left . ":";?>
-
leftStories;?>
+
+

block->bug;?>

+
+
block->totalBug . ":";?>
+
allBugs;?>
+
+
+
block->doneBugs . ":";?>
+
doneBugs;?>
+
+
+
block->leftBugs . ":";?>
+
leftBugs;?>
+
-
-

block->investment;?>

-
-
block->totalPeople . ":";?>
-
teamCount;?>
-
-
-
block->estimate . ":";?>
-
estimate;?>
-
-
-
block->consumedHours . ":";?>
-
consumed;?>
-
-
-
-

block->bug;?>

-
-
block->totalBug . ":";?>
-
allBugs;?>
-
-
-
block->doneBugs . ":";?>
-
doneBugs;?>
-
-
-
block->leftBugs . ":";?>
-
leftBugs;?>
-
-
-
- executions)):?> -
-

block->last;?>

-
-
createLink('execution', 'task', "executionID={$project->executions[0]->id}"), $project->executions[0]->name);?>
-
-
-
- executions[0]->hours->progress . '%';?> + executions)):?> +
+

block->last;?>

+
+
createLink('execution', 'task', "executionID={$project->executions[0]->id}"), $project->executions[0]->name);?>
+
+
+
+ executions[0]->hours->progress . '%';?> +
-
- - + +
project->weekly;?> diff --git a/module/common/lang/menu.php b/module/common/lang/menu.php index d6f2352e6c..4d30498d71 100644 --- a/module/common/lang/menu.php +++ b/module/common/lang/menu.php @@ -258,7 +258,7 @@ $lang->execution->menu->view['subMenu']->tree = "$lang->treeView|execution| $lang->execution->menu->qa['subMenu'] = new stdclass(); //$lang->execution->menu->qa['subMenu']->qa = array('link' => "$lang->dashboard|execution|qa|executionID=%s"); $lang->execution->menu->qa['subMenu']->bug = array('link' => "{$lang->bug->common}|execution|bug|executionID=%s", 'subModule' => 'bug'); -$lang->execution->menu->qa['subMenu']->testcase = array('link' => "{$lang->testcase->shortCommon}|execution|testcase|executionID=%s", 'alias' => 'create'); +$lang->execution->menu->qa['subMenu']->testcase = array('link' => "{$lang->testcase->shortCommon}|execution|testcase|executionID=%s", 'subModule' => 'testcase'); $lang->execution->menu->qa['subMenu']->testtask = array('link' => "{$lang->testtask->common}|execution|testtask|executionID=%s", 'subModule' => 'testtask'); $lang->execution->menu->qa['subMenu']->testreport = array('link' => "{$lang->testreport->common}|execution|testreport|exeutionID=%s", 'subModule' => 'testreport'); diff --git a/module/doc/control.php b/module/doc/control.php index 636148f606..d1deb4854e 100644 --- a/module/doc/control.php +++ b/module/doc/control.php @@ -877,9 +877,9 @@ class doc extends control // setcookie('from', $from, $this->config->cookieLife, $this->config->webRoot, '', false, true); $this->session->set('docList', $this->app->getURI(true), 'doc'); + $objects = $this->doc->getOrderedObjects($type); if($type == 'product') { - $objects = $this->loadModel('product')->getPairs('nocode'); $objectID = $this->product->saveState($objectID, $objects); $table = TABLE_PRODUCT; @@ -890,7 +890,6 @@ class doc extends control } else { - $objects = $this->loadModel('project')->getPairsByProgram(); $objectID = $this->project->saveState($objectID, $objects); $table = TABLE_PROJECT; @@ -900,6 +899,7 @@ class doc extends control $this->app->rawMethod = 'project'; } + if(!$libID) $libID = key($libs); $object = $this->dao->select('id,name,status')->from($table)->where('id')->eq($objectID)->fetch(); if(empty($object)) $this->locate($this->createLink($type, 'create', '', '', '', $this->session->project)); @@ -913,7 +913,7 @@ class doc extends control $this->doc->buildSearchForm(0, array(), 0, $actionURL, 'objectLibs'); $this->lang->TRActions = common::hasPriv('doc', 'createLib') ? html::a(helper::createLink('doc', 'createLib', "type=$type&objectID=$objectID"), " " . $this->lang->doc->createlib, '', "class='btn btn-secondary iframe' data-width='70%'") : ''; - $this->lang->TRActions .= common::hasPriv('doc', 'create') ? $this->doc->buildCreateButton4Doc($type, $objectID) : ''; + $this->lang->TRActions .= common::hasPriv('doc', 'create') ? $this->doc->buildCreateButton4Doc($type, $objectID, $libID) : ''; $this->view->customObjectLibs = $customObjectLibs; $this->view->showLibs = $this->config->doc->custom->objectLibs; @@ -924,6 +924,7 @@ class doc extends control $this->view->type = $type; $this->view->object = $object; $this->view->libs = $this->doc->getLibsByObject($type, $objectID); + $this->view->moduleTree = $this->doc->getTreeMenu($type, $objectID, 0); $this->view->canBeChanged = common::canModify($type, $object); // Determines whether an object is editable. $this->display(); } diff --git a/module/doc/css/objectlibs.css b/module/doc/css/objectlibs.css index 33aec7c1f9..5c92ebe539 100644 --- a/module/doc/css/objectlibs.css +++ b/module/doc/css/objectlibs.css @@ -3,6 +3,7 @@ .addbtn .icon-plus {font-size: 18px; display: block; opacity: 0.5; transition: opacity .2s; text-shadow: 1px 1px 3px rgba(0,0,0,.2);} .addbtn:hover .icon-plus {opacity: .9; animation: flash-icon 1s linear alternate infinite;} #dropMenu {min-width: 250px; box-sizing: inhert;} +#dropMenu .table-col .list-group {padding-top: 10px;} .main-col .block-files .panel-heading {padding-right: 20px;} .main-col .block-files .panel-heading .panel-title {height: 35px; line-height: 30px;} -#dropMenu .table-col .list-group {padding-top: 10px;} +.side-col .action a {margin-bottom: 3px;} diff --git a/module/doc/lang/en.php b/module/doc/lang/en.php index 748ad2e933..8351758fad 100644 --- a/module/doc/lang/en.php +++ b/module/doc/lang/en.php @@ -49,6 +49,7 @@ $lang->doc->item = ' Items'; $lang->doc->num = 'Documents'; $lang->doc->searchResult = 'Search Result'; $lang->doc->mailto = 'Mailto'; +$lang->doc->noModule = 'No document in this lib, please create it'; $lang->doc->moduleDoc = 'By Module'; $lang->doc->searchDoc = 'Search'; @@ -93,7 +94,7 @@ $lang->doc->createlib = 'Create Document Library'; $lang->doc->allLibs = 'Library List'; $lang->doc->objectLibs = "{$lang->productCommon}/{$lang->executionCommon} Libraries"; $lang->doc->showFiles = 'Attachments'; -$lang->doc->editlib = 'Edit Document Library'; +$lang->doc->editLib = 'Edit Document Library'; $lang->doc->deleteLib = 'Delete Document Library'; $lang->doc->fixedMenu = 'Fix to Menu'; $lang->doc->removeMenu = 'Remove from Menu'; diff --git a/module/doc/lang/zh-cn.php b/module/doc/lang/zh-cn.php index 137f36db1f..4214833e83 100644 --- a/module/doc/lang/zh-cn.php +++ b/module/doc/lang/zh-cn.php @@ -49,6 +49,7 @@ $lang->doc->item = '项'; $lang->doc->num = '文档数量'; $lang->doc->searchResult = '搜索结果'; $lang->doc->mailto = '抄送给'; +$lang->doc->noModule = '文档库下没有目录和文档,请维护目录或者创建文档'; $lang->doc->moduleDoc = '按模块浏览'; $lang->doc->searchDoc = '搜索'; @@ -74,10 +75,10 @@ $lang->doc->view = '文档详情'; $lang->doc->diff = '对比'; $lang->doc->diffAction = '对比文档'; $lang->doc->sort = '文档排序'; -$lang->doc->manageType = '维护分类'; -$lang->doc->editType = '编辑分类'; -$lang->doc->deleteType = '删除分类'; -$lang->doc->addType = '增加分类'; +$lang->doc->manageType = '维护目录'; +$lang->doc->editType = '编辑目录'; +$lang->doc->deleteType = '删除目录'; +$lang->doc->addType = '增加目录'; $lang->doc->childType = '子分类'; $lang->doc->collect = '收藏'; $lang->doc->cancelCollection = '取消收藏'; @@ -93,7 +94,7 @@ $lang->doc->createlib = '创建文档库'; $lang->doc->allLibs = '文档库列表'; $lang->doc->objectLibs = "{$lang->productCommon}/{$lang->executionCommon}库列表"; $lang->doc->showFiles = '附件库'; -$lang->doc->editlib = '编辑文档库'; +$lang->doc->editLib = '编辑文档库'; $lang->doc->deleteLib = '删除文档库'; $lang->doc->fixedMenu = '固定到菜单栏'; $lang->doc->removeMenu = '从菜单栏移除'; diff --git a/module/doc/model.php b/module/doc/model.php index 80661d7dff..9be74f367b 100644 --- a/module/doc/model.php +++ b/module/doc/model.php @@ -1152,6 +1152,76 @@ class docModel extends model return $libs; } + /** + * Get ordered objects for dic. + * + * @param string $objectType + * @access public + * @return array + */ + public function getOrderedObjects($objectType = 'product') + { + $myObjects = $normalObjects = $closedObjects = array(); + if($objectType == 'product') + { + $products = $this->loadModel('product')->getList(); + foreach($products as $id => $product) + { + if($product->status == 'normal' and $product->PO == $this->app->user->account) + { + $myObjects[$id] = $product->name; + } + elseif($product->status == 'normal' and !($product->PO == $this->app->user->account)) + { + $normalObjects[$id] = $product->name; + } + elseif($product->status == 'closed') + { + $closedObjects[$id] = $product->name; + } + } + } + elseif($objectType == 'project') + { + $programs = $this->dao->select('id, name')->from(TABLE_PROGRAM)->where('type')->eq('program')->andWhere('deleted')->eq(0)->orderBy('order_asc')->fetchPairs(); + $projects = $this->dao->select('*')->from(TABLE_PROJECT) + ->where('deleted')->eq(0) + ->andWhere('type')->eq('project') + ->beginIF(!$this->app->user->admin)->andWhere('id')->in($this->app->user->view->projects)->fi() + ->orderBy('order_asc') + ->fetchAll('id'); + + $orderedProjects = array(); + foreach($programs as $programID => $programName) + { + foreach($projects as $id => $project) + { + if($project->parent and $project->parent != $programID) continue; + $orderedProjects[$id] = $project; + unset($projects[$project->id]); + } + } + + foreach($orderedProjects as $id => $project) + { + if($project->status != 'done' and $project->status != 'closed' and $project->PM == $this->app->user->account) + { + $myObjects[$id] = $project->name; + } + else if($project->status != 'done' and $project->status != 'closed' and !($project->PM == $this->app->user->account)) + { + $normalObjects[$id] = $project->name; + } + else if($project->status == 'done' or $project->status == 'closed') + { + $closedObjects[$id] = $project->name; + } + } + } + + return $myObjects + $normalObjects + $closedObjects; + } + /** * Stat module and document counts of lib. * @@ -1598,28 +1668,24 @@ class docModel extends model * * @param string $type * @param int $objectID + * @param int $libID * @access public * @return string */ - public function buildCreateButton4Doc($type, $objectID) + public function buildCreateButton4Doc($type, $objectID, $libID) { - $libs = $this->getLibs('all', strpos($this->config->doc->custom->showLibs, 'unclosed') !== false ? 'unclosedProject' : ''); - $html = ""; - if($libs) + $html = ""; + return $html; } @@ -1814,4 +1880,83 @@ EOF; return $output; } + + /** + * Get doc tree menu. + * + * @param string $rootID + * @param int $rootID + * @param int $startModule + * @access public + * @return string + */ + public function getTreeMenu($type, $rootID, $startModule = 0) + { + return ''; + + $extra['projectID'] = $rootID; + $menu = "
    "; + $startModulePath = ''; + if($startModule > 0) + { + $startModule = $this->getById($startModule); + if($startModule) $startModulePath = $startModule->path . '%'; + } + + $executionModules = $this->getTaskTreeModules($rootID, true); + $executionBranches = $this->dao->select('DISTINCT t2.branch')->from(TABLE_PROJECTSTORY)->alias('t1') + ->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id') + ->where('t1.project')->eq($rootID) + ->andWhere('t2.deleted')->eq(0) + ->fetchPairs(); + + /* Get module according to product. */ + $products = $this->loadModel('product')->getProductPairsByProject($rootID); + $branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products)); + $productNum = count($products); + foreach($products as $id => $product) + { + $projectProductLink = helper::createLink('projectstory', 'story', "projectID=$rootID&productID=$id"); + $executionProductLink = helper::createLink('execution', 'story', "executionID=$rootID&ordery=&status=byProduct&praram=$id"); + $link = $this->app->rawModule == 'projectstory' ? $projectProductLink : $executionProductLink; + if($productNum > 1) $menu .= "
  • " . html::a($link, $product, '_self', "id='product$id'"); + + /* tree menu. */ + $tree = ''; + if(empty($branchGroups[$id])) $branchGroups[$id]['0'] = ''; + foreach($branchGroups[$id] as $branch => $branchName) + { + $treeMenu = array(); + $query = $this->dao->select('*')->from(TABLE_MODULE) + ->where('root')->eq((int)$id) + ->andWhere('type')->eq('story') + ->beginIF(count($branchGroups[$id]) > 1)->andWhere('branch')->eq($branch)->fi() + ->beginIF($startModulePath)->andWhere('path')->like($startModulePath)->fi() + ->andWhere('deleted')->eq(0) + ->orderBy('grade desc, branch, `order`, type') + ->get(); + $stmt = $this->dbh->query($query); + while($module = $stmt->fetch()) + { + /* If not manage, ignore unused modules. */ + if(isset($executionModules[$module->id]) and $this->app->rawModule == 'execution') $this->buildTree($treeMenu, $module, 'task', $userFunc, $extra); + if($this->app->rawModule == 'projectstory') $this->buildTree($treeMenu, $module, 'task', $userFunc, $extra); + } + if((isset($treeMenu[0]) and $branch) or isset($executionBranches[$branch])) + { + $childMenu = isset($treeMenu[0]) ? "
      {$treeMenu[0]}
    " : ''; + $projectBranchLink = helper::createLink('projectstory', 'story', "projectID=$rootID&productID=$id&branch=" . (empty($branch) ? 0 : $branch) . "&browseType=byBranch"); + $executionBranchLink = helper::createLink('execution', 'story', "executionID=$rootID&ordery=&status=byBranch&praram=" . (empty($branch) ? "{$id},0" : $branch)); + $link = $this->app->rawModule == 'projectstory' ? $projectBranchLink : $executionBranchLink; + if($branchName) $treeMenu[0] = "
  • " . html::a($link, $branchName, '_self', "id='branch" . (empty($branch) ? "{$id}_0" : $branch) . "'") . "{$childMenu}
  • "; + } + $tree .= isset($treeMenu[0]) ? $treeMenu[0] : ''; + } + if($productNum > 1) $tree = "
      " . $tree . "
    \n"; + $menu .= $tree; + } + + $menu .= '
'; + return $menu; + } } diff --git a/module/doc/view/side.html.php b/module/doc/view/side.html.php index 4d9f54a3c5..816751b59d 100644 --- a/module/doc/view/side.html.php +++ b/module/doc/view/side.html.php @@ -15,193 +15,22 @@ if(empty($type)) $type = 'product'; $sideWidth = common::checkNotCN() ? '270' : '238'; ?>
-
-
- -
- doclib->tabList as $tabValue => $tabName):?> - -
"> -
    - - -
  • - navGroup->doc == 'doc' and $tabValue == 'execution') - { - echo $lang->noData; - } - else - { - $text = zget($lang->doclib->create, $tabValue, ''); - if($text and common::hasPriv($tabValue, 'create')) echo html::a($this->createLink($tabValue, 'create', ''), $text, '', "class='text-ellipsis'"); - } - ?> -
  • - - $tabMenuName):?> - $subLibName) - { - if(is_numeric($subLibID) and !empty($mainLibID)) $customLibCount += 1; - if(is_numeric($subLibID) and empty($mainLibID)) $mainLibID = $subLibID; - } - } - - $icon = $tabValue == 'product' ? " " : " "; - $activeClass = ($this->methodName == 'objectlibs' && $type == $tabValue && $object->id == $tabMenuID) ? 'active' : ''; - $activeClass = ($this->methodName == 'browse' && isset($currentLib->id) && $currentLib->id == $mainLibID) ? 'active' : $activeClass; - ?> -
  • > - 0):?> - createLink('doc', 'objectLibs', "type=$tabValue&objectID=$tabMenuID"), $icon . $tabMenuName, '', "class='text-ellipsis' title='{$tabMenuName}'");?> - - createLink('doc', 'browse', "libID=$mainLibID"), $icon . $tabMenuName, '', "class='text-ellipsis' title='{$tabMenuName}'");?> - - -
      - $subLibName):?> - methodName == 'alllibs' && $type == 'execution' && $$tabValue == $tabMenuID) ? "class='active'" : ''; - $icon = 'icon-stack'; - } - elseif($subLibID == 'files') - { - $subLibLink = inlink('showFiles', "type=$tabValue&objectID=$tabMenuID"); - $activeClass = ($this->methodName == 'showfiles' && $type == $tabValue && $object->id == $tabMenuID) ? "class='active'" : ''; - $icon = 'icon-paper-clip'; - } - else - { - $subLibLink = inlink('browse', "libID=$subLibID"); - $activeClass = ($this->methodName == 'browse' && $browseType != 'bymodule' && $subLibID == $libID) ? "class='active'" : ''; - $icon = 'icon-folder-outline'; - } - ?> - 0):?> -
    • > - " . $subLibName, '', "class='text-ellipsis' title='{$subLibName}'");?> - - - 0):?> -
        - - - parent != 0) continue;?> -
      • methodName == 'browse' && $browseType == 'bymodule' && $moduleID == $module->id) echo "class='active'";?>> - createLink('doc', 'browse', "libID=$subLibID&browseType=byModule¶m={$module->id}"), " " . $module->name, '', "class='text-ellipsis' title='{$module->name}'");?> - doc->printChildModule($module, $subLibID, $this->methodName, $browseType, $moduleID);?> -
      • - - 0):?> -
      - - - 0):?> -
    • - - -
    • > - " . $subLibName, '', "class='text-ellipsis' title='{$subLibName}'");?> -
    • - - -
    - -
  • - - - - - -
  • - doclib->create, $tabValue, ''); - if($text and common::hasPriv('doc', 'createLib')) echo html::a($this->createLink('doc', 'createLib', "type={$tabValue}"), $text, '', "class='iframe' data-width='70%'"); - ?> -
  • - - $sideLibName):?> - - - - methodName == 'objectlibs' && $type == $tabValue && $object->id == $sideLibID) ? 'active' : ''; - $activeClass = ($this->methodName == 'browse' && isset($currentLib->id) && $currentLib->id == $sideLibID) ? 'active' : $activeClass; - ?> -
  • > - createLink('doc', 'browse', "libID=$sideLibID"), " " . $sideLibName, '', "class='text-ellipsis' title='{$sideLibName}'");?> - -
      - - parent != 0) continue;?> -
    • methodName == 'browse' && $browseType == 'bymodule' && $moduleID == $module->id) echo "class='active'";?>> - createLink('doc', 'browse', "libID=$sideLibID&browseType=byModule¶m={$module->id}"), " " . $module->name, '', "class='text-ellipsis' title='{$module->name}'");?> - doc->printChildModule($module, $sideLibID, $this->methodName, $browseType, $moduleID);?> -
    • - -
    - -
  • - - - - - -
-
- +
+ +
+
+ doc->noModule;?> +
+
+ + +
+ doc->manageType, '', "class='btn btn-info btn-wide'");?> + doc->editLib, '', "class='btn btn-info btn-wide'");?> + doc->deleteLib, '', "class='btn btn-info btn-wide'");?> +
- -
-