diff --git a/VERSION b/VERSION
index 4b99d26192..343f3a761a 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-15.0.beta1
+15.0.rc1
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..3ca79c4803 100644
--- a/db/zentao.sql
+++ b/db/zentao.sql
@@ -811,6 +811,7 @@ CREATE TABLE IF NOT EXISTS `zt_story` (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`parent` mediumint(9) NOT NULL default '0',
`product` mediumint(8) unsigned NOT NULL default '0',
+ `project` mediumint(8) unsigned NOT NULL default '0',
`branch` mediumint(8) unsigned NOT NULL default '0',
`module` mediumint(8) unsigned NOT NULL default '0',
`plan` text,
@@ -4146,6 +4147,7 @@ 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', 'common', 'global', 'mode', 'new');
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/framework/router.class.php b/framework/router.class.php
index e665fb722d..569859956e 100755
--- a/framework/router.class.php
+++ b/framework/router.class.php
@@ -154,7 +154,6 @@ class router extends baseRouter
{
if(!defined('ITERATION_KEY')) define('ITERATION_KEY', 0);
if(!defined('SPRINT_KEY')) define('SPRINT_KEY', 1);
- if(!defined('STAGE_KEY')) define('STAGE_KEY', 2);
if(!defined('PRODUCT_KEY')) define('PRODUCT_KEY', 0);
if(!defined('STORYPOINT_KEY')) define('STORYPOINT_KEY', 1);
if(!defined('FUNCTIONPOINT_KEY')) define('FUNCTIONPOINT_KEY', 2);
@@ -206,12 +205,7 @@ class router extends baseRouter
if($hourKey == STORYPOINT_KEY) $config->hourUnit = 'sp';
if($hourKey == FUNCTIONPOINT_KEY) $config->hourUnit = 'fp';
- $model = new stdclass();
- $model->model = 'scrum';
- //if($this->session->PRJ) $model = $this->dbh->query('SELECT model FROM' . TABLE_PROJECT . "WHERE id = {$this->session->PRJ}")->fetch();
-
$iterationKey = $projectKey;
- if(isset($model->model) && $model->model == 'waterfall') $projectKey = STAGE_KEY;
/* Set productCommon, projectCommon and hourCommon. Default english lang. */
$lang->productCommon = $this->config->productCommonList[$this->clientLang][PRODUCT_KEY];
@@ -244,7 +238,7 @@ class router extends baseRouter
if($this->dbh and !empty($this->config->db->name) and !defined('IN_UPGRADE'))
{
/* Get story concept in project and product. */
- $URSRList = $this->dbh->query('SELECT `key`, `value` FROM' . TABLE_LANG . "WHERE module = 'custom' and section = 'URSRList' and `key` = \"{$this->clientLang}\"")->fetchAll();
+ $URSRList = $this->dbh->query('SELECT `key`, `value` FROM' . TABLE_LANG . "WHERE module = 'custom' and section = 'URSRList' and `lang` = \"{$this->clientLang}\"")->fetchAll();
if(empty($URSRList)) $URSRList = $this->dbh->query('SELECT `key`, `value` FROM' . TABLE_LANG . "WHERE module = 'custom' and section = 'URSRList' and `key` = \"{$config->URSR}\"")->fetchAll();
/* Get UR pairs and SR pairs. */
diff --git a/module/block/view/contribute.html.php b/module/block/view/contribute.html.php
index 97858ccb15..9e2260c17a 100644
--- a/module/block/view/contribute.html.php
+++ b/module/block/view/contribute.html.php
@@ -6,10 +6,12 @@
block->createdTodos;?>
createLink('my', 'todo', 'type=all'), (int)$data['createdTodos']);?>
+ URAndSR):?>
block->createdRequirements;?>
+
block->createdStories;?>
diff --git a/module/block/view/projectstatisticblock.html.php b/module/block/view/projectstatisticblock.html.php
index 37532e6a0d..23cbdc39f4 100644
--- a/module/block/view/projectstatisticblock.html.php
+++ b/module/block/view/projectstatisticblock.html.php
@@ -62,10 +62,10 @@ 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;}
+.block-statistic .progress-text-left .progress-text {padding-top: 2px; font-size: 14px; padding-right:5px; left: -45px;}
.status-count {margin: auto;}
.status-count tr:first-child td:last-child {color: #000; font-weight: bold;}
@@ -134,68 +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;?>
-
-
-
-
-
block->last;?>
-
-
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/block/view/recentprojectblock.html.php b/module/block/view/recentprojectblock.html.php
index 5646c60e8a..1b08ff76b4 100644
--- a/module/block/view/recentprojectblock.html.php
+++ b/module/block/view/recentprojectblock.html.php
@@ -22,7 +22,7 @@
#cards .project-detail .progress {height: 4px;}
#cards .project-detail .progress-text-left .progress-text {width: 50px; left: -50px;}
#cards .panel-heading {cursor: pointer;}
-#cards .project-stages-container {margin: 0 -16px -16px -16px; padding: 0 4px; height: 46px; overflow-x: auto; position: relative;}
+#cards .project-stages-container {margin: 0 0 -16px 0; padding: 0 4px; height: 46px; overflow-x: auto; position: relative;}
#cards .project-stages:after {content: ' '; width: 30px; display: block; right: -16px; top: 16px; bottom: -6px; z-index: 1; background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%); position: absolute;}
#cards .project-stages-row {position: relative; height: 30px; z-index: 0;}
#cards .project-stage-item {white-space: nowrap; position: absolute; top: 0; min-width: 48px; padding-top: 13px; color: #838A9D;}
diff --git a/module/block/view/todoblock.html.php b/module/block/view/todoblock.html.php
index b49987904e..55cb05f1c3 100644
--- a/module/block/view/todoblock.html.php
+++ b/module/block/view/todoblock.html.php
@@ -96,7 +96,7 @@ if(!$selfCall) die(include('./todolist.html.php'));
?>
- >
+ >
date == '2030-01-01') :?>
todo->periods['future'] ?>
diff --git a/module/bug/control.php b/module/bug/control.php
index 90e202f660..8f1d5148fd 100644
--- a/module/bug/control.php
+++ b/module/bug/control.php
@@ -1098,11 +1098,12 @@ class bug extends control
/**
* Batch update assign of bug.
*
- * @param int $executionID
+ * @param int $objectID projectID|executionID
+ * @param string $type execution|project|product|my
* @access public
* @return void
*/
- public function batchAssignTo($executionID, $type = 'execution')
+ public function batchAssignTo($objectID, $type = 'execution')
{
if(!empty($_POST) && isset($_POST['bugIDList']))
{
@@ -1119,8 +1120,10 @@ class bug extends control
}
$this->loadModel('score')->create('ajax', 'batchOther');
}
+
if($type == 'product' || $type == 'my') die(js::locate($this->session->bugList, 'parent'));
- die(js::locate($this->createLink('execution', 'bug', "executionID=$executionID")));
+ if($type == 'execution') die(js::locate($this->createLink('execution', 'bug', "executionID=$objectID")));
+ if($type == 'project') die(js::locate($this->createLink('project', 'bug', "projectID=$objectID")));
}
/**
diff --git a/module/common/lang/menu.php b/module/common/lang/menu.php
index a01621e869..848b1a7125 100644
--- a/module/common/lang/menu.php
+++ b/module/common/lang/menu.php
@@ -158,6 +158,8 @@ $lang->product->menuOrder[55] = 'setting';
$lang->product->menuOrder[60] = 'create';
$lang->product->menuOrder[65] = 'all';
+$lang->product->menu->doc['subMenu'] = new stdclass();
+
$lang->product->menu->settings['subMenu'] = new stdclass();
$lang->product->menu->settings['subMenu']->view = array('link' => "{$lang->overview}|product|view|productID=%s", 'alias' => 'edit');
$lang->product->menu->settings['subMenu']->module = array('link' => "{$lang->module}|tree|browse|product=%s&view=story", 'subModule' => 'tree');
@@ -197,6 +199,8 @@ $lang->scrum->menuOrder[40] = 'release';
$lang->scrum->menuOrder[48] = 'dynamic';
$lang->scrum->menuOrder[50] = 'settings';
+$lang->scrum->menu->doc['subMenu'] = new stdclass();
+
$lang->scrum->menu->qa['subMenu'] = new stdclass();
//$lang->scrum->menu->qa['subMenu']->index = array('link' => "$lang->dashboard|project|qa|projectID=%s");
$lang->scrum->menu->qa['subMenu']->bug = array('link' => "{$lang->bug->common}|project|bug|projectID=%s", 'subModule' => 'bug');
@@ -245,6 +249,8 @@ $lang->execution->menuOrder[55] = 'release';
$lang->execution->menuOrder[60] = 'action';
$lang->execution->menuOrder[65] = 'setting';
+$lang->execution->menu->doc['subMenu'] = new stdclass();
+
$lang->execution->menu->view['subMenu'] = new stdclass();
$lang->execution->menu->view['subMenu']->groupTask = "$lang->groupView|execution|grouptask|executionID=%s";
$lang->execution->menu->view['subMenu']->tree = "$lang->treeView|execution|tree|executionID=%s";
@@ -252,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');
@@ -320,8 +326,8 @@ $lang->doc->menu->dashboard = array('link' => "{$lang->dashboard}|doc|index");
$lang->doc->menu->recent = array('link' => "{$lang->doc->recent}|doc|browse|libID=0&browseTyp=byediteddate", 'alias' => 'recent');
$lang->doc->menu->my = array('link' => "{$lang->doc->my}|doc|browse|libID=0&browseTyp=openedbyme", 'alias' => 'my');
$lang->doc->menu->collect = array('link' => "{$lang->doc->favorite}|doc|browse|libID=0&browseTyp=collectedbyme", 'alias' => 'collect');
-$lang->doc->menu->product = array('link' => "{$lang->doc->product}|doc|objectLibs|type=product");
-$lang->doc->menu->project = array('link' => "{$lang->doc->project}|doc|objectLibs|type=project");
+$lang->doc->menu->product = array('link' => "{$lang->doc->product}|doc|objectLibs|type=product", 'alias' => 'product');
+$lang->doc->menu->project = array('link' => "{$lang->doc->project}|doc|objectLibs|type=project", 'alias' => 'project');
$lang->doc->menu->custom = array('link' => "{$lang->doc->custom}|doc|objectLibs|libID=0");
$lang->doc->dividerMenu = ',product,';
@@ -335,6 +341,9 @@ $lang->doc->menuOrder[25] = 'product';
$lang->doc->menuOrder[30] = 'project';
$lang->doc->menuOrder[35] = 'custom';
+$lang->doc->menu->product['subMenu'] = new stdclass();
+$lang->doc->menu->project['subMenu'] = new stdclass();
+
/* Report menu.*/
$lang->report->menu = new stdclass();
$lang->report->menu->annual = array('link' => "{$lang->report->annual}|report|annualData|year=&dept=&userID=" . (isset($_SESSION['user']) ? zget($_SESSION['user'], 'id', 0) : 0), 'target' => '_blank');
@@ -373,7 +382,7 @@ $lang->admin->menu->custom = array('link' => "{$lang->custom->common}|custom|
$lang->admin->menu->extension = array('link' => "{$lang->extension->common}|extension|browse", 'subModule' => 'extension');
$lang->admin->menu->dev = array('link' => "$lang->redev|dev|api", 'alias' => 'db', 'subModule' => 'dev,editor,entry');
$lang->admin->menu->message = array('link' => "{$lang->message->common}|message|index", 'subModule' => 'message,mail,webhook');
-$lang->admin->menu->system = array('link' => "{$lang->admin->system}|backup|index", 'subModule' => 'cron,backup,action,admin,search', 'exclude' => 'admin-index');
+$lang->admin->menu->system = array('link' => "{$lang->admin->system}|backup|index", 'subModule' => 'cron,backup,action,admin,search', 'exclude' => 'admin-index,admin-xuanxuan');
/* Admin menu order. */
$lang->admin->menuOrder[5] = 'index';
@@ -529,7 +538,8 @@ $lang->navGroup->entry = 'admin';
$lang->navGroup->extension = 'admin';
$lang->navGroup->action = 'admin';
-$lang->navGroup->search = 'search';
-$lang->navGroup->index = 'index';
-$lang->navGroup->tree = 'tree';
-$lang->navGroup->misc = 'misc';
+$lang->navGroup->search = 'search';
+$lang->navGroup->index = 'index';
+$lang->navGroup->tree = 'tree';
+$lang->navGroup->misc = 'misc';
+$lang->navGroup->upgrade = 'upgrade';
diff --git a/module/custom/config.php b/module/custom/config.php
index d8c98dc875..e5837ffb1e 100644
--- a/module/custom/config.php
+++ b/module/custom/config.php
@@ -62,7 +62,7 @@ $config->custom->fieldList['testsuite'] = 'desc';
$config->custom->fieldList['caselib'] = 'desc';
$config->custom->fieldList['testcase']['createcase'] = 'lib,stage,pri,precondition,keywords';
$config->custom->fieldList['testreport'] = 'begin,end,members,report';
-$config->custom->fieldList['testtask'] = 'owner,pri,status,desc';
+$config->custom->fieldList['testtask'] = 'owner,pri,desc';
$config->custom->fieldList['doc'] = 'keywords,content';
$config->custom->fieldList['user']['create'] = 'dept,role,email,commiter';
$config->custom->fieldList['user']['edit'] = 'dept,role,email,commiter,skype,qq,mobile,phone,address,zipcode,dingding,slack,whatsapp,weixin';
diff --git a/module/custom/control.php b/module/custom/control.php
index 00b5a84737..ce5e543de9 100644
--- a/module/custom/control.php
+++ b/module/custom/control.php
@@ -540,7 +540,7 @@ class custom extends control
$mode = zget($this->config->global, 'mode', 'classic');
if($mode == 'new')
{
- if(isset($this->config->global->upgradeStep) and $this->config->global->upgradeStep == 'mergeProgram') $this->locate($this->createLink('upgrade', 'mergeProgram'));
+ if(isset($this->config->global->upgradeStep) and $this->config->global->upgradeStep == 'mergeProgram') $this->locate($this->createLink('upgrade', 'mergeProgram'), 'parent');
unset($_SESSION['upgrading']);
$this->locate(inlink('index'));
diff --git a/module/doc/control.php b/module/doc/control.php
index b9ffb0c8a5..d1deb4854e 100644
--- a/module/doc/control.php
+++ b/module/doc/control.php
@@ -47,10 +47,6 @@ class doc extends control
$this->app->loadClass('pager', $static = true);
$pager = new pager(0, 5, 1);
- $this->lang->TRActions = $this->doc->setFastMenu($this->lang->doc->fast);
- $this->lang->TRActions .= common::hasPriv('doc', 'createLib') ? html::a(helper::createLink('doc', 'createLib'), " " . $this->lang->doc->createlib, '', "class='btn btn-secondary iframe' data-width='70%'") : '';
- $this->lang->TRActions .= common::hasPriv('doc', 'create') ? $this->doc->buildCreateButton4Doc() : '';
-
$actionURL = $this->createLink('doc', 'browse', "lib=0&browseType=bySearch&queryID=myQueryID");
$this->doc->buildSearchForm(0, array(), 0, $actionURL, 'index');
@@ -218,7 +214,7 @@ class doc extends control
if(!dao::isError())
{
$this->action->create('docLib', $libID, 'Created');
- die(js::locate($this->createLink($this->moduleName, 'browse', "libID=$libID"), 'parent.parent'));
+ die(js::locate($this->createLink('doc', 'objectLibs', "type=$type&objectID=$objectID&libID=$libID"), 'parent.parent'));
}
else
{
@@ -226,9 +222,9 @@ class doc extends control
}
}
- $projectID = $this->session->project;
- $products = $this->product->getProductPairsByProject($projectID, 'noclosed');
- $executions = $this->execution->getByProject($projectID, 'all', 0, true);
+ $products = $this->product->getPairs();
+ $projects = $this->project->getPairsByProgram();
+ $executions = $this->execution->getPairs();
$libTypeList = $this->lang->doc->libTypeList;
if(empty($products)) unset($libTypeList['product']);
@@ -237,6 +233,7 @@ class doc extends control
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->users = $this->user->getPairs('nocode');
$this->view->products = $products;
+ $this->view->projects = $projects;
$this->view->executions = $executions;
$this->view->type = $type;
$this->view->libTypeList = $libTypeList;
@@ -310,7 +307,7 @@ class doc extends control
* @access public
* @return void
*/
- public function create($libID, $moduleID = 0, $docType = '')
+ public function create($type, $objectID, $libID, $moduleID = 0, $docType = '')
{
if(!empty($_POST))
{
@@ -336,6 +333,22 @@ class doc extends control
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $link));
}
+ if($this->app->openApp == 'product')
+ {
+ $this->product->setMenu($objectID);
+ unset($this->lang->product->menu->doc['subMenu']);
+ }
+ else if($this->app->openApp == 'project')
+ {
+ $this->project->setMenu($objectID);
+ unset($this->lang->project->menu->doc['subMenu']);
+ }
+ else if($this->app->openApp == 'execution')
+ {
+ $this->execution->setMenu($objectID);
+ unset($this->lang->exectuion->menu->doc['subMenu']);
+ }
+
$lib = $this->doc->getLibByID($libID);
$type = $lib->type;
@@ -859,12 +872,34 @@ class doc extends control
* @access public
* @return void
*/
- public function objectLibs($type, $objectID = 0)
+ public function objectLibs($type, $objectID = 0, $libID = 0)
{
// setcookie('from', $from, $this->config->cookieLife, $this->config->webRoot, '', false, true);
$this->session->set('docList', $this->app->getURI(true), 'doc');
- $table = $type == 'product' ? TABLE_PRODUCT : TABLE_PROJECT;
+ $objects = $this->doc->getOrderedObjects($type);
+ if($type == 'product')
+ {
+ $objectID = $this->product->saveState($objectID, $objects);
+ $table = TABLE_PRODUCT;
+
+ $libs = $this->doc->getLibsByObject('product', $objectID);
+ $this->lang->modulePageNav = $this->doc->select($type, $objects, $objectID, $libs, $libID == 0 ? key($libs) : $libID);
+
+ $this->app->rawMethod = 'product';
+ }
+ else
+ {
+ $objectID = $this->project->saveState($objectID, $objects);
+ $table = TABLE_PROJECT;
+
+ $libs = $this->doc->getLibsByObject('project', $objectID);
+ $this->lang->modulePageNav = $this->doc->select($type, $objects, $objectID, $libs, $libID == 0 ? key($libs) : $libID);
+
+ $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));
@@ -877,6 +912,9 @@ class doc extends control
$actionURL = $this->createLink('doc', 'browse', "lib=0&browseType=bySearch&queryID=myQueryID");
$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, $libID) : '';
+
$this->view->customObjectLibs = $customObjectLibs;
$this->view->showLibs = $this->config->doc->custom->objectLibs;
@@ -886,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 42e741fb34..5c92ebe539 100644
--- a/module/doc/css/objectlibs.css
+++ b/module/doc/css/objectlibs.css
@@ -3,5 +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;}
+.side-col .action a {margin-bottom: 3px;}
diff --git a/module/doc/js/createlib.js b/module/doc/js/createlib.js
index 94a784e005..8e756e199d 100644
--- a/module/doc/js/createlib.js
+++ b/module/doc/js/createlib.js
@@ -14,18 +14,28 @@ function changeByLibType(libType)
if(libType == 'product')
{
$('table tr.product').removeClass('hidden');
+ $('table tr.project').addClass('hidden');
+ $('table tr.execution').addClass('hidden');
+ changeDoclibAcl(libType);
+ }
+ else if(libType == 'project')
+ {
+ $('table tr.product').addClass('hidden');
+ $('table tr.project').removeClass('hidden');
$('table tr.execution').addClass('hidden');
changeDoclibAcl(libType);
}
else if(libType == 'execution')
{
$('table tr.product').addClass('hidden');
+ $('table tr.project').addClass('hidden');
$('table tr.execution').removeClass('hidden');
changeDoclibAcl(libType);
}
else
{
$('table tr.product').addClass('hidden');
+ $('table tr.project').addClass('hidden');
$('table tr.execution').addClass('hidden');
changeDoclibAcl(libType);
}
diff --git a/module/doc/lang/en.php b/module/doc/lang/en.php
index cbd766b9ce..8351758fad 100644
--- a/module/doc/lang/en.php
+++ b/module/doc/lang/en.php
@@ -13,6 +13,7 @@
$lang->doc->common = 'Document';
$lang->doc->id = 'ID';
$lang->doc->product = $lang->productCommon;
+$lang->doc->project = 'Project';
$lang->doc->execution = $lang->executionCommon;
$lang->doc->lib = 'Library';
$lang->doc->module = 'Category';
@@ -48,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';
@@ -82,6 +84,8 @@ $lang->doc->collect = 'Add Favorite';
$lang->doc->cancelCollection = 'Remove Favorite';
$lang->doc->deleteFile = 'Delete File';
+$lang->doc->collectAction = 'Add Favorite';
+
$lang->doc->libName = 'Document Library';
$lang->doc->libType = 'Category';
$lang->doc->custom = 'Custom Document Library';
@@ -90,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';
@@ -101,6 +105,7 @@ $lang->doc->allProduct = 'All' . $lang->productCommon . 's';
$lang->doc->allExecutions = 'All' . $lang->executionCommon . 's';
$lang->doc->libTypeList['product'] = $lang->productCommon . ' Library';
+$lang->doc->libTypeList['project'] = 'Project Library';
$lang->doc->libTypeList['execution'] = $lang->executionCommon . ' Library';
$lang->doc->libTypeList['custom'] = 'Custom Library';
@@ -212,6 +217,7 @@ $lang->doclib->create['execution'] = 'Create ' . $lang->executionCommon . ' Libr
$lang->doclib->create['custom'] = 'Create Custom Library';
$lang->doclib->main['product'] = 'Primary Library';
+$lang->doclib->main['project'] = 'Primary Library';
$lang->doclib->main['execution'] = 'Primary Library';
$lang->doclib->tabList['product'] = $lang->productCommon;
diff --git a/module/doc/lang/zh-cn.php b/module/doc/lang/zh-cn.php
index bfc7ace429..4214833e83 100644
--- a/module/doc/lang/zh-cn.php
+++ b/module/doc/lang/zh-cn.php
@@ -13,6 +13,7 @@
$lang->doc->common = '文档';
$lang->doc->id = '文档编号';
$lang->doc->product = '所属' . $lang->productCommon;
+$lang->doc->project = '所属项目';
$lang->doc->execution = '所属' . $lang->executionCommon;
$lang->doc->lib = '所属文档库';
$lang->doc->module = '所属分类';
@@ -48,6 +49,7 @@ $lang->doc->item = '项';
$lang->doc->num = '文档数量';
$lang->doc->searchResult = '搜索结果';
$lang->doc->mailto = '抄送给';
+$lang->doc->noModule = '文档库下没有目录和文档,请维护目录或者创建文档';
$lang->doc->moduleDoc = '按模块浏览';
$lang->doc->searchDoc = '搜索';
@@ -73,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 = '取消收藏';
@@ -92,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 = '从菜单栏移除';
@@ -103,6 +105,7 @@ $lang->doc->allProduct = '所有' . $lang->productCommon;
$lang->doc->allExecutions = '所有' . $lang->executionCommon;
$lang->doc->libTypeList['product'] = $lang->productCommon . '文档库';
+$lang->doc->libTypeList['project'] = '项目文档库';
$lang->doc->libTypeList['execution'] = $lang->executionCommon . '文档库';
$lang->doc->libTypeList['custom'] = '自定义文档库';
diff --git a/module/doc/model.php b/module/doc/model.php
index fd5b8a535b..9be74f367b 100644
--- a/module/doc/model.php
+++ b/module/doc/model.php
@@ -1117,6 +1117,7 @@ class docModel extends model
public function getLibsByObject($type, $objectID, $mode = '')
{
if($type != 'product' and $type != 'project' and $type != 'execution') return false;
+
$objectLibs = $this->dao->select('*')->from(TABLE_DOCLIB)->where('deleted')->eq(0)->andWhere($type)->eq($objectID)->orderBy('`order`, id')->fetchAll('id');
if($type == 'product')
@@ -1139,16 +1140,88 @@ class docModel extends model
$itemCounts = $this->statLibCounts(array_keys($libs));
foreach($libs as $libID => $lib) $libs[$libID]->allCount = $itemCounts[$libID];
+ /*
if(common::hasPriv('doc', 'showFiles'))
{
$libs['files'] = new stdclass();
$libs['files']->name = $this->lang->doclib->files;
$libs['files']->allCount = count($this->getLibFiles($type, $objectID, 'id_desc'));
}
+ */
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.
*
@@ -1203,6 +1276,7 @@ class docModel extends model
public function getLibFiles($type, $objectID, $orderBy, $pager = null)
{
if($type != 'execution' and $type != 'project' and $type != 'product') return true;
+
$this->loadModel('file');
$docs = $this->dao->select('*')->from(TABLE_DOC)->where($type)->eq($objectID)->fetchAll('id');
foreach($docs as $id => $doc)
@@ -1289,7 +1363,8 @@ class docModel extends model
$executionIdList = join(',', $executionIdList);
$files = $this->dao->select('*')->from(TABLE_FILE)->alias('t1')
->where('size')->gt('0')
- ->andWhere("(objectType = 'execution' and objectID in ($executionIdList))", true)
+ ->andWhere("(objectType = 'project' and objectID = $objectID)", true)
+ ->orWhere("(objectType = 'execution' and objectID in ($executionIdList))")
->orWhere("(objectType = 'doc' and objectID in ($docIdList))")
->orWhere("(objectType = 'task' and objectID in ($taskIdList))")
->orWhere("(objectType = 'build' and objectID in ($buildIdList))")
@@ -1591,28 +1666,26 @@ class docModel extends model
/**
* Build document module index page create document button.
*
+ * @param string $type
+ * @param int $objectID
+ * @param int $libID
* @access public
* @return string
*/
- public function buildCreateButton4Doc()
+ public function buildCreateButton4Doc($type, $objectID, $libID)
{
- $libs = $this->getLibs('all', strpos($this->config->doc->custom->showLibs, 'unclosed') !== false ? 'unclosedProject' : '');
- $html = "";
- if($libs)
+ $html = "";
+ $html .= "";
+ $html .= "
";
+
return $html;
}
@@ -1767,4 +1840,123 @@ EOF;
}
return $navCSS;
}
+
+ /**
+ * Create the select code of doc.
+ *
+ * @param string $type
+ * @param array $objects
+ * @param int $objectID
+ * @param array $libs
+ * @param int $libID
+ * @access public
+ * @return string
+ */
+ public function select($type, $objects, $objectID, $libs, $libID = 0)
+ {
+ if(empty($objects)) return '';
+
+ $output = '';
+ $dropMenuLink = helper::createLink('repo', 'ajaxGetDropMenu');
+
+ $output = "";
+
+ $dropMenuLink = helper::createLink('repo', 'ajaxGetBranchDropMenu');
+ $output .= "";
+
+ 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]) ? "" : '';
+ $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 = "\n
";
+ $menu .= $tree;
+ }
+
+ $menu .= '';
+ return $menu;
+ }
}
diff --git a/module/doc/view/browse.html.php b/module/doc/view/browse.html.php
index f2ef2957e8..96457575b2 100644
--- a/module/doc/view/browse.html.php
+++ b/module/doc/view/browse.html.php
@@ -20,7 +20,7 @@
app->user->feedback) && !$this->cookie->feedbackView && $this->from == 'doc') ? true : false;?>
-
+
diff --git a/module/doc/view/createlib.html.php b/module/doc/view/createlib.html.php
index b62f0bd177..5ce73f96ae 100644
--- a/module/doc/view/createlib.html.php
+++ b/module/doc/view/createlib.html.php
@@ -29,6 +29,10 @@
doc->product?> |
|
+
+ | doc->project?> |
+ |
+
| doc->execution?> |
|
diff --git a/module/doc/view/index.html.php b/module/doc/view/index.html.php
index 8b1a313b1e..336898342a 100644
--- a/module/doc/view/index.html.php
+++ b/module/doc/view/index.html.php
@@ -13,7 +13,7 @@
doc->appendNavCSS();?>
-
+
diff --git a/module/doc/view/objectlibs.html.php b/module/doc/view/objectlibs.html.php
index 9788f087ea..609c2c1117 100644
--- a/module/doc/view/objectlibs.html.php
+++ b/module/doc/view/objectlibs.html.php
@@ -10,7 +10,6 @@
* @link http://www.zentao.net
*/
?>
-doc->appendNavCSS();?>
openApp == 'execution'):;?>
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):?>
-
-
-
-
-
- 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'");?>
+
-
-
-