Merge branch 'master' into 'sprint/189_mayue_task#53652'

# Conflicts:
#   module/project/model.php
This commit is contained in:
孙广明
2022-05-12 05:01:42 +00:00
74 changed files with 1715 additions and 631 deletions
+37
View File
@@ -132,6 +132,43 @@ $config->project->maxCheckList = new stdclass();
$config->project->maxCheckList->scrum = array('bug', 'execution', 'build', 'doc', 'release', 'testtask', 'case', 'issue', 'risk', 'meeting');
$config->project->maxCheckList->waterfall = array('execution', 'design', 'doc', 'bug', 'case', 'build', 'release', 'testtask', 'review', 'build', 'researchplan', 'issue', 'risk', 'opportunity', 'auditplan', 'gapanalysis', 'meeting');
$config->project->search['module'] = 'project';
$config->project->search['fields']['name'] = $lang->project->name;
$config->project->search['fields']['code'] = $lang->project->code;
$config->project->search['fields']['id'] = $lang->project->id;
$config->project->search['fields']['model'] = $lang->project->model;
$config->project->search['fields']['parent'] = $lang->project->parent;
$config->project->search['fields']['status'] = $lang->project->status;
$config->project->search['fields']['desc'] = $lang->project->desc;
$config->project->search['fields']['PM'] = $lang->project->PM;
$config->project->search['fields']['openedDate'] = $lang->project->openedDate;
$config->project->search['fields']['begin'] = $lang->project->begin;
$config->project->search['fields']['end'] = $lang->project->end;
$config->project->search['fields']['realBegan'] = $lang->project->realBeganAB;
$config->project->search['fields']['realEnd'] = $lang->project->realEndAB;
$config->project->search['fields']['openedBy'] = $lang->project->openedBy;
$config->project->search['fields']['closedBy'] = $lang->project->closedBy;
$config->project->search['fields']['lastEditedDate'] = $lang->project->lastEditedDate;
$config->project->search['fields']['closedDate'] = $lang->project->closedDate;
$config->project->search['params']['name'] = array('operator' => 'include', 'control' => 'input' , 'values' => '');
$config->project->search['params']['code'] = array('operator' => '=' , 'control' => 'input' , 'values' => '');
$config->project->search['params']['id'] = array('operator' => '=' , 'control' => 'input' , 'values' => '');
$config->project->search['params']['model'] = array('operator' => '=' , 'control' => 'select', 'values' => $lang->project->modelList);
$config->project->search['params']['parent'] = array('operator' => '=' , 'control' => 'select', 'values' => '');
$config->project->search['params']['status'] = array('operator' => '=' , 'control' => 'select', 'values' => $lang->project->statusList);
$config->project->search['params']['desc'] = array('operator' => 'include', 'control' => 'input' , 'values' => '');
$config->project->search['params']['PM'] = array('operator' => '=' , 'control' => 'select', 'values' => 'users');
$config->project->search['params']['openedDate'] = array('operator' => '=' , 'control' => 'input' , 'values' => '', 'class' => 'date');
$config->project->search['params']['begin'] = array('operator' => '=' , 'control' => 'input' , 'values' => '', 'class' => 'date');
$config->project->search['params']['end'] = array('operator' => '=' , 'control' => 'input' , 'values' => '', 'class' => 'date');
$config->project->search['params']['realBegan'] = array('operator' => '=' , 'control' => 'input' , 'values' => '', 'class' => 'date');
$config->project->search['params']['realEnd'] = array('operator' => '=' , 'control' => 'input' , 'values' => '', 'class' => 'date');
$config->project->search['params']['openedBy'] = array('operator' => '=' , 'control' => 'select', 'values' => 'users');
$config->project->search['params']['closedBy'] = array('operator' => '=' , 'control' => 'select', 'values' => 'users');
$config->project->search['params']['lastEditedDate'] = array('operator' => '=' , 'control' => 'input' , 'values' => '', 'class' => 'date');
$config->project->search['params']['closedDate'] = array('operator' => '=' , 'control' => 'input' , 'values' => '', 'class' => 'date');
$config->project->includedPriv['project'] = array('edit', 'group', 'createGroup', 'managePriv', 'manageMembers', 'manageGroupMember', 'copyGroup', 'editGroup', 'start', 'suspend', 'close', 'activate', 'delete', 'view', 'whitelist', 'addWhitelist', 'unbindWhitelist', 'manageProducts', 'dynamic', 'build', 'bug', 'testcase', 'testtask', 'testreport', 'execution', 'team', 'unlinkMember');
$config->project->includedPriv['execution'] = array('create', 'start', 'delete', 'calendar', 'effortCalendar', 'effort', 'taskEffort', 'computeTaskEffort', 'deleterelation', 'maintainrelation', 'relation', 'gantt');
$config->project->includedPriv['task'] = array('create');
+5
View File
@@ -308,6 +308,11 @@ class project extends control
$programTitle = $this->loadModel('setting')->getItem('owner=' . $this->app->user->account . '&module=project&key=programTitle');
$projectStats = $this->loadModel('program')->getProjectStats($programID, $browseType, $queryID, $orderBy, $pager, $programTitle);
$actionURL = $this->createLink('project', 'browse', "&programID=$programID&browseType=bySearch&queryID=myQueryID");
$this->project->buildSearchFrom($queryID, $actionURL);
$projectQuery = $this->session->projectQuery;
if($browseType == 'bySearch') $projectStats = $this->project->getBySearch($projectQuery);
$this->view->title = $this->lang->project->browse;
$this->view->position[] = $this->lang->project->browse;
+2
View File
@@ -227,6 +227,7 @@ $lang->project->currencySymbol['NZD'] = 'NZ$';
$lang->project->currencySymbol['THB'] = '฿';
$lang->project->currencySymbol['SGD'] = 'S$';
$lang->project->modelList[''] = '';
$lang->project->modelList['scrum'] = "Scrum";
$lang->project->modelList['waterfall'] = "CMMI";
$lang->project->modelList['kanban'] = "Kanban";
@@ -257,6 +258,7 @@ $lang->project->kanbanSubAclList['program'] = 'Open in the program (all upper-le
$lang->project->authList['extend'] = 'Inherit (system privilege and project privilege)';
$lang->project->authList['reset'] = 'Reset (project privilege only)';
$lang->project->statusList[''] = '';
$lang->project->statusList['wait'] = 'Waiting';
$lang->project->statusList['doing'] = 'Doing';
$lang->project->statusList['suspended'] = 'Suspended';
+2
View File
@@ -227,6 +227,7 @@ $lang->project->currencySymbol['NZD'] = 'NZ$';
$lang->project->currencySymbol['THB'] = '฿';
$lang->project->currencySymbol['SGD'] = 'S$';
$lang->project->modelList[''] = "";
$lang->project->modelList['scrum'] = "Scrum";
$lang->project->modelList['waterfall'] = "瀑布";
$lang->project->modelList['kanban'] = "看板";
@@ -257,6 +258,7 @@ $lang->project->kanbanSubAclList['program'] = '项目集内公开(所有上级
$lang->project->authList['extend'] = '继承 (取系统权限与项目权限的合集)';
$lang->project->authList['reset'] = '重新定义 (只取项目权限)';
$lang->project->statusList[''] = '';
$lang->project->statusList['wait'] = '未开始';
$lang->project->statusList['doing'] = '进行中';
$lang->project->statusList['suspended'] = '已挂起';
+146 -48
View File
@@ -825,6 +825,39 @@ class projectModel extends model
->fetchGroup('productID', 'branchID');
}
/*
* Get projects by search conditions.
*
* @param string $projectQuery
* @return array
* */
public function getBySearch($projectQuery)
{
return $this->dao->select('*')->from(TABLE_PROJECT)
->where($projectQuery)
->andWhere('type')->eq('project')
->fetchAll();
}
/*
* Build search form
*
* @param int $queryID
* @param string $actionURL
*
* @return 0
* */
public function buildSearchFrom($queryID, $actionURL)
{
$this->config->project->search['queryID'] = $queryID;
$this->config->project->search['actionURL'] = $actionURL;
$programPairs = array(0 => '');
$programPairs += $this->loadModel('program')->getPairs();
$this->config->project->search['params']['parent']['values'] = $programPairs;
$this->loadModel('search')->setSearchParams($this->config->project->search);
}
/**
* Build the query.
*
@@ -1959,54 +1992,8 @@ class projectModel extends model
echo html::ring($project->hours->progress);
break;
case 'actions':
$moduleName = $this->config->systemMode == 'classic' ? "execution" : "project";
if($project->status == 'wait' or $project->status == 'suspended') common::printIcon($moduleName, 'start', "projectID=$project->id", $project, 'list', 'play', '', 'iframe', true);
if($project->status == 'doing') common::printIcon($moduleName, 'close', "projectID=$project->id", $project, 'list', 'off', '', 'iframe', true);
if($project->status == 'closed') common::printIcon($moduleName, 'activate', "projectID=$project->id", $project, 'list', 'magic', '', 'iframe', true);
if(common::hasPriv($moduleName, 'suspend') or (common::hasPriv($moduleName, 'close') and $project->status != 'doing') or (common::hasPriv($moduleName, 'activate') && $project->status != 'closed'))
{
echo "<div class='btn-group'>";
echo "<button type='button' class='btn icon-caret-down dropdown-toggle' data-toggle='context-dropdown' title='{$this->lang->more}' style='width: 16px; padding-left: 0px; border-radius: 4px;'></button>";
echo "<ul class='dropdown-menu pull-right text-center' role='menu' style='position: unset; min-width: auto; padding: 5px 6px;'>";
common::printIcon($moduleName, 'suspend', "projectID=$project->id", $project, 'list', 'pause', '', 'iframe btn-action', true);
if($project->status != 'doing') common::printIcon($moduleName, 'close', "projectID=$project->id", $project, 'list', 'off', '', 'iframe btn-action', true);
if($project->status != 'closed') common::printIcon($moduleName, 'activate', "projectID=$project->id", $project, 'list', 'magic', '', 'iframe btn-action', true);
echo "</ul>";
echo "</div>";
}
$from = $project->from == 'project' ? 'project' : 'pgmproject';
$iframe = ($this->app->tab == 'program' or $project->model == 'kanban') ? 'iframe' : '';
$onlyBody = ($this->app->tab == 'program' or $project->model == 'kanban') ? true : '';
$dataApp = $this->config->systemMode == 'classic' ? "data-app=execution" : "data-app=project";
$attr = $project->model == 'kanban' ? " disabled='disabled'" : '';
common::printIcon($moduleName, 'edit', "projectID=$project->id", $project, 'list', 'edit', '', $iframe, $onlyBody, $dataApp);
if($this->config->vision != 'lite')
{
common::printIcon($moduleName, 'team', "projectID=$project->id", $project, 'list', 'group', '', '', '', $dataApp . $attr, $this->lang->execution->team);
if($this->config->systemMode == 'new') common::printIcon('project', 'group', "projectID=$project->id&programID=$programID", $project, 'list', 'lock', '', '', '', $dataApp . $attr);
if(common::hasPriv($moduleName, 'manageProducts') or common::hasPriv($moduleName, 'whitelist') or common::hasPriv($moduleName, 'delete'))
{
echo "<div class='btn-group'>";
echo "<button type='button' class='btn dropdown-toggle' data-toggle='context-dropdown' title='{$this->lang->more}'><i class='icon-more-alt'></i></button>";
echo "<ul class='dropdown-menu pull-right text-center' role='menu'>";
common::printIcon($moduleName, 'manageProducts', "projectID=$project->id", $project, 'list', 'link', '', 'btn-action', '', $attr, $this->lang->project->manageProducts);
if($this->config->systemMode == 'new') common::printIcon('project', 'whitelist', "projectID=$project->id&module=project&from=$from", $project, 'list', 'shield-check', '', 'btn-action', '', $dataApp . $attr);
if(common::hasPriv($moduleName, 'delete')) echo html::a(helper::createLink($moduleName, "delete", "projectID=$project->id"), "<i class='icon-trash'></i>", 'hiddenwin', "class='btn btn-action' title='{$this->lang->project->delete}'");
echo "</ul>";
echo "</div>";
}
}
else
{
common::printIcon($moduleName, 'team', "projectID=$project->id", $project, 'list', 'group', '', '', '', $dataApp, $this->lang->execution->team);
if($this->config->systemMode == 'new') common::printIcon('project', 'whitelist', "projectID=$project->id&module=project&from=$from", $project, 'list', 'shield-check', '', 'btn-action', '', $dataApp);
if(common::hasPriv($moduleName, 'delete')) echo html::a(helper::createLink($moduleName, "delete", "projectID=$project->id"), "<i class='icon-trash'></i>", 'hiddenwin', "class='btn btn-action' title='{$this->lang->project->delete}'");
}
$project->programID = $programID;
echo $this->buildOperateMenu($project, 'browse');
break;
}
echo '</td>';
@@ -2553,4 +2540,115 @@ class projectModel extends model
->fetch();
return $result;
}
/**
* Build project action menu.
*
* @param object $project
* @param string $type
* @access public
* @return string
*/
public function buildOperateMenu($project, $type = 'view')
{
$function = 'buildOperate' . ucfirst($type) . 'Menu';
return $this->$function($project);
}
/**
* Build project view action menu.
*
* @param object $project
* @access public
* @return string
*/
public function buildOperateViewMenu($project)
{
if($project->deleted) return '';
$menu = '';
$params = "projectID=$project->id";
$menu .= "<div class='divider'></div>";
$menu .= $this->buildMenu('project', 'start', $params, $project, 'view', 'play', '', 'iframe', true, '', $this->lang->project->start);
$menu .= $this->buildMenu('project', 'activate', $params, $project, 'view', 'magic', '', 'iframe', true, '', $this->lang->project->activate);
$menu .= $this->buildMenu('project', 'suspend', $params, $project, 'view', 'pause', '', 'iframe', true, '', $this->lang->project->suspend);
$menu .= $this->buildMenu('project', 'close', $params, $project, 'view', 'off', '', 'iframe', true, '', $this->lang->close);
$menu .= "<div class='divider'></div>";
$menu .= $this->buildFlowMenu('project', $project, 'view', 'direct');
$menu .= "<div class='divider'></div>";
$menu .= $this->buildMenu('project', 'edit', "project=$project->id&from=view", $project, 'button', 'edit', '', '', '', '', $this->lang->edit);
$menu .= $this->buildMenu('project', 'delete', "project=$project->id", $project, 'button', 'trash', 'hiddenwin', '', '', '', $this->lang->delete);
return $menu;
}
/**
* Build project browse action menu.
*
* @param object $project
* @access public
* @return string
*/
public function buildOperateBrowseMenu($project)
{
$menu = '';
$params = "projectID=$project->id";
$moduleName = $this->config->systemMode == 'classic' ? "execution" : "project";
if($project->status == 'wait' || $project->status == 'suspended')
{
$menu .= $this->buildMenu($moduleName, 'start', $params, $project, 'browse', 'play', '', 'iframe', true);
}
if($project->status == 'doing') $menu .= $this->buildMenu($moduleName, 'close', $params, $project, 'browse', 'off', '', 'iframe', true);
if($project->status == 'closed') $menu .= $this->buildMenu($moduleName, 'activate', $params, $project, 'browse', 'magic', '', 'iframe', true);
if(common::hasPriv($moduleName, 'suspend') || (common::hasPriv($moduleName, 'close') && $project->status != 'doing') || (common::hasPriv($moduleName, 'activate') && $project->status != 'closed'))
{
$menu .= "<div class='btn-group'>";
$menu .= "<button type='button' class='btn icon-caret-down dropdown-toggle' data-toggle='context-dropdown' title='{$this->lang->more}' style='width: 16px; padding-left: 0px; border-radius: 4px;'></button>";
$menu .= "<ul class='dropdown-menu pull-right text-center' role='menu' style='position: unset; min-width: auto; padding: 5px 6px;'>";
$menu .= $this->buildMenu($moduleName, 'suspend', $params, $project, 'browse', 'pause', '', 'iframe btn-action', true);
if($project->status != 'doing') $menu .= $this->buildMenu($moduleName, 'close', $params, $project, 'browse', 'off', '', 'iframe btn-action', true);
if($project->status != 'closed') $menu .= $this->buildMenu($moduleName, 'activate', $params, $project, 'browse', 'magic', '', 'iframe btn-action', true);
$menu .= "</ul>";
$menu .= "</div>";
}
$from = $project->from == 'project' ? 'project' : 'pgmproject';
$iframe = ($this->app->tab == 'program' || $project->model == 'kanban') ? 'iframe' : '';
$onlyBody = ($this->app->tab == 'program' || $project->model == 'kanban') ? true : '';
$dataApp = $this->config->systemMode == 'classic' ? "data-app=execution" : "data-app=project";
$attr = $project->model == 'kanban' ? " disabled='disabled'" : '';
$menu .= $this->buildMenu($moduleName, 'edit', $params, $project, 'browse', 'edit', '', $iframe, $onlyBody, $dataApp);
if($this->config->vision != 'lite')
{
$menu .= $this->buildMenu($moduleName, 'team', $params, $project, 'browse', 'group', '', '', '', $dataApp . $attr, $this->lang->execution->team);
if($this->config->systemMode == 'new') $menu .= $this->buildMenu('project', 'group', "$params&programID={$project->programID}", $project, 'browse', 'lock', '', '', '', $dataApp . $attr);
if(common::hasPriv($moduleName, 'manageProducts') || common::hasPriv($moduleName, 'whitelist') || common::hasPriv($moduleName, 'delete'))
{
$menu .= "<div class='btn-group'>";
$menu .= "<button type='button' class='btn dropdown-toggle' data-toggle='context-dropdown' title='{$this->lang->more}'><i class='icon-more-alt'></i></button>";
$menu .= "<ul class='dropdown-menu pull-right text-center' role='menu'>";
$menu .= $this->buildMenu($moduleName, 'manageProducts', $params, $project, 'browse', 'link', '', 'btn-action', '', $attr, $this->lang->project->manageProducts);
if($this->config->systemMode == 'new') $menu .= $this->buildMenu('project', 'whitelist', "$params&module=project&from=$from", $project, 'browse', 'shield-check', '', 'btn-action', '', $dataApp . $attr);
$menu .= $this->buildMenu($moduleName, "delete", $params, $project, 'browse', 'trash', 'hiddenwin', 'btn-action');
$menu .= "</ul>";
$menu .= "</div>";
}
}
else
{
$menu .= $this->buildMenu($moduleName, 'team', $params, $project, 'browse', 'group', '', '', '', $dataApp, $this->lang->execution->team);
if($this->config->systemMode == 'new') $menu .= $this->buildMenu('project', 'whitelist', "$params&module=project&from=$from", $project, 'browse', 'shield-check', '', 'btn-action', '', $dataApp);
$menu .= $this->buildMenu($moduleName, "delete", $params, $project, 'browse', 'trash', 'hiddenwin', 'btn-action');
}
return $menu;
}
}
@@ -40,6 +40,7 @@
<?php echo html::a(inlink('browse', "programID=$programID&browseType=$key"), $label, '', "class='btn btn-link $active'");?>
<?php endforeach;?>
<?php echo html::checkbox('involved', array('1' => $lang->project->mine), '', $this->cookie->involved ? 'checked=checked' : '');?>
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php echo $lang->search->common;?></a>
</div>
<div class="btn-toolbar pull-right">
<div class="btn-group panel-actions">
@@ -67,6 +68,7 @@
</div>
<?php endif;?>
<div class="main-col">
<div class="cell<?php if($browseType == 'bysearch') echo ' show';?>" id="queryBox" data-module='project'></div>
<?php if(empty($projectStats)):?>
<div class="table-empty-tip">
<p>
+3 -19
View File
@@ -96,25 +96,9 @@
</div>
<div class='main-actions'>
<div class="btn-toolbar">
<?php
$params = "project=$project->id";
$browseLink = $this->session->projectList ? $this->session->projectList : inlink('browse');
common::printBack($browseLink);
if(!$project->deleted)
{
echo "<div class='divider'></div>";
common::printIcon('project', 'start', "projectID=$project->id", $project, 'button', 'play', '', 'iframe', true, '', $lang->project->start);
common::printIcon('project', 'activate', "projectID=$project->id", $project, 'button', 'magic', '', 'iframe', true, '', $lang->project->activate);
common::printIcon('project', 'suspend', "projectID=$project->id", $project, 'button', 'pause', '', 'iframe', true, '', $lang->project->suspend);
common::printIcon('project', 'close', "projectID=$project->id", $project, 'button', 'off', '', 'iframe', true, '', $lang->close);
echo $this->buildOperateMenu($project, 'view');
echo "<div class='divider'></div>";
common::printIcon('project', 'edit', $params . '&from=view', $project, 'button', 'edit', '', '', '', '', $lang->edit);
common::printIcon('project', 'delete', $params, $project, 'button', 'trash', 'hiddenwin', '', '', '', $lang->delete);
}
?>
<?php $browseLink = $this->session->projectList ? $this->session->projectList : inlink('browse');?>
<?php common::printBack($browseLink);?>
<?php echo $this->project->buildOperateMenu($project, 'view');?>
</div>
</div>
</div>