Merge branch '15.0.beta3' of https://gitlab.zcorp.cc/easycorp/zentaopms into 15.0.beta3

This commit is contained in:
wangyidong
2021-04-02 14:07:24 +08:00
59 changed files with 505 additions and 375 deletions
+1 -1
View File
@@ -1 +1 @@
15.0.beta1
15.0.rc1
+1 -1
View File
@@ -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');
+3 -1
View File
@@ -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');
+1 -7
View File
@@ -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. */
+2
View File
@@ -6,10 +6,12 @@
<div class="tile-title"><?php echo $lang->block->createdTodos;?></div>
<div class="tile-amount"><?php echo empty($data['createdTodos']) ? 0 : html::a($this->createLink('my', 'todo', 'type=all'), (int)$data['createdTodos']);?></div>
</div>
<?php if($config->URAndSR):?>
<div class="col-xs-4 tile">
<div class="tile-title"><?php echo $lang->block->createdRequirements;?></div>
<div class="tile-amount"><?php echo empty($data['createdRequirements']) ? 0 : (int)$data['createdRequirements'];?></div>
</div>
<?php endif;?>
<div class="col-xs-4 tile">
<div class="tile-title"><?php echo $lang->block->createdStories;?></div>
<div class="tile-amount"><?php echo empty($data['createdStories']) ? 0 : (int)$data['createdStories'];?></div>
@@ -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()
<?php foreach($projects as $project):?>
<div class="tab-pane fade<?php if($project->id == $selected) echo ' active in';?>" id="tab3Content<?php echo $project->id;?>">
<div class="table-row">
<?php if($project->model == 'scrum'):?>
<div class='table-row'>
<div class="col-4 text-center">
<div><h4><?php echo $lang->block->story;?></h4></div>
<div>
<div class="col dataTitle"><?php echo $lang->project->allStories . "";?></div>
<div class="col data"><?php echo $project->allStories;?></div>
<?php if($project->model == 'scrum'):?>
<div class='table-row'>
<div class="col-4 text-center">
<div><h4><?php echo $lang->block->story;?></h4></div>
<div>
<div class="col dataTitle"><?php echo $lang->project->allStories . "";?></div>
<div class="col data"><?php echo $project->allStories;?></div>
</div>
<div>
<div class="col dataTitle"><?php echo $lang->project->doneStories . "";?></div>
<div class="col data"><?php echo $project->doneStories;?></div>
</div>
<div>
<div class="col dataTitle"><?php echo $lang->block->left . "";?></div>
<div class="col data"><?php echo $project->leftStories;?></div>
</div>
</div>
<div>
<div class="col dataTitle"><?php echo $lang->project->doneStories . "";?></div>
<div class="col data"><?php echo $project->doneStories;?></div>
<div class="col-4 text-center">
<div><h4><?php echo $lang->block->investment;?></h4></div>
<div>
<div class="col dataTitle"><?php echo $lang->block->totalPeople . "";?></div>
<div class="col data"><?php echo $project->teamCount;?></div>
</div>
<div>
<div class="col dataTitle"><?php echo $lang->block->estimate . "";?></div>
<div class="col data"><?php echo $project->estimate;?></div>
</div>
<div>
<div class="col dataTitle"><?php echo $lang->block->consumedHours . "";?></div>
<div class="col data"><?php echo $project->consumed;?></div>
</div>
</div>
<div>
<div class="col dataTitle"><?php echo $lang->block->left . "";?></div>
<div class="col data"><?php echo $project->leftStories;?></div>
<div class="col-4 text-center">
<div><h4><?php echo $lang->block->bug;?></h4></div>
<div>
<div class="col dataTitle"><?php echo $lang->block->totalBug . "";?></div>
<div class="col data"><?php echo $project->allBugs;?></div>
</div>
<div>
<div class="col dataTitle"><?php echo $lang->block->doneBugs . "";?></div>
<div class="col data"><?php echo $project->doneBugs;?></div>
</div>
<div>
<div class="col dataTitle"><?php echo $lang->block->leftBugs . "";?></div>
<div class="col data"><?php echo $project->leftBugs;?></div>
</div>
</div>
</div>
<div class="col-4 text-center">
<div><h4><?php echo $lang->block->investment;?></h4></div>
<div>
<div class="col dataTitle"><?php echo $lang->block->totalPeople . "";?></div>
<div class="col data"><?php echo $project->teamCount;?></div>
</div>
<div>
<div class="col dataTitle"><?php echo $lang->block->estimate . "";?></div>
<div class="col data"><?php echo $project->estimate;?></div>
</div>
<div>
<div class="col dataTitle"><?php echo $lang->block->consumedHours . "";?></div>
<div class="col data"><?php echo $project->consumed;?></div>
</div>
</div>
<div class="col-4 text-center">
<div><h4><?php echo $lang->block->bug;?></h4></div>
<div>
<div class="col dataTitle"><?php echo $lang->block->totalBug . "";?></div>
<div class="col data"><?php echo $project->allBugs;?></div>
</div>
<div>
<div class="col dataTitle"><?php echo $lang->block->doneBugs . "";?></div>
<div class="col data"><?php echo $project->doneBugs;?></div>
</div>
<div>
<div class="col dataTitle"><?php echo $lang->block->leftBugs . "";?></div>
<div class="col data"><?php echo $project->leftBugs;?></div>
</div>
</div>
</div>
<div class="table-row project-info">
<div class="col-3 text-center"><h4><?php echo $lang->block->last;?></h4></div>
<div class="table-row lastIteration">
<div class='col-3 text-center executionName'><?php echo $project->executions[0]->name;?></div>
<div class='col-8'>
<div class='progress progress-text-left'>
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="<?php echo $project->executions[0]->hours->progress;?>" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $project->executions[0]->hours->progress;?>%">
<span class='progress-text'><?php echo $project->executions[0]->hours->progress . '%';?></span>
<?php if(!empty($project->executions)):?>
<div class="table-row project-info">
<div class="col-2 text-right"><h4><?php echo $lang->block->last;?></h4></div>
<div class="table-row lastIteration">
<div class='col-5 text-center executionName'><?php echo html::a($this->createLink('execution', 'task', "executionID={$project->executions[0]->id}"), $project->executions[0]->name);?></div>
<div class='col-7'>
<div class='progress progress-text-left'>
<div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="<?php echo $project->executions[0]->hours->progress;?>" aria-valuemin="0" aria-valuemax="100" style="width: <?php echo $project->executions[0]->hours->progress;?>%">
<span class='progress-text'><?php echo $project->executions[0]->hours->progress . '%';?></span>
</div>
</div>
</div>
</div>
</div>
</div>
<?php else:?>
<?php endif;?>
<?php else:?>
<div class="col-12">
<div class='table-row text-left weekly-row with-padding'>
<span class='weekly-title'><?php echo $lang->project->weekly;?></span>
@@ -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;}
+1 -1
View File
@@ -96,7 +96,7 @@ if(!$selfCall) die(include('./todolist.html.php'));
?>
<li data-id='<?php echo $todo->id?>'>
<span class="todo-check icon icon-check-circle"></span>
<a href="<?php echo empty($sso) ? $viewLink : $sso . $sign . 'referer=' . base64_encode($viewLink);?>" class='iframe' <?php echo $appid?>>
<a href="<?php echo empty($sso) ? $viewLink : $sso . $sign . 'referer=' . base64_encode($viewLink);?>" class='iframe' data-toggle='modal' <?php echo $appid?>>
<?php if ($todo->date == '2030-01-01') :?>
<span class="todo-time"><?php echo $lang->todo->periods['future'] ?></span>
<?php else:?>
+6 -3
View File
@@ -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")));
}
/**
+18 -8
View File
@@ -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';
+1 -1
View File
@@ -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';
+1 -1
View File
@@ -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'));
+50 -11
View File
@@ -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'), "<i class='icon icon-plus'></i> " . $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"), "<i class='icon icon-plus'></i> " . $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();
}
+2
View File
@@ -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;}
+10
View File
@@ -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);
}
+7 -1
View File
@@ -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;
+8 -5
View File
@@ -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'] = '自定义文档库';
+209 -17
View File
@@ -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 = "<div class='dropdown' id='createDropdown'>";
$html .= "<button class='btn btn-primary' type='button' data-toggle='dropdown'><i class='icon icon-plus'></i>" . $this->lang->doc->create . " <span class='caret'></span></button>";
$html .= "<ul class='dropdown-menu' style='left:0px'>";
foreach($this->lang->doc->typeList as $typeKey => $typeName)
{
$libID = key($libs);
$html .= "<div class='dropdown' id='createDropdown'>";
$html .= "<button class='btn btn-primary' type='button' data-toggle='dropdown'><i class='icon icon-plus'></i>" . $this->lang->doc->create . " <span class='caret'></span></button>";
$html .= "<ul class='dropdown-menu' style='left:0px'>";
foreach($this->lang->doc->typeList as $typeKey => $typeName)
{
$class = strpos($this->config->doc->officeTypes, $typeKey) !== false ? 'iframe' : '';
$html .= "<li>";
$html .= html::a(helper::createLink('doc', 'create', "libID=$libID&moduleID=0&type=$typeKey"), $typeName, '', "class='$class'");
$html .= "</li>";
}
$html .="</ul></div>";
$class = strpos($this->config->doc->officeTypes, $typeKey) !== false ? 'iframe' : '';
$html .= "<li>";
$html .= html::a(helper::createLink('doc', 'create', "type=$type&objectID=$objectID&libID=$libID&moduleID=0&type=$typeKey"), $typeName, '', "class='$class' data-app='{$this->app->openApp}'");
$html .= "</li>";
}
$html .= "</ul></div>";
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 = "<div class='btn-group angle-btn'><div class='btn-group'><button data-toggle='dropdown' type='button' class='btn btn-limit' id='currentItem' title='{$objects[$objectID]}'><span class='text'>{$objects[$objectID]}</span> <span class='caret'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList'>";
$output .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
$output .= "<div class='table-col'><div class='list-group'>";
foreach($objects as $key => $object)
{
$output .= html::a(inlink('objectLibs', "type=$type&objectID=$key"), $object);
}
$output .= "</div></div></div></div></div>";
$dropMenuLink = helper::createLink('repo', 'ajaxGetBranchDropMenu');
$output .= "<div class='btn-group angle-btn'><div class='btn-group'><button id='currentBranch' data-toggle='dropdown' type='button' class='btn btn-limit'>{$libs[$libID]->name} <span class='caret'></span></button><div id='dropMenu' class='dropdown-menu search-list' data-ride='searchList'>";
$output .= '<div class="input-control search-box has-icon-left has-icon-right search-example"><input type="search" class="form-control search-input" /><label class="input-control-icon-left search-icon"><i class="icon icon-search"></i></label><a class="input-control-icon-right search-clear-btn"><i class="icon icon-close icon-sm"></i></a></div>';
$output .= "<div class='table-col'><div class='list-group'>";
foreach($libs as $key => $lib)
{
$output .= html::a(inlink('objectLibs', "type=$type&objectID=$objectID&libID=$key"), $lib->name);
}
$output .= "</div></div></div></div></div>";
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 = "<ul id='modules' class='tree' data-ride='tree' data-name='tree-story'>";
$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 .= "<li>" . 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]) ? "<ul>{$treeMenu[0]}</ul>" : '';
$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] = "<li>" . html::a($link, $branchName, '_self', "id='branch" . (empty($branch) ? "{$id}_0" : $branch) . "'") . "{$childMenu}</li>";
}
$tree .= isset($treeMenu[0]) ? $treeMenu[0] : '';
}
if($productNum > 1) $tree = "<ul>" . $tree . "</ul>\n</li>";
$menu .= $tree;
}
$menu .= '</ul>';
return $menu;
}
}
+1 -1
View File
@@ -20,7 +20,7 @@
<?php $spliter = (empty($this->app->user->feedback) && !$this->cookie->feedbackView && $this->from == 'doc') ? true : false;?>
<div class="main-row fade <?php if($spliter) echo 'split-row';?>" id="mainRow">
<div class="main-col" data-min-width="400">
<div id="mainContent">
<div class="cell<?php if($browseType == 'bysearch') echo ' show';?>" id="queryBox" data-module='doc'></div>
<div class="panel block-files block-sm no-margin">
<?php if(empty($docs) and $browseType == 'bysearch'):?>
+4
View File
@@ -29,6 +29,10 @@
<th><?php echo $lang->doc->product?></th>
<td><?php echo html::select('product', $products, $type == 'product' ? $objectID : '', "class='form-control chosen' data-drop_direction='down'")?></td>
</tr>
<tr class='project hidden'>
<th><?php echo $lang->doc->project?></th>
<td><?php echo html::select('project', $projects, $type == 'project' ? $objectID : '', "class='form-control chosen' data-drop_direction='down'")?></td>
</tr>
<tr class='execution hidden'>
<th><?php echo $lang->doc->execution?></th>
<td><?php echo html::select('execution', $executions, $type == 'execution' ? $objectID : '', "class='form-control chosen' data-drop_direction='down'")?></td>
+1 -1
View File
@@ -13,7 +13,7 @@
<?php $pageCSS .= $this->doc->appendNavCSS();?>
<?php include '../../common/view/header.html.php';?>
<div class='main-row split-row fade' id='mainRow'>
<div class="main-col" data-min-width="400">
<div id="mainContent">
<div class="cell" id="queryBox" data-module='doc'></div>
<div class="row">
<div class="col-sm-7">
-1
View File
@@ -10,7 +10,6 @@
* @link http://www.zentao.net
*/
?>
<?php $pageCSS .= $this->doc->appendNavCSS();?>
<?php include '../../common/view/header.html.php';?>
<?php if($app->openApp == 'execution'):;?>
<style>.panel-body{min-height: 180px}</style>
+14 -185
View File
@@ -15,193 +15,22 @@ if(empty($type)) $type = 'product';
$sideWidth = common::checkNotCN() ? '270' : '238';
?>
<div class="side-col" style="width:<?php echo $sideWidth;?>px" data-min-width="<?php echo $sideWidth;?>">
<div class="cell">
<div class="tabs">
<ul class='nav nav-tabs'>
<?php foreach($lang->doclib->tabList as $tabValue => $tabName):?>
<?php $activeClass = $tabValue == $type ? 'active' : '';?>
<li class='<?php echo $activeClass;?>'><?php echo html::a("#{$tabValue}", $tabName, '', "data-tab");?></li>
<?php endforeach;?>
</ul>
<div class="tab-content">
<?php foreach($lang->doclib->tabList as $tabValue => $tabName):?>
<?php $activeClass = $tabValue == $type ? 'active' : '';?>
<div class="tab-pane <?php echo $activeClass;?>" id="<?php echo "$tabValue";?>">
<ul data-name="docsTree" data-ride="tree" data-initial-state="preserve" class="tree no-margin">
<?php if(isset($sideSubLibs[$tabValue])):?>
<?php if(empty($sideLibs[$tabValue])):?>
<li>
<?php
if($lang->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'");
}
?>
</li>
<?php else:?>
<?php foreach($sideLibs[$tabValue] as $tabMenuID => $tabMenuName):?>
<?php
$customLibCount = 0;
$mainLibID = 0;
if(isset($sideSubLibs[$tabValue][$tabMenuID]))
{
foreach($sideSubLibs[$tabValue][$tabMenuID] as $subLibID => $subLibName)
{
if(is_numeric($subLibID) and !empty($mainLibID)) $customLibCount += 1;
if(is_numeric($subLibID) and empty($mainLibID)) $mainLibID = $subLibID;
}
}
$icon = $tabValue == 'product' ? "<i class='icon icon-product'></i> " : "<i class='icon icon-stack'></i> ";
$activeClass = ($this->methodName == 'objectlibs' && $type == $tabValue && $object->id == $tabMenuID) ? 'active' : '';
$activeClass = ($this->methodName == 'browse' && isset($currentLib->id) && $currentLib->id == $mainLibID) ? 'active' : $activeClass;
?>
<li <?php echo "class='$activeClass'";?>>
<?php if($customLibCount > 0):?>
<?php echo html::a($this->createLink('doc', 'objectLibs', "type=$tabValue&objectID=$tabMenuID"), $icon . $tabMenuName, '', "class='text-ellipsis' title='{$tabMenuName}'");?>
<?php else:?>
<?php echo html::a($this->createLink('doc', 'browse', "libID=$mainLibID"), $icon . $tabMenuName, '', "class='text-ellipsis' title='{$tabMenuName}'");?>
<?php endif;?>
<?php if(isset($sideSubLibs[$tabValue][$tabMenuID])):?>
<ul>
<?php foreach($sideSubLibs[$tabValue][$tabMenuID] as $subLibID => $subLibName):?>
<?php
if($subLibID == 'execution')
{
$subLibLink = inlink('allLibs', "type=execution&product=$tabMenuID");
$activeClass = ($this->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';
}
?>
<?php if($customLibCount > 0):?>
<li <?php echo $activeClass;?>>
<?php echo html::a($subLibLink, "<i class='icon {$icon}'></i> " . $subLibName, '', "class='text-ellipsis' title='{$subLibName}'");?>
<?php endif;?>
<?php if(isset($allModules[$subLibID])):?>
<?php if($customLibCount > 0):?>
<ul>
<?php endif;?>
<?php foreach($allModules[$subLibID] as $module):?>
<?php if($module->parent != 0) continue;?>
<li <?php if($this->methodName == 'browse' && $browseType == 'bymodule' && $moduleID == $module->id) echo "class='active'";?>>
<?php echo html::a($this->createLink('doc', 'browse', "libID=$subLibID&browseType=byModule&param={$module->id}"), "<i class='icon icon-folder-outline'></i> " . $module->name, '', "class='text-ellipsis' title='{$module->name}'");?>
<?php $this->doc->printChildModule($module, $subLibID, $this->methodName, $browseType, $moduleID);?>
</li>
<?php endforeach;?>
<?php if($customLibCount > 0):?>
</ul>
<?php endif;?>
<?php endif;?>
<?php if($customLibCount > 0):?>
</li>
<?php endif;?>
<?php if($customLibCount == 0 and !is_numeric($subLibID)):?>
<li <?php echo $activeClass;?>>
<?php echo html::a($subLibLink, "<i class='icon {$icon}'></i> " . $subLibName, '', "class='text-ellipsis' title='{$subLibName}'");?>
</li>
<?php endif;?>
<?php endforeach;?>
</ul>
<?php endif;?>
</li>
<?php endforeach;?>
<?php endif;?>
<?php else:?>
<?php if(empty($sideLibs[$tabValue])):?>
<li>
<?php
$text = zget($lang->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%'");
?>
</li>
<?php else:?>
<?php foreach($sideLibs[$tabValue] as $sideLibID => $sideLibName):?>
<?php if($tabValue == 'book'):?>
<?php include './bookside.html.php';?>
<?php else:?>
<?php
$activeClass = ($this->methodName == 'objectlibs' && $type == $tabValue && $object->id == $sideLibID) ? 'active' : '';
$activeClass = ($this->methodName == 'browse' && isset($currentLib->id) && $currentLib->id == $sideLibID) ? 'active' : $activeClass;
?>
<li <?php echo "class='$activeClass'";?>>
<?php echo html::a($this->createLink('doc', 'browse', "libID=$sideLibID"), "<i class='icon icon-folder-o'></i> " . $sideLibName, '', "class='text-ellipsis' title='{$sideLibName}'");?>
<?php if(isset($allModules[$sideLibID])):?>
<ul>
<?php foreach($allModules[$sideLibID] as $module):?>
<?php if($module->parent != 0) continue;?>
<li <?php if($this->methodName == 'browse' && $browseType == 'bymodule' && $moduleID == $module->id) echo "class='active'";?>>
<?php echo html::a($this->createLink('doc', 'browse', "libID=$sideLibID&browseType=byModule&param={$module->id}"), "<i class='icon icon-folder-outline'></i> " . $module->name, '', "class='text-ellipsis' title='{$module->name}'");?>
<?php $this->doc->printChildModule($module, $sideLibID, $this->methodName, $browseType, $moduleID);?>
</li>
<?php endforeach;?>
</ul>
<?php endif;?>
</li>
<?php endif;?>
<?php endforeach;?>
<?php endif;?>
<?php endif;?>
</ul>
</div>
<?php endforeach;?>
<div class="cell">
<?php if(!$moduleTree):?>
<hr class="space">
<div class="text-center text-muted">
<?php echo $lang->doc->noModule;?>
</div>
<hr class="space">
<?php endif;?>
<?php echo $moduleTree;?>
<div class="text-center action">
<?php common::printLink('tree', 'browse', "rootID=0&view=story", $lang->doc->manageType, '', "class='btn btn-info btn-wide'");?>
<?php common::printLink('tree', 'browse', "rootID=0&view=story", $lang->doc->editLib, '', "class='btn btn-info btn-wide'");?>
<?php common::printLink('tree', 'browse', "rootID=0&view=story", $lang->doc->deleteLib, '', "class='btn btn-info btn-wide'");?>
<hr class="space-sm" />
</div>
</div>
<div class='side-footer clearfix'>
<span id='customShowLibsBox'>
<?php echo html::a('###', "<i class='icon-cog'></i> {$lang->doc->customShowLibs}", '', "class='setting text-secondary small' data-target='#settingModal' data-toggle='modal'");?>
</span>
<span id='orderBox'>
<?php
if(common::hasPriv('doc', 'sort'))
{
echo html::a('###', "<i class='icon-sort'></i> {$lang->doc->orderLib}", '', "id='orderLib' class='text-secondary small " . (($type != 'product' and $type !='execution') ? '' : 'hidden') . "' style='padding-left:5px;'");
echo html::a('javascript:saveOrder()', "<i class='icon-checked'></i> {$lang->save}", '', "id='saveOrder' class='text-secondary small hidden' style='padding-left:10px;'");
}
?>
</span>
</div>
</div>
<div class='modal fade' id='settingModal' aria-hidden="true">
<div class='modal-dialog mw-400px'>
<div class='modal-content'>
<div class='modal-header'>
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only"><?php echo $lang->close;?></span></button>
<strong><?php echo $lang->doc->customShowLibs;?></strong>
</div>
<div class='modal-body'>
<form action='<?php echo $this->createLink('custom', 'ajaxSetDoc');?>' target='hiddenwin' method='post'>
<table class='table table-form'>
<tr>
<td><?php echo html::checkbox('showLibs', $lang->doc->customShowLibsList, $config->doc->custom->showLibs);?></td>
</tr>
<tr>
<td><?php echo html::submitButton();?></td>
</tr>
</table>
</form>
</div>
</div>
</div>
</div>
<script>
$(function()
{
+1 -1
View File
@@ -16,7 +16,7 @@ $app->loadLang('task');
$config->execution->task = new stdclass();
$config->execution->create = new stdclass();
$config->execution->edit = new stdclass();
$config->execution->create->requiredFields = 'project,name,code,begin,end';
$config->execution->create->requiredFields = 'name,code,begin,end';
$config->execution->edit->requiredFields = 'name,code,begin,end';
$config->execution->customBatchEditFields = 'days,type,teamname,status,desc,PO,QD,PM,RD';
+6 -5
View File
@@ -727,7 +727,7 @@ class execution extends control
/* Append id for secend sort. */
$sort = $this->loadModel('common')->appendOrder($orderBy);
$queryID = ($type == 'bysearch') ? (int)$param : 0;
$queryID = ($type == 'bysearch') ? (int)$param : 0;
$execution = $this->commonAction($executionID);
$executionID = $execution->id;
@@ -768,7 +768,7 @@ class execution extends control
$storyBugs = $this->loadModel('bug')->getStoryBugCounts($storyIdList, $executionID);
$storyCases = $this->loadModel('testcase')->getStoryCaseCounts($storyIdList);
$plans = $this->execution->getPlans($products);
$plans = $this->execution->getPlans($products);
$allPlans = array('' => '');
if(!empty($plans))
{
@@ -802,6 +802,7 @@ class execution extends control
$this->view->type = $this->session->executionStoryBrowseType;
$this->view->param = $param;
$this->view->moduleTree = $this->loadModel('tree')->getProjectStoryTreeMenu($executionID, $startModuleID = 0, array('treeModel', 'createStoryLink'));
$this->view->modulePairs = $this->tree->getModulePairs($productID, 'story', true);
$this->view->tabID = 'story';
$this->view->storyTasks = $storyTasks;
$this->view->storyBugs = $storyBugs;
@@ -1203,7 +1204,7 @@ class execution extends control
}
elseif($this->app->openApp == 'execution')
{
$executionID = key($this->executions);
if($this->config->systemMode == 'new') $executionID = key($this->executions);
$this->execution->setMenu($executionID);
}
@@ -1297,7 +1298,7 @@ class execution extends control
}
}
$this->view->title = $this->lang->execution->create;
$this->view->title = (($this->app->openApp == 'execution') and ($this->config->systemMode == 'new')) ? $this->lang->execution->createExec : $this->lang->execution->create;
$this->view->position[] = $this->view->title;
$this->view->executions = array('' => '') + $this->execution->getList();
$this->view->groups = $this->loadModel('group')->getPairs();
@@ -1923,7 +1924,7 @@ class execution extends control
unset($this->lang->story->stageList['']);
unset($this->lang->story->stageList['wait']);
unset($this->lang->story->stageList['planned']);
unset($this->lang->story->stageList['executioned']);
unset($this->lang->story->stageList['projected']);
unset($this->lang->story->stageList['released']);
unset($this->lang->task->statusList['']);
unset($this->lang->task->statusList['wait']);
+15 -10
View File
@@ -280,15 +280,20 @@ class executionModel extends model
{
$this->lang->execution->team = $this->lang->execution->teamname;
if(empty($_POST['project']))
if($this->config->systemMode == 'new')
{
dao::$errors['message'][] = $this->lang->execution->projectNotEmpty;
return false;
}
if(empty($_POST['project']))
{
dao::$errors['message'][] = $this->lang->execution->projectNotEmpty;
return false;
}
/* Determine whether to add a sprint or a stage according to the model of the execution. */
$project = $this->getByID($_POST['project']);
$sprintType = $this->config->systemMode == 'new' ? zget($this->config->execution->modelList, $project->model, '') : 'sprint';
/* Determine whether to add a sprint or a stage according to the model of the execution. */
$project = $this->getByID($_POST['project']);
$sprintType = zget($this->config->execution->modelList, $project->model, 'sprint');
$this->config->execution->create->requiredFields .= ',project';
}
/* If the execution model is a stage, determine whether the product is linked. */
if($sprintType == 'stage' and empty($this->post->products[0]))
@@ -346,7 +351,7 @@ class executionModel extends model
$this->file->updateObjectID($this->post->uid, $executionID, 'execution');
/* Update the path. */
$this->setTreePath($executionID);
if($this->config->systemMode == 'new') $this->setTreePath($executionID);
/* Copy team of execution. */
if($copyExecutionID != '')
@@ -378,7 +383,7 @@ class executionModel extends model
$member->hours = $this->config->execution->defaultWorkhours;
$this->dao->insert(TABLE_TEAM)->data($member)->exec();
$this->addProjectMembers($sprint->project, array($member));
if($this->config->systemMode == 'new') $this->addProjectMembers($sprint->project, array($member));
}
/* Create doc lib. */
@@ -2435,7 +2440,7 @@ class executionModel extends model
->where('t1.project')->in(array_keys($executions))
->andWhere('t2.deleted')->eq(0)
->andWhere('t2.status')->ne('closed')
->andWhere('t2.stage')->in('wait,planned,executioned,developing')
->andWhere('t2.stage')->in('wait,planned,projected,developing')
->groupBy('project')
->fetchAll('project');
+2 -2
View File
@@ -42,7 +42,7 @@
</div>
<div class='btn-toolbar pull-right'>
<?php common::printLink('execution', 'export', "status=$status&productID=$productID&orderBy=$orderBy&from=$from", "<i class='icon-export muted'> </i>" . $lang->export, '', "class='btn btn-link export'")?>
<?php if(common::hasPriv('execution', 'create')) echo html::a($this->createLink('execution', 'create', "projectID=$projectID"), "<i class='icon icon-sm icon-plus'></i> " . ($from == 'execution' ? $lang->execution->createExec : $lang->execution->create), '', "class='btn btn-primary' data-app='$from'");?>
<?php if(common::hasPriv('execution', 'create')) echo html::a($this->createLink('execution', 'create', "projectID=$projectID"), "<i class='icon icon-sm icon-plus'></i> " . ((($from == 'execution') and ($config->systemMode == 'new')) ? $lang->execution->createExec : $lang->execution->create), '', "class='btn btn-primary' data-app='$from'");?>
</div>
</div>
<div id='mainContent' class="main-row fade">
@@ -66,7 +66,7 @@
<?php endif;?>
<?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?>
</th>
<th><?php common::printOrderLink('name', $orderBy, $vars, $from == 'execution' ? $lang->execution->execName : $lang->execution->name);?></th>
<th><?php common::printOrderLink('name', $orderBy, $vars, (($from == 'execution') and ($config->systemMode == 'new')) ? $lang->execution->execName : $lang->execution->name);?></th>
<th class='thWidth'><?php common::printOrderLink('PM', $orderBy, $vars, $lang->execution->owner);?></th>
<th class='w-100px'><?php common::printOrderLink('end', $orderBy, $vars, $lang->execution->end);?></th>
<th class='w-100px'><?php common::printOrderLink('status', $orderBy, $vars, $from == 'execution' ? $lang->execution->execStatus : $lang->execution->status);?></th>
+8 -6
View File
@@ -38,25 +38,27 @@
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $from == 'execution' ? $lang->execution->createExec : $lang->execution->create;?></h2>
<h2><?php echo (($from == 'execution') and ($config->systemMode == 'new')) ? $lang->execution->createExec : $lang->execution->create;?></h2>
<div class="pull-right btn-toolbar">
<button type='button' class='btn btn-link' data-toggle='modal' data-target='#copyProjectModal'><?php echo html::icon($lang->icons['copy'], 'muted') . ' ' . ($from == 'execution' ? $lang->execution->copyExec : $lang->execution->copy);?></button>
<button type='button' class='btn btn-link' data-toggle='modal' data-target='#copyProjectModal'><?php echo html::icon($lang->icons['copy'], 'muted') . ' ' . ((($from == 'execution') and ($config->systemMode == 'new')) ? $lang->execution->copyExec : $lang->execution->copy);?></button>
</div>
</div>
<form class='form-indicator main-form form-ajax' method='post' target='hiddenwin' id='dataform'>
<table class='table table-form'>
<?php if($config->systemMode == 'new'):?>
<tr>
<th class='w-120px'><?php echo $lang->execution->project;?></th>
<td class="col-main"><?php echo html::select("project", $allProjects, $projectID, "class='form-control chosen' required onchange='refreshPage(this.value)'");?></td>
<td></td><td></td>
</tr>
<?php endif;?>
<tr>
<th class='w-120px'><?php echo $from == 'execution' ? $lang->execution->execName : $lang->execution->name;?></th>
<th class='w-120px'><?php echo (($from == 'execution') and ($config->systemMode == 'new')) ? $lang->execution->execName : $lang->execution->name;?></th>
<td class="col-main"><?php echo html::input('name', $name, "class='form-control' required");?></td>
<td></td><td></td>
</tr>
<tr>
<th><?php echo $from == 'execution' ? $lang->execution->execCode : $lang->execution->code;?></th>
<th><?php echo (($from == 'execution') and ($config->systemMode == 'new')) ? $lang->execution->execCode : $lang->execution->code;?></th>
<td><?php echo html::input('code', $code, "class='form-control' required");?></td><td></td><td></td>
</tr>
<tr>
@@ -84,7 +86,7 @@
<td><?php echo html::input('team', $team, "class='form-control'");?></td><td></td><td></td>
</tr>
<tr>
<th><?php echo $from == 'execution' ? $lang->execution->execType : $lang->execution->type;?></th>
<th><?php echo (($from == 'execution') and ($config->systemMode == 'new')) ? $lang->execution->execType : $lang->execution->type;?></th>
<td><?php echo html::select('lifetime', $lang->execution->lifeTimeList, '', "class='form-control' onchange='showLifeTimeTips()'"); ?></td>
<td class='muted' colspan='2'><div id='lifeTimeTips'><?php echo $lang->execution->typeDesc;?></div></td>
</tr>
@@ -142,7 +144,7 @@
</td>
</tr>
<tr>
<th><?php echo $from == 'execution' ? $lang->execution->execDesc : $lang->execution->desc;?></th>
<th><?php echo (($from == 'execution') and ($config->systemMode == 'new')) ? $lang->execution->execDesc : $lang->execution->desc;?></th>
<td colspan='3'>
<?php echo $this->fetch('user', 'ajaxPrintTemplates', 'type=execution&link=desc');?>
<?php echo html::textarea('desc', '', "rows='6' class='form-control kindeditor' hidefocus='true'");?>
+7 -3
View File
@@ -174,6 +174,7 @@
<td class='c-pri'><span class='label-pri <?php echo 'label-pri-' . $story->pri?>' title='<?php echo zget($lang->story->priList, $story->pri, $story->pri);?>'><?php echo zget($lang->story->priList, $story->pri, $story->pri);?></span></td>
<td class='c-name' title="<?php echo $story->title?>">
<?php if(isset($branchGroups[$story->product][$story->branch])) echo "<span class='label label-outline label-badge'>" . $branchGroups[$story->product][$story->branch] . '</span>';?>
<?php if(!empty($story->module)) echo "<span class='label label-gray label-badge'>{$modulePairs[$story->module]}</span> ";?>
<?php if($story->parent > 0) echo "<span class='label'>{$lang->story->childrenAB}</span>";?>
<?php echo html::a($storyLink,$story->title, null, "style='color: $story->color' data-app='execution'");?>
</td>
@@ -213,7 +214,7 @@
if(commonModel::isTutorialMode())
{
$wizardParams = helper::safe64Encode($param);
echo html::a($this->createLink('tutorial', 'wizard', "module=task&method=create&params=$wizardParams"), "<i class='icon-plus'></i>",'', "class='btn btn-task-create' title='{$lang->execution->wbs}'");
echo html::a($this->createLink('tutorial', 'wizard', "module=task&method=create&params=$wizardParams"), "<i class='icon-plus'></i>",'', "class='btn btn-task-create' title='{$lang->execution->wbs}' data-app='execution'");
}
else
{
@@ -224,7 +225,10 @@
if($hasDBPriv) common::printIcon('task', 'batchCreate', "executionID={$execution->id}&story={$story->id}", '', 'list', 'pluses');
$lang->testcase->batchCreate = $lang->testcase->create;
if($productID && $hasDBPriv) common::printIcon('testcase', 'batchCreate', "productID=$story->product&branch=$story->branch&moduleID=$story->module&storyID=$story->id", '', 'list', 'sitemap');
if($productID and $hasDBPriv and common::hasPriv('testcase', 'create'))
{
echo html::a($this->createLink('testcase', 'create', "productID=$story->product&branch=$story->branch&moduleID=$story->module&form=&param=0&storyID=$story->id"), '<i class="icon-testcase-create icon-sitemap"></i>', '', "title='{$lang->testcase->create}' data-app='qa'");
}
if($canBeChanged and common::hasPriv('execution', 'unlinkStory', $execution))
{
@@ -272,7 +276,7 @@
foreach($lang->story->stageList as $key => $stage)
{
if(empty($key)) continue;
if(strpos('wait|planned|executioned', $key) !== false) continue;
if(strpos('wait|planned|projected', $key) !== false) continue;
$actionLink = $this->createLink('story', 'batchChangeStage', "stage=$key");
echo "<li>" . html::a('#', $stage, '', "onclick=\"setFormAction('$actionLink', 'hiddenwin')\"") . "</li>";
}
+1 -1
View File
@@ -41,7 +41,7 @@
</div>
</div>
<?php
$cols = array('executioned', 'developing', 'developed', 'testing', 'tested', 'verified', 'released');
$cols = array('projected', 'developing', 'developed', 'testing', 'tested', 'verified', 'released');
$account = $this->app->user->account;
?>
<div id="kanban" class="main-table" data-ride="table" data-checkable="false" data-group="true">
+4 -3
View File
@@ -218,6 +218,7 @@ if($config->systemMode == 'new')
$lang->resource->project->bug = 'bug';
$lang->resource->project->testcase = 'testcase';
$lang->resource->project->testtask = 'testtask';
$lang->resource->project->testreport = 'testreport';
$lang->resource->project->execution = 'execution';
$lang->resource->project->export = 'export';
$lang->resource->project->createGuide = 'createGuide';
@@ -254,8 +255,8 @@ if($config->systemMode == 'new')
$lang->project->methodOrder[145] = 'bug';
$lang->project->methodOrder[150] = 'testcase';
$lang->project->methodOrder[155] = 'testtask';
$lang->project->methodOrder[160] = 'execution';
$lang->project->methodOrder[165] = 'testreport';
$lang->project->methodOrder[160] = 'testreport';
$lang->project->methodOrder[165] = 'execution';
$lang->project->methodOrder[170] = 'export';
$lang->project->methodOrder[175] = 'createGuide';
@@ -1012,7 +1013,7 @@ $lang->resource->doc = new stdclass();
$lang->resource->doc->index = 'index';
$lang->resource->doc->browse = 'browse';
$lang->resource->doc->createlib = 'createlib';
$lang->resource->doc->editlib = 'editlib';
$lang->resource->doc->editlib = 'editLib';
$lang->resource->doc->deleteLib = 'deleteLib';
$lang->resource->doc->create = 'create';
$lang->resource->doc->view = 'view';
+1 -1
View File
@@ -19,7 +19,7 @@
<table align='center' class='table table-form'>
<tr>
<th class='w-100px'><?php echo $lang->group->name;?></th>
<td><?php echo html::input('name', $group->name, "class='form-control'");?></td>
<td class='required'><?php echo html::input('name', $group->name, "class='form-control'");?></td>
</tr>
<tr>
<th><?php echo $lang->group->desc;?></th>
+5
View File
@@ -11,6 +11,11 @@
*/
?>
<?php include '../../common/view/header.html.php'; ?>
<div id="mainMenu" class="clearfix">
<div class="btn-toolbar pull-right">
<?php if(common::hasPriv('jenkins', 'create')) common::printLink('jenkins', 'create', "", "<i class='icon icon-plus'></i> " . $lang->jenkins->create, '', "class='btn btn-primary'");?>
</div>
</div>
<div id='mainContent' class='main-row'>
<form class='main-table' id='ajaxForm' method='post'>
<table id='jenkinsList' class='table has-sort-head table-fixed'>
+1
View File
@@ -3,4 +3,5 @@
.data-basic.table-data tbody > tr > th {width: 100px;}
.col-12 .cell table td {word-wrap: break-word; word-break: normal;}
td.normal {color: #00da88;}
td.acl {white-space: nowrap;}
.row > .col-sm-12:first-child {padding-bottom: 20px;}
+1 -1
View File
@@ -1286,7 +1286,7 @@ class productModel extends model
$products = $this->dao->select('t1.id as id, t1.*')->from(TABLE_PRODUCT)->alias('t1')
->leftJoin(TABLE_PROGRAM)->alias('t2')->on('t1.program = t2.id')
->where('t1.id')->in($productKeys)
->orderBy('t2.order_asc, t1.line_desc, t1.order_asc')
->orderBy('t2.order_asc, t1.line_desc, t1.order_desc')
->page($pager)
->fetchAll('id');
}
+5 -1
View File
@@ -47,6 +47,7 @@
<td><strong><?php echo zget($users, $product->PO);?></strong></td>
<th><i class="icon icon-person icon-sm"></i> <?php echo $lang->product->release;?></th>
<td><strong><?php echo zget($users, $product->RD);?></strong></td>
<td></td>
</tr>
<tr>
<th><i class="icon icon-person icon-sm"></i> <?php echo $lang->product->qa;?></th>
@@ -66,18 +67,21 @@
<td><strong><?php echo $product->code;?></strong></td>
<th class="w-80px"><?php echo $lang->story->openedBy?></th>
<td><strong><?php echo zget($users, $product->createdBy);?></strong></td>
<td></td>
</tr>
<tr>
<th class="w-80px"><?php echo $lang->product->type;?></th>
<td><strong><?php echo zget($lang->product->typeList, $product->type);?></strong></td>
<th><?php echo $lang->story->openedDate?></th>
<td><strong><?php echo formatTime($product->createdDate, DT_DATE1);?></strong></td>
<td></td>
</tr>
<tr>
<th class="w-80px"><?php echo $lang->productCommon . $lang->product->status;?></th>
<td class="<?php echo $product->status;?>"><strong><?php echo zget($lang->product->statusList, $product->status);?></strong></td>
<th><?php echo $lang->product->acl;?></th>
<td><strong><?php echo $lang->product->aclList[$product->acl];?></strong></td>
<td class='acl'><strong><?php echo $lang->product->aclList[$product->acl];?></strong></td>
<td></td>
</tr>
<?php if($product->acl == 'custom'):?>
<tr>
+11 -2
View File
@@ -852,6 +852,16 @@ class projectModel extends model
$this->dao->replace(TABLE_USERGROUP)->data($groupPriv)->exec();
}
/* Create doc lib. */
$this->app->loadLang('doc');
$lib = new stdclass();
$lib->project = $projectID;
$lib->name = $this->lang->doclib->main['project'];
$lib->type = 'project';
$lib->main = '1';
$lib->acl = 'default';
$this->dao->insert(TABLE_DOCLIB)->data($lib)->exec();
return $projectID;
}
}
@@ -905,7 +915,7 @@ class projectModel extends model
if($project->budget != 0 and $program->budget != 0)
{
$availableBudget = $this->loadModel('program')->getBudgetLeft($program);
if($project->budget > $availableBudget + $oldProject->budget) dao::$errors['budget'] = $this->lang->project->beyondParentBudget;
if($project->budget > $availableBudget + $oldProject->budget) dao::$errors['budget'] = $this->lang->program->beyondParentBudget;
}
}
@@ -1686,7 +1696,6 @@ class projectModel extends model
if($project->model == 'waterfall')
{
$this->loadModel('execution');
$lang->scrum->menu->execution['link'] = str_replace($lang->executionCommon, $lang->project->stage, $lang->scrum->menu->execution['link']);
$lang->execution->create = str_replace($lang->executionCommon, $lang->project->stage, $lang->execution->create);
$lang->execution->name = str_replace($lang->executionCommon, $lang->project->stage, $lang->execution->name);
$lang->execution->status = str_replace($lang->executionCommon, $lang->project->stage, $lang->execution->status);
+1 -1
View File
@@ -12,7 +12,7 @@ function switchRepo(repoID, module, method)
if(typeof(eventKeyCode) == 'undefined') eventKeyCode = 0;
if(eventKeyCode > 0 && eventKeyCode != 13) return false;
/* The projec id is a string, use it as the project model. */
/* The project id is a string, use it as the project model. */
if(isNaN(repoID))
{
$.cookie('projectMode', repoID, {expires:config.cookieLife, path:config.webRoot});
+1 -1
View File
@@ -117,7 +117,7 @@ $config->story->datatable->fieldList['openedDate']['required'] = 'no';
$config->story->datatable->fieldList['assignedTo']['title'] = 'assignedToAB';
$config->story->datatable->fieldList['assignedTo']['fixed'] = 'no';
$config->story->datatable->fieldList['assignedTo']['width'] = '85';
$config->story->datatable->fieldList['assignedTo']['width'] = '86';
$config->story->datatable->fieldList['assignedTo']['required'] = 'no';
$config->story->datatable->fieldList['assignedDate']['title'] = 'assignedDate';
+1 -1
View File
@@ -1776,7 +1776,7 @@ class story extends control
public function report($productID, $branchID, $storyType = 'story', $browseType = 'unclosed', $moduleID = 0, $chartType = 'pie')
{
$this->loadModel('report');
$this->view->charts = array();
$this->view->charts = array();
if(!empty($_POST))
{
+2 -1
View File
@@ -3,8 +3,9 @@ $(function()
if(typeof(resetActive) != 'undefined') return false;
if(typeof(storyType) == 'undefined') storyType = '';
if(typeof(rawModule) == 'undefined') rawModule = 'product';
if(typeof(app) == 'undefined') app = '';
if(typeof(execution) != 'undefined') rawModule = 'projectstory';
if(['project', 'projectstory'].indexOf(rawModule) === -1 && app != 'qa')
if(['project', 'projectstory'].indexOf(rawModule) === -1)
{
$('#navbar .nav li').removeClass('active');
$("#navbar .nav li[data-id=" + storyType + ']').addClass('active');
+1 -1
View File
@@ -1788,7 +1788,7 @@ class storyModel extends model
->andWhere('deleted')->eq(0)
->fetchGroup('type');
/* No tasks, then the stage is executioned. */
/* No tasks, then the stage is projected. */
if(!$tasks and $executions)
{
foreach($stages as $branch => $stage)
+2 -1
View File
@@ -13,7 +13,8 @@
<?php include '../../common/view/header.html.php';?>
<div id="mainMenu" class="clearfix">
<div class="btn-toolbar pull-left">
<?php echo html::a($this->createLink('product', 'browse', "productID=$productID&branch=$branchID&browseType=$browseType&moduleID=$moduleID"), "<i class='icon icon-back icon-sm'> </i>" . $lang->goback, '', "class='btn btn-link'");?>
<?php $browseLink = $this->session->storyList ? $this->session->storyList : $this->createLink('product', 'browse', "productID=$productID&branch=$branchID&browseType=$browseType&moduleID=$moduleID&storyType=$storyType")?>
<?php echo html::a($browseLink, "<i class='icon icon-back icon-sm'> </i>" . $lang->goback, '', "class='btn btn-link'");?>
<div class='divider'></div>
<div class='page-title'>
<span class='text'><?php echo $lang->story->report->common;?></span>
@@ -13,6 +13,9 @@
<?php include '../../common/view/header.html.php';?>
<?php include '../../common/view/datepicker.html.php';?>
<?php include '../../common/view/kindeditor.html.php';?>
<style>
.input-group>.chosen-container.required:after {top: 6px;}
</style>
<?php js::import($jsRoot . 'misc/date.js');?>
<div id='mainContent' class='main-content'>
<div class='center-block'>
@@ -92,7 +95,6 @@
<?php echo html::submitButton();?>
<?php echo html::backButton();?>
<?php echo html::hidden('product', $productID);?>
<?php echo html::hidden('status', 'done');?>
</td>
</tr>
</table>
+1 -1
View File
@@ -667,7 +667,7 @@ class todo extends control
$this->session->set('project', $projectID);
$products = $this->loadModel('product')->getProductPairsByProject($projectID);
die(html::select('product', $products, '', "class='form-control chosen'"));
die(html::select('bugProduct', $products, '', "class='form-control chosen'"));
}
/**
+2 -4
View File
@@ -31,7 +31,6 @@ $(function()
{
var onlybody = config.onlybody;
var programID = $('#productProgram').val();
var productID = $('#product').val();
var link = createLink('story', 'create', 'productID=' + productID + '&branch=0&moduleID=0&storyID=0&projectID=0&bugID=0&planID=0&todoID=' + todoID, config.defaultView, 'no', programID);
@@ -41,9 +40,8 @@ $(function()
$('#toBugButton').click(function()
{
var onlybody = config.onlybody;
var projectID = $('#project').val();
var productID = $('#product').val();
var projectID = $('#bugProject').val();
var productID = $('#bugProduct').val();
var link = createLink('bug', 'create', 'productID=' + productID + '&branch=0&extras=todoID=' + todoID, config.defaultView, 'no', projectID);
location.href = link;
+2 -2
View File
@@ -272,11 +272,11 @@
<table align='center' class='table table-form'>
<tr>
<th><?php echo $lang->todo->project;?></th>
<td><?php echo html::select('project', $projects, '', "class='form-control chosen' onchange=getProductByProject(this.value);");?></td>
<td><?php echo html::select('bugProject', $projects, '', "class='form-control chosen' onchange=getProductByProject(this.value);");?></td>
</tr>
<tr>
<th><?php echo $lang->todo->product;?></th>
<td id='productIdBox'><?php echo html::select('product', $projectProducts, '', "class='form-control chosen'");?></td>
<td id='productIdBox'><?php echo html::select('bugProduct', $projectProducts, '', "class='form-control chosen'");?></td>
</tr>
<tr>
<td colspan='2' class='text-center'><?php echo html::commonButton($lang->todo->reasonList['bug'], "id='toBugButton'", 'btn btn-primary');?></td>
+3 -3
View File
@@ -30,12 +30,12 @@ class tree extends control
if($this->app->openApp == 'product')
{
$this->product->setMenu($rootID);;
$this->product->setMenu($rootID, 0, 0, '', $viewType);;
}
else if($this->app->openApp == 'qa')
{
$products = $this->product->getPairs('noclosed');
$this->loadModel('qa')->setMenu($products, $rootID);;
$this->loadModel('qa')->setMenu($products, $rootID, 0, $viewType);;
}
else if($this->app->openApp == 'project')
{
@@ -83,7 +83,7 @@ class tree extends control
/* Set menu.*/
$products = $this->product->getPairs();
$this->product->saveState($rootID, $products);
$this->product->setMenu($rootID);
$this->product->setMenu($rootID, 0, 0, '', $viewType);
unset($products[$rootID]);
$currentProduct = key($products);
+7 -1
View File
@@ -796,7 +796,8 @@ class treeModel extends model
*/
public function getProjectStoryTreeMenu($rootID, $startModule = 0, $userFunc)
{
$extra['projectID'] = $rootID;
if($this->app->rawModule == 'projectstory') $extra['projectID'] = $rootID;
if($this->app->rawModule == 'execution') $extra['executionID'] = $rootID;
$menu = "<ul id='modules' class='tree' data-ride='tree' data-name='tree-story'>";
$startModulePath = '';
if($startModule > 0)
@@ -1025,6 +1026,11 @@ class treeModel extends model
$projectID = $extra['projectID'];
return html::a(helper::createLink('projectstory', 'story', "projectID=$projectID&productID=$productID&branch=&browseType=byModule&param={$module->id}"), $module->name, '_self', "id='module{$module->id}'");
}
elseif(isset($extra['executionID']) and !empty($extra['executionID']))
{
$executionID = $extra['executionID'];
return html::a(helper::createLink('execution', 'story', "executionID=$executionID&orderBy=order_desc&type=byModule&param={$module->id}"), $module->name, '_self', "id='module{$module->id}'");
}
else
{
return html::a(helper::createLink('product', 'browse', "root={$module->root}&branch=&type=byModule&param={$module->id}"), $module->name, '_self', "id='module{$module->id}'");
-2
View File
@@ -493,8 +493,6 @@ class upgrade extends control
if(empty($repos))
{
$this->loadModel('setting')->deleteItems('owner=system&module=common&section=global&key=upgradeStep');
if($this->config->version == $this->config->installedVersion) die(js::alert($this->lang->upgrade->successTip) . js::locate($this->createLink('user', 'logout')));
die(js::locate($this->createLink('upgrade', 'afterExec', "fromVersion=&processed=no")));
}
+1 -1
View File
@@ -52,7 +52,7 @@ $lang->upgrade->noticeSQL = 'Your database is inconsistent with the standard
$lang->upgrade->afterDeleted = 'File is not deleted. Please refresh after you delete it.';
$lang->upgrade->mergeProgram = 'Data Merge';
$lang->upgrade->mergeTips = 'Data Migration Tips';
$lang->upgrade->to15Guide = 'ZenTao open source version 15.0.beta1 upgrade';
$lang->upgrade->to15Guide = 'ZenTao open source version 15.0 upgrade';
$lang->upgrade->to15Desc = <<<EOD
<p>Dear users, ZenTao has made adjustments to navigation and concepts since version 15. The main changes are as follows:</p>
<ol>
+1
View File
@@ -132,3 +132,4 @@ $lang->upgrade->fromVersions['12_4_4'] = '12.4.4';
$lang->upgrade->fromVersions['12_5'] = '12.5';
$lang->upgrade->fromVersions['12_5_1'] = '12.5.1';
$lang->upgrade->fromVersions['12_5_2'] = '12.5.2';
$lang->upgrade->fromVersions['12_5_3'] = '12.5.3';
+1 -1
View File
@@ -53,7 +53,7 @@ $lang->upgrade->noticeSQL = '检查到你的数据库跟标准不一致,
$lang->upgrade->afterDeleted = '以上文件未能删除, 删除后刷新!';
$lang->upgrade->mergeProgram = '数据迁移';
$lang->upgrade->mergeTips = '数据迁移提示';
$lang->upgrade->to15Guide = '禅道开源版15.0.beta1升级';
$lang->upgrade->to15Guide = '禅道开源版15版本升级';
$lang->upgrade->to15Desc = <<<EOD
<p>尊敬的用户,禅道从15版本开始对导航和概念做了调整,主要改动如下:</p>
<ol>
+5 -6
View File
@@ -632,17 +632,15 @@ class upgradeModel extends model
case '12_5_2':
$this->saveLogs('Execute 12_5_2');
$this->appendExec('12_5_2');
case '12_5_3':
$this->saveLogs('Execute 12_5_3');
$this->appendExec('12_5_3');
case '15_0':
$this->saveLogs('Execute 15_0');
$this->execSQL($this->getUpgradeFile('15.0'));
$this->adjustWhitelistOfProject();
$this->adjustWhitelistOfProduct();
$this->appendExec('15_0');
case '15_0_beta1':
$this->saveLogs('Execute 15_0_beta1');
$this->adjustBugOfProject();
$this->adjustPriv15_0();
$this->appendExec('15_0_beta1');
}
$this->deletePatch();
@@ -826,6 +824,7 @@ class upgradeModel extends model
case '12_5':
case '12_5_1':
case '12_5_2':
case '12_5_3':
case '15_0' : $confirmContent .= file_get_contents($this->getUpgradeFile('15.0'));
}
return str_replace('zt_', $this->config->db->prefix, $confirmContent);
@@ -4327,7 +4326,7 @@ class upgradeModel extends model
$data->path = ",{$projectID},{$sprint->id},";
$data->type = 'sprint';
$data->acl = $sprint->acl == 'custom' ? 'private' : $sprint->acl;
$data->lifetime = $sprint->type;
$data->lifetime = empty($sprint->lifetime) ? $sprint->type : $sprint->lifetime;
$this->dao->update(TABLE_PROJECT)->data($data)->where('id')->eq($sprint->id)->exec();
}
+1 -1
View File
@@ -89,7 +89,7 @@
</tr>
<tr class='programParams'>
<th><?php echo $lang->project->acl;?></th>
<td><?php echo nl2br(html::radio('acl', $lang->project->aclList, 'open', '', 'block'));?></td>
<td><?php echo nl2br(html::radio('acl', $lang->program->subAclList, 'open', '', 'block'));?></td>
</tr>
</table>
<div class='table-foot text-center'><?php echo html::submitButton();?></div>
+1 -1
View File
@@ -2291,7 +2291,7 @@ class userModel extends model
}
/* Judge sprint auth. */
if(($project->type == 'sprint' || $project->type == 'stage') && $project->acl == 'private')
if(($project->type == 'sprint' || $project->type == 'stage') && $project->acl == 'private' && $this->config->systemMode == 'new')
{
$parent = $this->dao->select('openedBy,PM')->from(TABLE_PROJECT)->where('id')->eq($project->project)->fetch();
$users[$parent->openedBy] = $parent->openedBy;
+1
View File
@@ -49,6 +49,7 @@ $imgCutter.imgCutter(
done: function(response)
{
window.parent.$('#main-avatar, #menu-avatar').html('<img src="<?php echo $user->avatar?>"/>');
window.parent.$('#mainContent .avatar').html('<img src="<?php echo $user->avatar?>"/>');
if(window.parent.$('#main-avatar, #menu-avatar').hasClass('with-text')) window.parent.$('#main-avatar, #menu-avatar').toggleClass('with-text').css('background', 'none');
location.href = createLink('my', 'profile');
},
@@ -14,9 +14,6 @@ $position[] = html::a($this->createLink('admin', 'xuanxuan'), $this->lang->im->c
$position[] = $this->lang->client->browse;
?>
<?php include '../../../common/view/header.html.php';?>
<div id="mainMenu" class="clearfix">
<div class="btn-toolbar pull-left"><?php common::printAdminSubMenu('xuanxuan');?></div>
</div>
<div id='mainContent' class='main-content'>
<div class='main-header'>
<div class='pull-right'>
@@ -12,9 +12,6 @@
?>
<?php include '../../../common/view/header.html.php';?>
<?php $this->app->loadLang('client')?>
<div id="mainMenu" class="clearfix">
<div class="btn-toolbar pull-left"><?php common::printAdminSubMenu('xuanxuan');?></div>
</div>
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>