Merge branch 'lite' into sprint/185

This commit is contained in:
zhujinyong
2022-02-17 10:20:50 +08:00
53 changed files with 960 additions and 130 deletions

View File

@@ -32,6 +32,7 @@ $config->methodVar = 'f'; // 请求类型为GET模块
$config->viewVar = 't'; // 请求类型为GET视图变量名。 requestType=GET: the view var name.
$config->sessionVar = 'zentaosid'; // 请求类型为GETsession变量名。 requestType=GET: the session var name.
$config->views = ',html,json,mhtml,xhtml,'; // 支持的视图类型。 Supported view formats.
$config->visions = ',rnd,lite,'; // 支持的界面类型。 Supported vision formats.
/* 支持的主题和语言。Supported thems and languages. */
$config->themes['default'] = 'default';

View File

@@ -1,3 +1,4 @@
=======
ALTER TABLE `zt_project` ADD `vision` varchar(10) NOT NULL DEFAULT 'rnd' AFTER `order`;
ALTER TABLE `zt_product` ADD `vision` varchar(10) NOT NULL DEFAULT 'rnd' AFTER `order`;
ALTER TABLE `zt_task` ADD `vision` varchar(10) NOT NULL DEFAULT 'rnd' AFTER `deleted`;
@@ -16,3 +17,6 @@ ALTER TABLE `zt_block` ADD `vision` varchar(10) NOT NULL DEFAULT 'rnd' AFTER `ac
ALTER TABLE `zt_block` DROP INDEX `account_module_type_order`, ADD UNIQUE `account_vision_module_type_order` (`account`, `vision`, `module`, `type`, `order`);
ALTER TABLE `zt_effort` ADD `vision` varchar(10) NOT NULL DEFAULT 'rnd' AFTER `id`;
ALTER TABLE `zt_story` ADD `vision` varchar(10) NOT NULL DEFAULT 'rnd' AFTER `id`;
ALTER TABLE `zt_user` ADD `visions` varchar(20) NOT NULL AFTER `visits`;
UPDATE `zt_user` SET `visions`='rnd,lite';

View File

@@ -1,8 +1,8 @@
<?php
$lang->action->label->execution = "看板|execution|task|executionID=%s";
$lang->action->label->task = '卡片|task|view|taskID=%s';
$lang->action->label->task = '任务|task|view|taskID=%s';
$lang->action->objectTypes['task'] = '卡片';
$lang->action->objectTypes['task'] = '任务';
unset($lang->action->dynamicAction->program);
unset($lang->action->dynamicAction->product);

View File

@@ -11,9 +11,9 @@ $lang->block->delayed = '已延期';
$lang->block->titleList['scrumlist'] = '看板列表';
$lang->block->titleList['sprint'] = '看板总览';
$lang->block->myTask = '我的卡片';
$lang->block->myTask = '我的任务';
$lang->block->finishedTasks = '完成的卡片数';
$lang->block->finishedTasks = '完成的任务数';
$lang->block->story = '目标';
@@ -44,7 +44,7 @@ $lang->block->modules['execution']->availableBlocks = new stdclass();
$lang->block->modules['execution']->availableBlocks->statistic = $lang->execution->common . '统计';
$lang->block->modules['execution']->availableBlocks->overview = $lang->execution->common . '总览';
$lang->block->modules['execution']->availableBlocks->list = $lang->execution->common . '列表';
$lang->block->modules['execution']->availableBlocks->task = '卡片列表';
$lang->block->modules['execution']->availableBlocks->task = '任务列表';
unset($lang->block->moduleList['product']);
unset($lang->block->moduleList['qa']);

View File

@@ -1,18 +1,16 @@
<?php
$lang->execution->common = '看板';
$lang->executionCommon = '看板';
$lang->task->common = '卡片';
$lang->task->common = '任务';
$lang->story->common = '目标';
/* Main Navigation. */
$lang->mainNav = new stdclass();
$lang->mainNav->my = "{$lang->navIcons['my']} {$lang->my->shortCommon}|my|index|";
$lang->mainNav->project = "{$lang->navIcons['project']} {$lang->project->common}|$projectModule|$projectMethod|";
$lang->mainNav->execution = "{$lang->navIcons['execution']} {$lang->execution->common}|$executionModule|$executionMethod|";
$lang->mainNav->execution = "{$lang->navIcons['execution']} 任务|$executionModule|$executionMethod|";
$lang->mainNav->kanban = "{$lang->navIcons['kanban']} {$lang->kanban->common}|kanban|space|";
$lang->mainNav->doc = "{$lang->navIcons['doc']} {$lang->doc->common}|doc|index|";
$lang->mainNav->report = "{$lang->navIcons['report']} {$lang->report->common}|report|productSummary|";
$lang->mainNav->kanban = "{$lang->navIcons['kanban']} {$lang->kanban->common}|kanban|space|";
$lang->mainNav->system = "{$lang->navIcons['system']} {$lang->system->common}|my|team|";
$lang->mainNav->admin = "{$lang->navIcons['admin']} {$lang->admin->common}|admin|index|";
@@ -46,7 +44,7 @@ else
$lang->dividerMenu = ',doc,admin,';
}
$lang->task->common = '卡片';
$lang->task->common = '任务';
/* My menu. */
$lang->my->menu = new stdclass();
@@ -88,13 +86,13 @@ $lang->kanban->menuOrder[20] = 'doc';
$lang->kanban->menuOrder[25] = 'dynamic';
$lang->kanban->menuOrder[30] = 'settings';
$lang->execution->menu = new stdclass();
$lang->execution->menu->kanban = array('link' => "看板|execution|kanban|executionID=%s");
$lang->execution->menu->list = array('link' => "列表|execution|task|executionID=%s");
if($config->edition != 'open') $lang->execution->menu->calendar = array('link' => "日历|execution|calendar|executionID=%s");
$lang->execution->menu = new stdclass();
$lang->execution->menu->kanban = array('link' => "看板视图|execution|kanban|executionID=%s");
$lang->execution->menu->task = array('link' => "列表视图|execution|task|executionID=%s");
if($config->edition != 'open') $lang->execution->menu->calendar = array('link' => "日历视图|execution|calendar|executionID=%s");
if($config->edition != 'open') $lang->execution->menu->gantt = array('link' => "甘特图|execution|gantt|executionID=%s");
$lang->execution->menu->tree = array('link' => "树状图|execution|tree|executionID=%s");
$lang->execution->menu->group = array('link' => "分组视图|execution|grouptask|executionID=%s");
$lang->execution->menu->tree = array('link' => "树状图|execution|tree|executionID=%s");
$lang->execution->menu->grouptask = array('link' => "分组视图|execution|grouptask|executionID=%s");
$lang->kanban->menu->doc['subMenu'] = new stdclass();
@@ -204,7 +202,7 @@ $lang->admin->dividerMenu = ',company,message,system,';
$lang->searchObjects['all'] = '全部';
$lang->searchObjects['todo'] = '待办';
$lang->searchObjects['story'] = '目标';
$lang->searchObjects['task'] = '卡片';
$lang->searchObjects['task'] = '任务';
$lang->searchObjects['doc'] = '文档';
$lang->searchObjects['project'] = '项目';
$lang->searchObjects['execution'] = '看板';
@@ -247,7 +245,7 @@ unset($lang->createIcons['kanbanspace']);
unset($lang->createIcons['kanban']);
$lang->createObjects['story'] = '目标';
$lang->createObjects['task'] = '卡片';
$lang->createObjects['task'] = '任务';
$lang->createObjects['execution'] = '看板';
$lang->createIcons['execution'] = 'kanban';

View File

@@ -0,0 +1,3 @@
<?php
$lang->company->execution = '看板';
$lang->company->product = '项目';

View File

@@ -4,6 +4,7 @@ $config->custom->requiredModules[10] = 'project';
$config->custom->requiredModules[20] = 'story';
$config->custom->requiredModules[35] = 'execution';
$config->custom->requiredModules[40] = 'task';
$config->custom->requiredModules[80] = 'doc';
$config->custom->requiredModules[85] = 'user';
$config->custom->fieldList['execution']['create'] = 'desc';

View File

@@ -1,7 +1,7 @@
<?php
$lang->custom->execution = '看板';
$lang->custom->closedExecution = '已关闭' . $lang->custom->execution;
$lang->custom->notice->readOnlyOfExecution = "禁止修改后,已关闭{$lang->custom->execution}下的卡片、日志以及关联目标都禁止修改。";
$lang->custom->notice->readOnlyOfExecution = "禁止修改后,已关闭{$lang->custom->execution}下的任务、日志以及关联目标都禁止修改。";
$lang->custom->moduleName['execution'] = $lang->custom->execution;
@@ -9,7 +9,7 @@ $lang->custom->object = array();
$lang->custom->object['project'] = '项目';
$lang->custom->object['execution'] = $lang->custom->execution;
$lang->custom->object['story'] = $lang->SRCommon;
$lang->custom->object['task'] = '卡片';
$lang->custom->object['task'] = '任务';
$lang->custom->object['todo'] = '待办';
$lang->custom->object['user'] = '用户';
$lang->custom->object['block'] = '区块';

View File

@@ -22,7 +22,7 @@ $lang->dev->tableList['projectstory'] = '项目' . $lang->SRCommon;
$lang->dev->tableList['execution'] = $lang->executionCommon;
$lang->dev->tableList['story'] = $lang->SRCommon;
$lang->dev->tableList['storyspec'] = "{$lang->SRCommon}描述";
$lang->dev->tableList['task'] = '卡片';
$lang->dev->tableList['task'] = '任务';
$lang->dev->tableList['taskestimate'] = '任务预计';
$lang->dev->tableList['team'] = '团队';
$lang->dev->tableList['todo'] = '待办';

View File

@@ -7,11 +7,14 @@ class myExecution extends execution
$this->app->loadLang('kanban');
common::setMenuVars('execution', $executionID);
$execution = $this->execution->getById($executionID);
$currentMethod = $this->app->methodName;
$execution = $this->execution->getById($executionID);
$this->loadModel('project')->setMenu($execution->project);
$this->lang->kanban->menu->execution['subMenu'] = $this->lang->execution->menu;
$this->lang->kanban->menu->execution['subMenu'] = new stdClass();
/* change subMenu to sub select menu */
$TRActions = $this->execution->getTRActions($currentMethod);
$TRActions = '';
$TRActions .= "<div class='dropdown'>";
$TRActions .= html::a('javascript:;', $this->lang->execution->kanbanGroup[$groupBy] . "<span class='caret'></span>", '', "data-toggle='dropdown' data- class='btn btn-link'");
$TRActions .= "<ul class='dropdown-menu pull-right'>";

View File

@@ -5,11 +5,18 @@ unset($lang->execution->featureBar['all']['suspended']);
$lang->execution->createKanban = '创建看板';
$lang->execution->noExecution = "暂时没有看板。";
$lang->execution->importTask = '转入卡片';
$lang->execution->batchCreateTask = '批量创建卡片';
$lang->execution->importTask = '转入任务';
$lang->execution->batchCreateTask = '批量创建任务';
$lang->execution->kanbanGroup['default'] = '默认方式';
$lang->execution->kanbanGroup['story'] = '目标';
$lang->execution->kanbanGroup['module'] = '所属目录';
$lang->execution->kanbanGroup['pri'] = '优先级';
$lang->execution->kanbanGroup['assignedTo'] = '指派人';
$lang->execution->icons['kanban'] = 'kanban';
$lang->execution->icons['task'] = 'list';
$lang->execution->icons['calendar'] = 'calendar';
$lang->execution->icons['gantt'] = 'lane';
$lang->execution->icons['tree'] = 'treemap';
$lang->execution->icons['grouptask'] = 'sitemap';

View File

@@ -7,7 +7,7 @@ public function setMenu($executionID, $buildID = 0, $extra = '')
if(isset($this->lang->execution->menu->kanban))
{
$this->loadModel('project')->setMenu($execution->project);
$this->lang->kanban->menu->execution['subMenu'] = $this->lang->execution->menu;
$this->lang->kanban->menu->execution['subMenu'] = new stdClass();
if($this->app->rawModule == 'tree') unset($this->lang->kanban->menu->execution['subMenu']);
}
@@ -28,7 +28,78 @@ public function setMenu($executionID, $buildID = 0, $extra = '')
$modulePageNav .= '<li>' . html::a(helper::createLink('execution', $this->app->rawMethod, "execution=$kanban->id"), $kanban->name) . '</li>';
}
$modulePageNav .= "</ul></div></div>";
if($this->app->rawMethod == 'task') $this->lang->TRActions = '';
if(in_array($this->app->rawMethod, array('task', 'calendar', 'gantt', 'tree', 'grouptask'))) $this->lang->TRActions = $this->getTRActions($this->app->rawMethod);
$this->lang->modulePageNav = $modulePageNav;
}
public function getTree($executionID)
{
$fullTrees = $this->loadModel('tree')->getTaskStructure($executionID, 0);
array_unshift($fullTrees, array('id' => 0, 'name' => '/', 'type' => 'task', 'actions' => false, 'root' => $executionID));
foreach($fullTrees as $i => $tree)
{
$tree = (object)$tree;
if($tree->type == 'product') array_unshift($tree->children, array('id' => 0, 'name' => '/', 'type' => 'story', 'actions' => false, 'root' => $tree->root));
$fullTree = $this->fillTasksInTree($tree, $executionID);
if(empty($fullTree->children))
{
unset($fullTrees[$i]);
}
else
{
$fullTrees[$i] = $fullTree;
}
}
if(isset($fullTrees[0]) and empty($fullTrees[0]->children)) array_shift($fullTrees);
$newTrees = array();
foreach($fullTrees as $i => $tree)
{
if($tree->type == 'product')
{
foreach($tree->children as $value)
{
$newTrees[] = $value;
}
}
else
{
$newTrees[] = $tree;
}
}
return array_values($newTrees);
}
public function getTRActions($currentMethod)
{
$subMenu = $this->lang->execution->menu;
foreach($subMenu as $key => $value)
{
$tmpValue = explode('|', $value['link']);
$subMenu->$key['name'] = $tmpValue[0];
$subMenu->$key['module'] = $tmpValue[1];
$subMenu->$key['method'] = $tmpValue[2];
$subMenu->$key['vars'] = $tmpValue[3];
}
$TRActions = '';
$TRActions .= "<div class='dropdown'>";
$TRActions .= html::a('javascript:;', "<i class='icon icon-".$this->lang->execution->icons[$currentMethod]."'></i> " . $subMenu->$currentMethod['name'] . "<span class='caret'></span>", '', "data-toggle='dropdown' data- class='btn btn-link'"); $TRActions .= "<ul class='dropdown-menu pull-right'>";
foreach($subMenu as $subKey => $subName)
{
$TRActions .= '<li>' . html::a(helper::createLink('execution', $subName['method'], $subName['vars']), "<i class='icon icon-" . $this->lang->execution->icons[$subName['method']] . "'></i> " . $subName['name']) . '</li>';
}
$TRActions .= "</ul></div>";
return $TRActions;
}

View File

@@ -1,3 +1,7 @@
<style>
.kanban-card .title i.icon-checked {display:none;}
.kanban-card .infos .info-id {display:none;}
</style>
<script>
$('#mainMenu').remove();
</script>

View File

@@ -0,0 +1,8 @@
<?php
$lang->kanban->taskColumn = array();
$lang->kanban->taskColumn['wait'] = '未开始';
$lang->kanban->taskColumn['developing'] = '进行中';
$lang->kanban->taskColumn['developed'] = '已完成';
$lang->kanban->taskColumn['pause'] = '已暂停';
$lang->kanban->taskColumn['canceled'] = '已取消';
$lang->kanban->taskColumn['closed'] = '已关闭';

View File

@@ -0,0 +1,174 @@
<?php
public function __construct($appName = '')
{
parent::__construct($appName);
$this->lang->kanban->menu = new stdclass();
}
public function getKanban4Group($executionID, $browseType, $groupBy)
{
/* Get card data. */
$cardList = array();
if($browseType == 'story') $cardList = $this->loadModel('story')->getExecutionStories($executionID, 0, 0, 't1.`order`_desc', 'allStory');
if($browseType == 'bug') $cardList = $this->loadModel('bug')->getExecutionBugs($executionID);
if($browseType == 'task') $cardList = $this->loadModel('execution')->getKanbanTasks($executionID, "id");
$lanes = $this->getLanes4Group($executionID, $browseType, $groupBy, $cardList);
if(empty($lanes)) return array();
$columns = $this->dao->select('t1.*, t2.`type` as columnType')->from(TABLE_KANBANCELL)->alias('t1')
->leftJoin(TABLE_KANBANCOLUMN)->alias('t2')->on('t1.`column` = t2.id')
->where('t1.kanban')->eq($executionID)
->andWhere('t1.`type`')->eq($browseType)
->fetchAll();
$cardGroup = array();
foreach($columns as $column)
{
if(empty($column->cards)) continue;
foreach($cardList as $card)
{
if(strpos($column->cards, ",$card->id,") !== false) $cardGroup[$column->columnType][$card->id] = $card;
}
}
/* Build kanban group data. */
$kanbanGroup = array();
foreach($lanes as $laneID => $lane)
{
$laneData = array();
$columnData = array();
$columnList = $this->lang->kanban->{$browseType . 'Column'};
$laneData['id'] = $groupBy . $laneID;
$laneData['laneID'] = $groupBy . $laneID;
$laneData['name'] = (($groupBy == 'pri' or $groupBy == 'severity') and $laneID) ? $this->lang->$browseType->$groupBy . ':' . $lane->name : $lane->name;
$laneData['color'] = $lane->color;
$laneData['order'] = $lane->order;
$laneData['defaultCardType'] = $browseType;
/* Construct kanban column data. */
foreach($columnList as $columnID => $columnName)
{
$parentColumn = '';
if(in_array($columnID, array('testing', 'tested'))) $parentColumn = 'test';
if(in_array($columnID, array('fixing', 'fixed'))) $parentColumn = 'resolving';
$columnData[$columnID]['id'] = $columnID;
$columnData[$columnID]['type'] = $columnID;
$columnData[$columnID]['name'] = $columnName;
$columnData[$columnID]['color'] = '#333';
$columnData[$columnID]['limit'] = -1;
$columnData[$columnID]['laneType'] = $browseType;
$columnData[$columnID]['asParent'] = in_array($columnID, array('develop', 'test', 'resolving')) ? true : false;
$columnData[$columnID]['parentType'] = $parentColumn;
$cardOrder = 1;
$objects = zget($cardGroup, $columnID, array());
foreach($objects as $object)
{
if(empty($object)) continue;
$cardData = array();
if(in_array($groupBy, array('module', 'story', 'pri', 'severity')) and (int)$object->$groupBy !== $laneID) continue;
if(in_array($groupBy, array('assignedTo', 'type', 'category', 'source')) and $object->$groupBy != $laneID) continue;
$cardData['id'] = $object->id;
$cardData['order'] = $cardOrder;
$cardData['pri'] = $object->pri ? $object->pri : '';
$cardData['estimate'] = $browseType == 'bug' ? '' : $object->estimate;
$cardData['assignedTo'] = $object->assignedTo;
$cardData['deadline'] = $browseType == 'story' ? '' : $object->deadline;
$cardData['severity'] = $browseType == 'bug' ? $object->severity : '';
if($browseType == 'task')
{
$cardData['name'] = $object->name;
}
else
{
$cardData['title'] = $object->title;
}
$laneData['cards'][$columnID][] = $cardData;
$cardOrder ++;
}
if(!isset($laneData['cards'][$columnID])) $laneData['cards'][$columnID] = array();
}
$kanbanGroup[$groupBy]['id'] = $groupBy . $laneID;
$kanbanGroup[$groupBy]['columns'] = array_values($columnData);
$kanbanGroup[$groupBy]['lanes'][] = $laneData;
$kanbanGroup[$groupBy]['defaultCardType'] = $browseType;
}
return $kanbanGroup;
}
/**
* Get card group by execution id.
*
* @param int $kanbanID
* @param string $browseType all|task|bug|story
* @param string $orderBy
* @access public
* @return array
*/
public function getCardGroupByExecution($executionID, $browseType = 'all', $orderBy = 'id_asc')
{
$cards = $this->dao->select('t1.*, t2.type as columnType')
->from(TABLE_KANBANCELL)->alias('t1')
->leftJoin(TABLE_KANBANCOLUMN)->alias('t2')->on('t1.column=t2.id')
->where('t1.kanban')->eq($executionID)
->beginIF($browseType != 'all')->andWhere('t1.type')->eq($browseType)->fi()
->orderby($orderBy)
->fetchgroup('lane', 'column');
/* Get group objects. */
if($browseType == 'all' or $browseType == 'story') $objectGroup['story'] = $this->loadModel('story')->getExecutionStories($executionID, 0, 0, 't1.`order`_desc', 'allStory');
if($browseType == 'all' or $browseType == 'bug') $objectGroup['bug'] = $this->loadModel('bug')->getExecutionBugs($executionID);
if($browseType == 'all' or $browseType == 'task') $objectGroup['task'] = $this->loadModel('execution')->getKanbanTasks($executionID, "id");
$taskCardMenu = $this->getKanbanCardMenu($executionID, $objectGroup['task'], 'task');
$cardGroup = array();
foreach($cards as $laneID => $cells)
{
foreach($cells as $columnID => $cell)
{
$cardIdList = array_filter(explode(',', $cell->cards));
$cardOrder = 1;
foreach($cardIdList as $cardID)
{
$cardData = array();
$objects = zget($objectGroup, $cell->type, array());
$object = zget($objects, $cardID, array());
if(empty($object)) continue;
$cardData['id'] = $object->id;
$cardData['order'] = $cardOrder++;
$cardData['pri'] = $object->pri ? $object->pri : '';
$cardData['estimate'] = $cell->type == 'bug' ? '' : $object->estimate;
$cardData['assignedTo'] = $object->assignedTo;
$cardData['deadline'] = $cell->type == 'story' ? '' : $object->deadline;
$cardData['severity'] = $cell->type == 'bug' ? $object->severity : '';
$cardData['acl'] = 'open';
$cardData['lane'] = $laneID;
$cardData['column'] = $cell->column;
$cardData['menus'] = $taskCardMenu[$cardID];
if($cell->type == 'task')
{
$cardData['name'] = $object->name;
}
else
{
$cardData['title'] = $object->title;
}
$cardGroup[$laneID][$cell->columnType][] = $cardData;
}
}
}
return $cardGroup;
}

View File

@@ -42,7 +42,6 @@ $projectIDParam = $isProjectStory ? "projectID=$projectID&" : '';
.btn-group button.dropdown-toggle.btn-secondary, .btn-group button.dropdown-toggle.btn-primary {padding:6px;}
</style>
<div id="mainMenu" class="clearfix">
<?php if(!$isProjectStory):?>
<div id="sidebarHeader">
<div class="title" title="<?php echo $moduleName;?>">
<?php
@@ -55,20 +54,7 @@ $projectIDParam = $isProjectStory ? "projectID=$projectID&" : '';
?>
</div>
</div>
<?php endif;?>
<div class="btn-toolbar pull-left">
<?php if($isProjectStory): ?>
<div class="btn-group">
<a href="javascript:;" class="btn btn-link" style="padding-right: 0;"> <?php echo $moduleName;?> </a>
<?php
if($moduleID)
{
$removeLink = $browseType == 'bymodule' ? $this->createLink($this->app->rawModule, $this->app->rawMethod, $projectIDParam . "productID=$productID&branch=$branch&browseType=$browseType&param=0&storyType=$storyType&orderBy=$orderBy&recTotal=0&recPerPage={$pager->recPerPage}") : 'javascript:removeCookieByKey("storyModuleParam")';
echo html::a($removeLink, "<i class='icon icon-sm icon-close'></i>", '', "class='text-muted btn btn-link' style='padding-left: 0;'");
}
?>
</div>
<?php endif;?>
<?php
if(!commonModel::isTutorialMode())
{

View File

@@ -0,0 +1,6 @@
<script>
$('#dataform table tbody tr:first-child').hide();
$('#dataform table tbody tr:nth-child(7)').hide();
$('#dataform table tbody tr:nth-child(8)').hide();
$('#dataform table tbody tr:nth-child(12)').hide();
</script>

View File

@@ -1,5 +1,5 @@
<?php
$lang->search->modules['task'] = '卡片';
$lang->search->modules['task'] = '任务';
$lang->search->modules['execution'] = '看板';
$lang->search->modules['story'] = '目标';

View File

@@ -0,0 +1,9 @@
<script>
$('#closedReason option').each(function()
{
if($(this).val() != '' && $(this).val() != 'done' && $(this).val() != 'duplicate' && $(this).val() != 'cancel')
{
$(this).remove();
}
})
</script>

View File

@@ -131,7 +131,7 @@
<th><?php echo $lang->story->spec;?></th>
<td colspan="4">
<?php echo $this->fetch('user', 'ajaxPrintTemplates', 'type=story&link=spec');?>
<?php echo html::textarea('spec', $spec, "rows='9' class='form-control kindeditor disabled-ie-placeholder' hidefocus='true' placeholder='" . htmlSpecialString($lang->story->specTemplate . "\n" . $lang->noticePasteImg) . "'");?>
<?php echo html::textarea('spec', $spec, "rows='9' class='form-control kindeditor disabled-ie-placeholder' hidefocus='true' placeholder='" . htmlSpecialString($lang->noticePasteImg) . "'");?>
</td>
</tr>
<tr class='hide'>
@@ -166,7 +166,7 @@
<?php echo html::hidden('product', $productID);?>
<?php echo html::hidden('plan', $planID);?>
<?php echo html::hidden('vision', 'lite');?>
<?php echo $gobackLink ? html::a($gobackLink, $lang->goback, '', 'class="btn btn-wide"') : html::backButton();?>
<?php echo html::backButton();?>
</td>
</tr>
</tfoot>

View File

@@ -0,0 +1,4 @@
<script>
$("a[href^='#affectedBugs']").parent().remove();
$("a[href^='#affectedCases']").parent().remove();
</script>

View File

@@ -11,6 +11,6 @@ class myTask extends task
die(js::locate(helper::createLink('execution', 'create')));
}
return parent::create($executionID = 0, $storyID = 0, $moduleID = 0, $taskID = 0, $todoID = 0, $extra = '');
return parent::create($executionID, $storyID, $moduleID, $taskID, $todoID, $extra);
}
}

View File

@@ -9,68 +9,69 @@
* @version $Id: zh-cn.php 5040 2013-07-06 06:22:18Z zhujinyonging@gmail.com $
* @link http://www.zentao.net
*/
$lang->task->index = "卡片一览";
$lang->task->create = "卡片";
$lang->task->batchCreateChildren = "批量建子卡片";
$lang->task->edit = "编辑卡片";
$lang->task->deleteAction = "删除卡片";
$lang->task->view = "查看卡片";
$lang->task->startAction = "开始卡片";
$lang->task->restartAction = "继续卡片";
$lang->task->finishAction = "完成卡片";
$lang->task->pauseAction = "暂停卡片";
$lang->task->closeAction = "关闭卡片";
$lang->task->cancelAction = "取消卡片";
$lang->task->activateAction = "激活卡片";
$lang->task->exportAction = "导出卡片";
$lang->task->copy = '复制卡片';
$lang->task->waitTask = '未开始的卡片';
$lang->task->index = "任务一览";
$lang->task->create = "任务";
$lang->task->batchCreateChildren = "批量建子任务";
$lang->task->edit = "编辑任务";
$lang->task->deleteAction = "删除任务";
$lang->task->view = "查看任务";
$lang->task->startAction = "开始任务";
$lang->task->restartAction = "继续任务";
$lang->task->finishAction = "完成任务";
$lang->task->pauseAction = "暂停任务";
$lang->task->closeAction = "关闭任务";
$lang->task->cancelAction = "取消任务";
$lang->task->activateAction = "激活任务";
$lang->task->exportAction = "导出任务";
$lang->task->copy = '复制任务';
$lang->task->waitTask = '未开始的任务';
$lang->task->common = '卡片';
$lang->task->name = '卡片名称';
$lang->task->type = '卡片类型';
$lang->task->status = '卡片状态';
$lang->task->desc = '卡片描述';
$lang->task->assignAction = '指派卡片';
$lang->task->multiple = '多人卡片';
$lang->task->children = '子卡片';
$lang->task->parent = '父卡片';
$lang->task->module = '所属目录';
$lang->task->common = '任务';
$lang->task->name = '任务名称';
$lang->task->type = '任务类型';
$lang->task->status = '任务状态';
$lang->task->desc = '任务描述';
$lang->task->assignAction = '指派任务';
$lang->task->multiple = '多人任务';
$lang->task->children = '子任务';
$lang->task->parent = '父任务';
/* Fields of zt_taskestimate. */
$lang->task->task = '卡片';
$lang->task->task = '任务';
$lang->task->dittoNotice = "卡片与上一卡片不属于同一%s";
$lang->task->yesterdayFinished = '昨日完成卡片数';
$lang->task->allTasks = '总卡片';
$lang->task->dittoNotice = "任务与上一任务不属于同一%s";
$lang->task->yesterdayFinished = '昨日完成任务数';
$lang->task->allTasks = '总任务';
$lang->task->afterChoices['continueAdding'] = "继续为该{$lang->SRCommon}添加卡片";
$lang->task->afterChoices['toTaskList'] = '返回卡片列表';
$lang->task->afterChoices['continueAdding'] = "继续为该{$lang->SRCommon}添加任务";
$lang->task->afterChoices['toTaskList'] = '返回任务列表';
$lang->task->legendLife = '卡片的一生';
$lang->task->legendDesc = '卡片描述';
$lang->task->legendDetail = '卡片详情';
$lang->task->legendLife = '任务的一生';
$lang->task->legendDesc = '任务描述';
$lang->task->legendDetail = '任务详情';
$lang->task->confirmDelete = "您确定要删除这个卡片吗?";
$lang->task->confirmDelete = "您确定要删除这个任务吗?";
$lang->task->confirmDeleteEstimate = "您确定要删除这个记录吗?";
$lang->task->confirmFinish = '"预计剩余"为0确认将卡片状态改为"已完成"吗?';
$lang->task->confirmRecord = '"剩余"为0卡片将标记为"已完成",您确定吗?';
$lang->task->confirmTransfer = '"当前剩余"为0卡片将被转交,您确定吗?';
$lang->task->noTask = '暂时没有卡片。';
$lang->task->confirmFinish = '"预计剩余"为0确认将任务状态改为"已完成"吗?';
$lang->task->confirmRecord = '"剩余"为0任务将标记为"已完成",您确定吗?';
$lang->task->confirmTransfer = '"当前剩余"为0任务将被转交,您确定吗?';
$lang->task->noTask = '暂时没有任务。';
$lang->task->kanbanDenied = '请先创建看板';
$lang->task->createDenied = '你不能在该项目添加卡片';
$lang->task->cannotDeleteParent = '不能删除父卡片。';
$lang->task->addChildTask = '因该卡片已经产生消耗,为保证数据一致性,我们会帮您创建一条同名子卡片记录该消耗。';
$lang->task->createDenied = '你不能在该项目添加任务';
$lang->task->cannotDeleteParent = '不能删除父任务。';
$lang->task->addChildTask = '因该任务已经产生消耗,为保证数据一致性,我们会帮您创建一条同名子任务记录该消耗。';
$lang->task->error->skipClose = '卡片%s 不是“已完成”或“已取消”状态,确定要关闭吗?';
$lang->task->error->consumed = '卡片%s工时不能小于0忽略该卡片工时的改动';
$lang->task->error->assignedTo = '当前状态的多人卡片不能指派给卡片团队外的成员。';
$lang->task->error->alreadyStarted = '此卡片已被启动,不能重复启动!';
$lang->task->error->alreadyConsumed = '当前选中的父卡片已有消耗。';
$lang->task->error->skipClose = '任务%s 不是“已完成”或“已取消”状态,确定要关闭吗?';
$lang->task->error->consumed = '任务%s工时不能小于0忽略该任务工时的改动';
$lang->task->error->assignedTo = '当前状态的多人任务不能指派给任务团队外的成员。';
$lang->task->error->alreadyStarted = '此任务已被启动,不能重复启动!';
$lang->task->error->alreadyConsumed = '当前选中的父任务已有消耗。';
/* Report. */
$lang->task->report->value = '卡片数';
$lang->task->report->value = '任务数';
$lang->task->report->charts['tasksPerExecution'] = '按' . $lang->executionCommon . '卡片数统计';
$lang->task->report->charts['tasksPerModule'] = '按模块卡片数统计';
$lang->task->report->charts['tasksPerType'] = '按卡片类型统计';
$lang->task->report->charts['tasksPerStatus'] = '按卡片状态统计';
$lang->task->report->charts['tasksPerExecution'] = '按' . $lang->executionCommon . '任务数统计';
$lang->task->report->charts['tasksPerModule'] = '按模块任务数统计';
$lang->task->report->charts['tasksPerType'] = '按任务类型统计';
$lang->task->report->charts['tasksPerStatus'] = '按任务状态统计';

View File

@@ -1,4 +1,7 @@
<?php
$lang->todo->typeList['task'] = '卡片';
$lang->todo->typeList['task'] = '任务';
$lang->effort->common = '日志';
unset($lang->todo->typeList['bug']);
unset($lang->todo->typeList['testtask']);

View File

@@ -44,7 +44,7 @@
<div class="col-4 text-center table-col">
<ul class="nav nav-primary">
<li class="active"><?php echo html::a($this->createLink('todo', 'calendar'), $lang->todo->common);?></li>
<?php if(common::hasPriv('effort', 'calendar')):?>
<?php if($this->config->edition != 'open' and common::hasPriv('effort', 'calendar')):?>
<li><?php echo html::a($this->createLink('effort', 'calendar'), $lang->effort->common);?></li>
<?php elseif(common::hasPriv('my', 'effort')):?>
<li><?php echo html::a($this->createLink('my', 'effort'), $lang->effort->common);?></li>
@@ -115,10 +115,10 @@
<ul class='todo-list'>
<?php $i = 1;?>
<?php foreach($todoList['task'] as $id => $todo):?>
<?php $projectID = isset($todoProjects[$type][$id]) ? $todoProjects[$type][$id] : 0;?>
<?php $projectID = isset($todoProjects['task'][$id]) ? $todoProjects['task'][$id] : 0;?>
<li data-index='<?php echo $i++;?>'>
<?php $class = common::hasPriv('todo', 'create') ? 'todo-item' : 'todoList'?>
<?php echo html::a($this->createLink('task', 'view', "id=$id", 'html', true), $todo, '', "class='iframe $class' data-id='{$id}' data-type='{$type}' data-title='{$todo}' title='{$todo}' data-width='70%'");?>
<?php echo html::a($this->createLink('task', 'view', "id=$id", 'html', true), $todo, '', "class='iframe $class' data-id='{$id}' data-type='task' data-title='{$todo}' title='{$todo}' data-width='70%'");?>
</li>
<?php endforeach;?>
</ul>

View File

@@ -0,0 +1,266 @@
<?php
/**
* The browse view file of tree module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package tree
* @version $Id: browse.html.php 4796 2013-06-06 02:21:59Z zhujinyonging@gmail.com $
* @link http://www.zentao.net
*/
?>
<?php include $this->app->getModuleRoot() . 'common/view/header.html.php';?>
<?php js::set('tab', $app->tab);?>
<style>
li.story-item > .tree-actions .tree-action[data-type=sort] {display: none;}
li.story-item > .tree-actions .tree-action[data-type=edit] {display: none;}
li.story-item > .tree-actions .tree-action[data-type=delete] {display: none;}
</style>
<div id="mainMenu" class="clearfix">
<div class="btn-toolbar pull-left">
<?php $backLink = $this->session->taskList ? $this->session->taskList : 'javascript:history.go(-1)';?>
<a href="<?php echo $backLink;?>" class="btn btn-secondary">
<i class="icon icon-back icon-sm"></i> <?php echo $lang->goback;?>
</a>
<div class="divider"></div>
<div class="page-title">
<span class='text' title='<?php echo $root->name;?>'><?php echo $lang->tree->common . $lang->colon . $root->name;?></span>
</div>
</div>
</div>
<div id="mainContent" class="main-row">
<div class="side-col col-4">
<div class='panel'>
<div class='panel-heading'>
<div class='panel-title'><?php echo $title;?></div>
</div>
<div class='panel-body'>
<ul id='modulesTree' data-name='tree-task'></ul>
</div>
</div>
</div>
<div class="main-col col-8">
<form id='childrenForm' method='post' target='hiddenwin' action='<?php echo $this->createLink('tree', 'manageChild', "root={$root->id}&viewType=task");?>'>
<div class='panel'>
<div class='panel-heading'>
<div class='panel-title'><?php echo $lang->tree->manageTaskChild;?></div>
</div>
<div class='panel-body'>
<table class='table table-form table-auto'>
<tr>
<td class="text-middle text-right with-padding">
<?php
echo "<span>" . html::a($this->createLink('tree', 'browsetask', "root={$root->id}&productID=$productID&viewType=task"), $root->name, '', "data-app='{$app->tab}'") . "<i class='icon icon-angle-right muted'></i></span>";
foreach($parentModules as $module)
{
echo "<span>" . html::a($this->createLink('tree', 'browsetask', "root={$root->id}&productID=$productID&moduleID=$module->id"), $module->name, '', "data-app='{$app->tab}'") . " <i class='icon icon-angle-right muted'></i></span>";
}
?>
</td>
<td>
<div id='sonModule'>
<?php $maxOrder = 0;?>
<?php if($newModule and !$productID):?>
<?php foreach($products as $product):?>
<div class="table-row row-module">
<div class="table-col col-module"><?php echo html::input("products[id$product->id]", $product->name, 'class=form-control disabled="true"')?></div>
</div>
<?php endforeach;?>
<?php endif;?>
<?php foreach($sons as $sonModule):?>
<?php
if($sonModule->order > $maxOrder) $maxOrder = $sonModule->order;
$disabled = $sonModule->type == 'task' ? '' : 'disabled';
?>
<div class='table-row row-module'>
<div class='table-col col-module'><?php echo html::input("modules[id$sonModule->id]", $sonModule->name, "class='form-control' placeholder='{$lang->tree->name}' $disabled")?></div>
<div class='table-col col-shorts'>
<?php
echo html::input("shorts[id$sonModule->id]", $sonModule->short, "class='form-control' placeholder='{$lang->tree->short}' $disabled");
echo html::hidden("order[id$sonModule->id]", $sonModule->order);
?>
</div>
<div class="table-col col-actions"> </div>
</div>
<?php endforeach;?>
<?php for($i = 0; $i < TREE::NEW_CHILD_COUNT ; $i ++):?>
<div class="table-row row-module row-module-new">
<div class='table-col col-module'><?php echo html::input("modules[]", '', "class='form-control' placeholder='{$lang->tree->name}'")?></div>
<div class='table-col col-shorts'><?php echo html::input("shorts[]", '', "class='form-control' placeholder='{$lang->tree->short}'")?></div>
<div class="table-col col-actions">
<button type="button" class="btn btn-link btn-icon btn-add" onclick="addItem(this)"><i class="icon icon-plus"></i></button>
<button type="button" class="btn btn-link btn-icon btn-delete" onclick="deleteItem(this)"><i class="icon icon-close"></i></button>
</div>
<?php echo html::hidden('branch[]', empty($module) ? 0 : $module->branch);?>
</div>
<?php endfor;?>
</div>
<div id="insertItemBox" class="template">
<div class="table-row row-module row-module-new">
<div class="table-col col-module"><?php echo html::input("modules[]", '', "class='form-control' placeholder='{$lang->tree->name}'");?></div>
<div class="table-col col-shorts"><?php echo html::input("shorts[]", '', "class='form-control' placeholder='{$lang->tree->short}'");?></div>
<div class="table-col col-actions">
<button type="button" class="btn btn-link btn-icon btn-add" onclick="addItem(this)"><i class="icon icon-plus"></i></button>
<button type="button" class="btn btn-link btn-icon btn-delete" onclick="deleteItem(this)"><i class="icon icon-close"></i></button>
</div>
<?php echo html::hidden('branch[]', empty($module) ? 0 : (int)$module->branch);?>
</div>
</div>
</td>
</tr>
<tr>
<td></td>
<td colspan='2' class="form-actions">
<?php
if($canBeChanged) echo html::submitButton();
echo html::a($backLink, $lang->goback, '', "class='btn btn-wide'");
echo html::hidden('parentModuleID', $currentModuleID);
echo html::hidden('maxOrder', $maxOrder);
?>
<input type='hidden' value='<?php echo $currentModuleID;?>' name='parentModuleID' />
</td>
</tr>
</table>
</div>
</div>
</form>
</div>
</div>
<script>
function getTree(data)
{
var tree = [];
$.each(data,function(index, value){
if(value.type === 'product')
{
for (var child of value.children) tree.push(child);
}
else
{
tree.push(value);
}
});
return tree;
}
$(function()
{
var data = $.parseJSON('<?php echo helper::jsonEncode4Parse($tree);?>');
data = getTree(data);
var options = {
initialState: 'preserve',
data: data,
itemCreator: function($li, item)
{
var $toggle = $('<span class="module-name" data-id="' + item.id + '">' + link + '</span>');
var title = (item.type === 'product' ? '<i class="icon icon-product text-muted"></i> ' : '') + item.name;
var link = item.id !== undefined ? ('<a data-app=' + tab + ' href="' + createLink('tree', 'browsetask', 'rootID=<?php echo $rootID ?>&viewType=task&moduleID={0}'.format(item.id)) + '">' + title + '</a>') : ('<span class="tree-toggle">' + title + '</span>');
var $toggle = $('<span class="module-name" data-id="' + item.id + '">' + link + '</span>');
if(item.type === 'task')
{
$toggle.append('&nbsp; <span class="text-muted">[T]</span>');
$li.addClass('task-item');
}
if(item.type === 'story') $li.addClass('story-item');
$li.append($toggle);
if(item.nodeType) $li.addClass('tree-item-' + item.nodeType);
return true;
},
actions:
{
sort:
{
title: '<?php echo $lang->tree->dragAndSort ?>',
template: '<a class="sort-handler" href="javascript:;"><i class="icon icon-move"></i></a>'
},
edit:
{
linkTemplate: '<?php echo helper::createLink('tree', 'edit', "moduleID={0}&type=task"); ?>',
title: '<?php echo $lang->tree->edit ?>',
template: '<a href="javascript:;"><i class="icon icon-edit"></i></a>'
},
"delete":
{
linkTemplate: '<?php echo helper::createLink('tree', 'delete', "rootID=$rootID&moduleID={0}"); ?>',
title: '<?php echo $lang->tree->delete ?>',
template: '<a href="javascript:;"><i class="icon icon-trash"></i></a>'
},
subModules:
{
linkTemplate: '<?php echo helper::createLink('tree', 'browsetask', "rootID=$rootID&viewType=task&moduleID={0}"); ?>',
title: '<?php echo $lang->tree->child ?>',
template: '<a href="javascript:;"><i class="icon icon-split"></i></a>'
}
},
action: function(event)
{
var action = event.action, $target = $(event.target), item = event.item;
if(action.type === 'edit')
{
new $.zui.ModalTrigger({
type: 'ajax',
url: action.linkTemplate.format(item.id),
keyboard: true
}).show();
}
else if(action.type === 'delete')
{
hiddenwin.location.href = action.linkTemplate.format(item.id);
}
else if(action.type === 'add')
{
window.location.href = action.linkTemplate.format(item.id);
}
else if(action.type === 'sort')
{
var orders = {};
$('#modulesTree').find('li:not(.tree-action-item)').each(function()
{
var $li = $(this);
var item = $li.data();
orders['orders[' + item.id + ']'] = $li.attr('data-order') || item.order;
});
$.post('<?php echo $this->createLink('tree', 'updateOrder', "root={$root->id}&viewType=task");?>', orders, function(data)
{
$('.main-col').load(location.href + ' .main-col .panel');
}).error(function()
{
bootbox.alert(lang.timeout);
});
}
else if(action.type === 'subModules')
{
window.location.href = action.linkTemplate.format(item.id, item.branch);
}
}
};
if(<?php echo (common::hasPriv('tree', 'updateorder') and $canBeChanged) ? 'false' : 'true' ?>) options.actions["sort"] = false;
if(<?php echo (common::hasPriv('tree', 'edit') and $canBeChanged) ? 'false' : 'true' ?>) options.actions["edit"] = false;
if(<?php echo (common::hasPriv('tree', 'delete') and $canBeChanged) ? 'false' : 'true' ?>) options.actions["delete"] = false;
if(<?php echo $canBeChanged ? 'false' : 'true' ?>) options.actions["subModules"] = false;
var $tree = $('#modulesTree').tree(options);
var tree = $tree.data('zui.tree');
if(!tree.store.time) tree.expand($tree.find('li:not(.tree-action-item)').first());
if(<?php echo $currentModuleID ?>)
{
var $currentLi = $tree.find('.module-name[data-id=' + <?php echo $currentModuleID ?> + ']').closest('li');
if($currentLi.length) tree.show($currentLi);
}
$tree.on('mouseenter', 'li:not(.tree-action-item)', function(e)
{
$('#modulesTree').find('li.hover').removeClass('hover');
$(this).addClass('hover');
e.stopPropagation();
});
$tree.find('[data-toggle="tooltip"]').tooltip();
});
</script>
<?php include $this->app->getModuleRoot() . 'common/view/footer.html.php';?>

View File

@@ -1,2 +1,2 @@
<?php
$lang->user->task = '卡片';
$lang->user->task = '任务';

View File

@@ -0,0 +1,106 @@
<?php
/**
* Get the project or execution in which the user participates..
*
* @param string $account
* @param string $type project|execution
* @param string $status
* @param string $orderBy
* @param object $pager
* @access public
* @return array
*/
public function getObjects($account, $type = 'execution', $status = 'all', $orderBy = 'id_desc', $pager = null)
{
$objectType = $type == 'execution' ? 'sprint,stage,kanban' : $type;
$myObjectsList = $this->dao->select('t1.*,t2.*')->from(TABLE_TEAM)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.root = t2.id')
->where('t1.type')->eq($type)
->andWhere('t2.type')->in($objectType)
->beginIF(strpos('doing|wait|suspended|closed', $status) !== false)->andWhere('status')->eq($status)->fi()
->beginIF($status == 'done')->andWhere('status')->in('done,closed')->fi()
->beginIF($status == 'undone')->andWhere('status')->notin('done,closed')->fi()
->beginIF($status == 'openedbyme')->andWhere('openedBy')->eq($account)->fi()
->beginIF($type == 'execution' and !$this->app->user->admin)->andWhere('t2.id')->in($this->app->user->view->sprints)->fi()
->beginIF($type == 'project' and !$this->app->user->admin)->andWhere('t2.id')->in($this->app->user->view->projects)->fi()
->andWhere('t1.account')->eq($account)
->andWhere('t2.deleted')->eq(0)
->andWhere('t2.vision')->eq($this->config->vision)
->orderBy("t2.$orderBy")
->page($pager)
->fetchAll('root');
$objectIdList = array();
$projectIdList = array();
foreach($myObjectsList as $object)
{
$objectIdList[] = $object->id;
$projectIdList[] = $object->project;
}
/* Get all tasks and compute totalConsumed, totalLeft, totalWait, progress according to them. */
$hours = array();
$emptyHour = array('totalConsumed' => 0, 'totalLeft' => 0, 'progress' => 0, 'waitTasks' => 0, 'assignedToMeTasks' => 0, 'doneTasks' => 0, 'taskTotal' => 0);
$searchField = $type == 'project' ? 'project' : 'execution';
$tasks = $this->dao->select('id, project, execution, consumed, `left`, status, assignedTo,finishedBy')
->from(TABLE_TASK)
->where('parent')->lt(1)
->andWhere($searchField)->in($objectIdList)->fi()
->andWhere('deleted')->eq(0)
->fetchGroup($searchField, 'id');
/* Compute totalEstimate, totalConsumed, totalLeft. */
foreach($tasks as $objectID => $objectTasks)
{
$hour = (object)$emptyHour;
$hour->taskTotal = count($objectTasks);
foreach($objectTasks as $task)
{
if($task->status == 'wait') $hour->waitTasks += 1;
if($task->finishedBy != '') $hour->doneTasks += 1;
if($task->status != 'cancel') $hour->totalConsumed += $task->consumed;
if($task->status != 'cancel' and $task->status != 'closed') $hour->totalLeft += $task->left;
if($task->assignedTo == $account) $hour->assignedToMeTasks += 1;
}
$hours[$objectID] = $hour;
}
/* Compute totalReal and progress. */
foreach($hours as $hour)
{
$hour->totalConsumed = round($hour->totalConsumed, 1);
$hour->totalLeft = round($hour->totalLeft, 1);
$hour->totalReal = $hour->totalConsumed + $hour->totalLeft;
$hour->progress = $hour->totalReal ? round($hour->totalConsumed / $hour->totalReal, 2) * 100 : 0;
}
$myObjects = array();
$projectList = $this->loadModel('project')->getByIdList($projectIdList);
foreach($myObjectsList as $object)
{
/* Judge whether the project or execution is delayed. */
if($object->status != 'done' and $object->status != 'closed' and $object->status != 'suspended')
{
$delay = helper::diffDate(helper::today(), $object->end);
if($delay > 0) $object->delay = $delay;
}
/* Process the hours. */
$object->progress = isset($hours[$object->id]) ? $hours[$object->id]->progress : 0;
$object->waitTasks = isset($hours[$object->id]) ? $hours[$object->id]->waitTasks : 0;
$object->doneTasks = isset($hours[$object->id]) ? $hours[$object->id]->doneTasks : 0;
$object->taskTotal = isset($hours[$object->id]) ? $hours[$object->id]->taskTotal : 0;
$object->totalConsumed = isset($hours[$object->id]) ? $hours[$object->id]->totalConsumed : 0;
$object->assignedToMeTasks = isset($hours[$object->id]) ? $hours[$object->id]->assignedToMeTasks : 0;
if($object->project)
{
$parentProject = zget($projectList, $object->project, '');
$object->projectName = $parentProject ? $parentProject->name : '';
}
$myObjects[$object->id] = $object;
}
return $myObjects;
}

View File

@@ -0,0 +1,63 @@
<?php
/**
* The project view file of dashboard module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Chunsheng Wang <chunsheng@cnezsoft.com>
* @package dashboard
* @version $Id: project.html.php 4129 2013-01-18 01:58:14Z wwccss $
* @link http://www.zentao.net
*/
?>
<?php include $this->app->getModuleRoot() . 'common/view/header.html.php';?>
<?php include $this->app->getModuleRoot() . 'common/view/tablesorter.html.php';?>
<?php include $this->app->getModuleRoot() . 'user/view/featurebar.html.php';?>
<div id='mainContent'>
<div class='main-table'>
<table class='table has-sort-head table-fixed'>
<?php $vars = "userID={$user->id}&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"; ?>
<thead>
<tr class='colhead'>
<th class='c-id'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th class="text-left"><?php common::printOrderLink('name', $orderBy, $vars, $lang->user->name);?></th>
<th class='c-status'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-user'> <?php echo $lang->team->role;?></th>
<th class='c-date'> <?php common::printOrderLink('begin', $orderBy, $vars, $lang->execution->begin);?></th>
<th class='c-date'> <?php common::printOrderLink('end', $orderBy, $vars, $lang->execution->end);?></th>
<th class='c-date'> <?php echo $lang->team->join;?></th>
<th class='c-hours'> <?php echo $lang->team->hours;?></th>
</tr>
</thead>
<tbody>
<?php foreach($executions as $execution):?>
<?php $executionLink = $this->createLink('execution', 'view', "executionID=$execution->id");?>
<?php if($this->config->vision == 'lite') $executionLink = $this->createLink('execution', 'kanban', "kanbanID=$execution->id");?>
<tr>
<td><?php echo html::a($executionLink, $execution->id);?></td>
<td>
<?php if(isset($config->maxVersion)):?>
<span class='project-type-label label label-info label-outline'><?php echo zget($lang->user->executionTypeList, $execution->type);?></span>
<?php endif;?>
<?php echo html::a($executionLink, $execution->name);?>
</td>
<?php if(isset($execution->delay)):?>
<td class='project-delay'><?php echo $lang->execution->delayed;?></td>
<?php else:?>
<td class='project-<?php echo $execution->status?>'><?php echo $this->processStatus('execution', $execution);?></td>
<?php endif;?>
<td><?php echo $execution->role;?></td>
<td><?php echo $execution->begin;?></td>
<td><?php echo $execution->end;?></td>
<td><?php echo $execution->join;?></td>
<td><?php echo $execution->hours;?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
<?php if($executions):?>
<div class="table-footer"><?php $pager->show('right', 'pagerjs');?></div>
<?php endif;?>
</div>
</div>
<?php include $this->app->getModuleRoot() . 'common/view/footer.html.php';?>

View File

@@ -696,6 +696,7 @@ class baseRouter
$account = isset($_SESSION['user']) ? $_SESSION['user']->account : '';
if($this->config->installed) $vision = $this->dbh->query("SELECT * FROM " . TABLE_CONFIG . " WHERE owner = '$account' AND `key` = 'vision' LIMIT 1")->fetch();
if(!empty($_SESSION['user']->visions) and empty($vision)) list($vision) = explode(',', $_SESSION['user']->visions);
$this->config->vision = $vision ? $vision->value : 'rnd';
}

View File

@@ -99,6 +99,7 @@ $lang->block->productName = $lang->productCommon . ' Name';
$lang->block->totalStory = 'The Total ' . $lang->SRCommon;
$lang->block->totalBug = 'The Total Bug';
$lang->block->totalRelease = 'Release The Number';
$lang->block->totalTask = 'The Total ' . $lang->task->common;
$lang->block->totalInvestment = 'Total investment';
$lang->block->totalPeople = 'Total number';

View File

@@ -99,6 +99,7 @@ $lang->block->productName = $lang->productCommon . '名称';
$lang->block->totalStory = '总' . $lang->SRCommon;
$lang->block->totalBug = '总Bug';
$lang->block->totalRelease = '发布次数';
$lang->block->totalTask = '总' . $lang->task->common;
$lang->block->totalInvestment = '总投入';
$lang->block->totalPeople = '总人数';

View File

@@ -10,6 +10,7 @@
* @link http://www.zentao.net
*/
?>
<?php $vision = $this->config->vision;?>
<?php if(empty($totalData)): ?>
<div class='empty-tip'><?php common::printLink('project', 'create', '', "<i class='icon-plus'></i> " . $lang->project->create, '', "class='btn btn-primary'")?></div>
<?php else:?>
@@ -22,7 +23,11 @@
<th></th>
<th><?php echo $lang->workingHour;?></th>
<th></th>
<?php if($vision == 'lite'): ?>
<th><?php echo $lang->block->taskCount;?></th>
<?php else:?>
<th><?php echo $lang->block->bugCount;?></th>
<?php endif;?>
<th></th>
</tr>
</thead>
@@ -34,8 +39,8 @@
<td><?php echo $totalData[$projectID]->teamCount ? html::a($this->createLink('project', 'team', 'projectID=' . $projectID), $totalData[$projectID]->teamCount) : 0;?></td>
<th><?php echo $lang->block->estimatedHours . ':';?></th>
<td><?php echo $totalData[$projectID]->estimate . $lang->execution->workHour;?></td>
<th><?php echo $lang->block->totalBug. ':';?></th>
<td><?php echo $totalData[$projectID]->allBugs;?></td>
<th><?php echo ($vision == 'lite' ? $lang->block->totalTask : $lang->block->totalBug) . ':';?></th>
<td><?php echo $vision == 'lite' ? $totalData[$projectID]->allTasks : $totalData[$projectID]->allBugs;?></td>
</tr>
<tr>
<th><?php echo $lang->block->done . ':';?></th>
@@ -44,8 +49,8 @@
<td></td>
<th><?php echo $lang->block->consumedHours . ':';?></th>
<td><?php echo $totalData[$projectID]->consumed . $lang->execution->workHour;?></td>
<th><?php echo $lang->bug->statusList['resolved'] . ':';?></th>
<td><?php echo $totalData[$projectID]->doneBugs;?></td>
<th><?php echo ($vision == 'lite' ? $lang->block->done : $lang->bug->statusList['resolved']) . ':';?></th>
<td><?php echo $vision == 'lite' ? $totalData[$projectID]->doneTasks : $totalData[$projectID]->doneBugs;?></td>
</tr>
<tr>
<th><?php echo $lang->block->left . ':';?></th>
@@ -54,8 +59,8 @@
<td></td>
<th></th>
<td></td>
<th><?php echo $lang->bug->unResolved . ':';?></th>
<td><?php echo $totalData[$projectID]->leftBugs;?></td>
<th><?php echo ($vision == 'lite' ? $lang->block->undone : $lang->bug->unResolved) . ':';?></th>
<td><?php echo $vision == 'lite' ? $totalData[$projectID]->leftTasks : $totalData[$projectID]->leftBugs;?></td>
</tr>
</tbody>

View File

@@ -320,7 +320,7 @@ $lang->exportTypeList['all'] = '全部记录';
$lang->exportTypeList['selected'] = '选中记录';
$lang->visionList = array();
$lang->visionList['rnd'] = '研发界面';
$lang->visionList['rnd'] = '研发综合界面';
$lang->visionList['lite'] = '迅捷界面';
$lang->createObjects['todo'] = '待办';

View File

@@ -1037,12 +1037,34 @@ function processMinusBtn()
}
}
/**
* Create task menu
* @returns {Object[]}
*/
function createTaskMenu(options)
{
var $card = options.$trigger.closest('.kanban-item');
var task = $card.data('item');
var items = [];
$.each(task.menus, function()
{
var item = {label: this.label, icon: this.icon, url: this.url, attrs: {'data-toggle': 'modal', 'data-type': 'iframe'}};
if(this.size) item.attrs['data-width'] = this.size;
items.push(item);
});
return items;
}
/* Define menu creators */
window.menuCreators =
{
lane: createLaneMenu,
column: createColumnMenu,
columnCreate: createColumnCreateMenu
columnCreate: createColumnCreateMenu,
task: createTaskMenu,
};
/**

View File

@@ -115,6 +115,7 @@
return link.prj ? 'project' : 'report';
}
}
if(moduleName === 'story' && vision === 'lite') return 'project'
if(moduleName === 'story' && methodLowerCase === 'zerocase')
{
return link.params.from == 'project' ? 'project' : 'qa';

View File

@@ -517,6 +517,7 @@ class installModel extends model
$admin->realname = $this->post->account;
$admin->password = md5($this->post->password);
$admin->gender = 'f';
$admin->visions = 'rnd,lite';
$this->dao->replace(TABLE_USER)->data($admin)->check('account', 'notempty')->exec();
}
}

View File

@@ -18,7 +18,7 @@
<h2><i class='icon-pencil'></i> <?php echo $lang->my->editProfile;?></h2>
</div>
<form method='post' target='hiddenwin' id='dataform'>
<table class='table table-form'>
<table class='table table-form'>
<caption><?php echo $lang->my->form->lblBasic;?></caption>
<tr>
<th class='w-90px'><?php echo $lang->user->realname;?></th>
@@ -83,12 +83,18 @@
</td>
</tr>
</table>
<?php echo html::select('visions[]', $this->user->getVisionList(), $user->visions, "class='form-control chosen' multiple");?>
<div class='text-center form-actions'><?php echo html::submitButton() . html::backButton();?></div>
</form>
<?php echo html::hidden('verifyRand', $rand);?>
</div>
<?php js::set('passwordStrengthList', $lang->user->passwordStrengthList)?>
<script>
$(function()
{
$('#visions_chosen').css('display', 'none')
});
function checkPassword(password)
{
$('#passwordStrength').html(password == '' ? '' : passwordStrengthList[computePasswordStrength(password)]);

View File

@@ -310,6 +310,10 @@ class projectModel extends model
$allBugs = $this->getTotalBugByProject($projectIdList, 'all');
$doneBugs = $this->getTotalBugByProject($projectIdList, 'resolved');
$leftTasks = $this->getTotalTaskByProject($projectIdList, 'undone');
$allTasks = $this->getTotalTaskByProject($projectIdList, 'all');
$doneTasks = $this->getTotalTaskByProject($projectIdList, 'done');
foreach($projects as $projectID => $project)
{
$project->consumed = isset($hours[$projectID]) ? (float)$hours[$projectID]->consumed : 0;
@@ -322,6 +326,9 @@ class projectModel extends model
$project->allStories = $allStories[$projectID];
$project->doneStories = $doneStories[$projectID];
$project->leftStories = $leftStories[$projectID];
$project->leftTasks = isset($leftTasks[$projectID]) ? $leftTasks[$projectID] : 0;
$project->allTasks = isset($allTasks[$projectID]) ? $allTasks[$projectID] : 0;
$project->doneTasks = isset($doneTasks[$projectID]) ? $doneTasks[$projectID] : 0;
if(is_float($project->consumed)) $project->consumed = round($project->consumed, 1);
if(is_float($project->estimate)) $project->estimate = round($project->estimate, 1);
@@ -553,6 +560,25 @@ class projectModel extends model
->fetchPairs('project');
}
/**
* Get associated tasks by project.
*
* @param array $projectIdList
* @param string $status all|done|undone
* @access public
* @return array
*/
public function getTotalTaskByProject($projectIdList, $status)
{
return $this->dao->select('project, count(*) as tasks')->from(TABLE_TASK)
->where('project')->in($projectIdList)
->andWhere('deleted')->eq(0)
->beginIF($status == 'done')->andWhere('status')->in('done,closed')->fi()
->beginIF($status == 'undone')->andWhere('status')->in('wait,pause,cancel')->fi()
->groupBy('project')
->fetchPairs('project');
}
/**
* Get branches by project id.
*
@@ -917,7 +943,7 @@ class projectModel extends model
$lib->main = '1';
$lib->acl = $project->acl != 'program' ? $project->acl : 'custom';
$lib->users = ',' . implode(',', array_filter($authorizedUsers)) . ',';
$lib->vision = zget($project, 'vision', 'common');
$lib->vision = zget($project, 'vision', 'rnd');
$this->dao->insert(TABLE_DOCLIB)->data($lib)->exec();
$this->updateProducts($projectID);
@@ -935,7 +961,7 @@ class projectModel extends model
$product->createdDate = helper::now();
$product->status = 'normal';
$product->createdVersion = $this->config->version;
$product->vision = zget($project, 'vision', 'common');
$product->vision = zget($project, 'vision', 'rnd');
$this->dao->insert(TABLE_PRODUCT)->data($product)->exec();
$productID = $this->dao->lastInsertId();

View File

@@ -2891,6 +2891,7 @@ class storyModel extends model
$stories = $sql->where('t1.deleted')->eq(0)
->andWhere('t1.type')->eq($storyType)
->andWhere('t1.vision')->eq($this->config->vision)
->beginIF($type != 'closedBy' and $this->app->moduleName == 'block')->andWhere('t1.status')->ne('closed')->fi()
->beginIF($type != 'all')
->beginIF($type == 'assignedTo')->andWhere('assignedTo')->eq($account)->fi()
@@ -3904,7 +3905,7 @@ class storyModel extends model
}
break;
case 'taskCount':
$tasksLink = helper::createLink('story', 'tasks', "storyID=$story->id");
$tasksLink = helper::createLink('story', 'tasks', "storyID=$story->id", '', 'class="iframe"');
$storyTasks[$story->id] > 0 ? print(html::a($tasksLink, $storyTasks[$story->id], '', 'class="iframe"')) : print(0);
break;
case 'bugCount':

View File

@@ -3,8 +3,8 @@ $config->user = new stdclass();
$config->user->create = new stdclass();
$config->user->edit = new stdclass();
$config->user->create->requiredFields = 'account,realname,password,password1,password2';
$config->user->edit->requiredFields = 'account,realname';
$config->user->create->requiredFields = 'account,realname,visions,password,password1,password2';
$config->user->edit->requiredFields = 'account,realname,visions';
$config->user->availableBatchCreateFields = 'dept,email,gender,commiter,join,skype,qq,dingding,weixin,mobile,slack,whatsapp,phone,address,zipcode';
$config->user->availableBatchEditFields = 'dept,email,commiter,skype,qq,dingding,weixin,mobile,slack,whatsapp,phone,address,zipcode';

View File

@@ -2,6 +2,7 @@ th.required:after {position: relative; right: 10px;}
td .passwordBox {border-left-width: 0px!important;}
.c-id {width: 40px;}
.c-dept {width: 150px;}
.c-dept {width: 120px;}
.c-realname {width: 130px;}
.c-visions {width: 130px;}
.c-role, .c-group, .c-commiter, .c-join, .c-contact {width: 120px;}

View File

@@ -1,2 +1,2 @@
.accountThWidth {width: 200px !important;}
.accountThWidth {width: 120px !important;}
.genderThWidth {width: 140px !important;}

View File

@@ -1,2 +1,2 @@
.accountThWidth {width: 180px !important;}
.accountThWidth {width: 120px !important;}
.genderThWidth {width: 100px !important;}

View File

@@ -1,2 +1,2 @@
.accountThWidth {width: 180px !important;}
.accountThWidth {width: 120px !important;}
.genderThWidth {width: 100px !important;}

View File

@@ -0,0 +1 @@
.checkbox-primary {display:inline-block; padding-right:10px;}

View File

@@ -42,6 +42,7 @@ $lang->user->address = '通讯地址';
$lang->user->zipcode = '邮编';
$lang->user->join = '入职日期';
$lang->user->visits = '访问次数';
$lang->user->visions = '版本类型';
$lang->user->ip = '最后IP';
$lang->user->last = '最后登录';
$lang->user->ranzhi = 'ZDOO帐号';

View File

@@ -302,9 +302,11 @@ class userModel extends model
->setDefault('join', '0000-00-00')
->setDefault('type', 'inside')
->setDefault('company', 0)
->setDefault('visions', '')
->setIF($this->post->password1 != false, 'password', substr($this->post->password1, 0, 32))
->setIF($this->post->password1 == false, 'password', '')
->setIF($this->post->email != false, 'email', trim($this->post->email))
->join('visions', ',')
->remove('new, group, password1, password2, verifyPassword, passwordStrength')
->get();
@@ -392,7 +394,8 @@ class userModel extends model
if($users->email[$i] and !validater::checkEmail($users->email[$i])) die(js::error(sprintf($this->lang->user->error->mail, $i + 1)));
$users->password[$i] = (isset($prev['password']) and $users->ditto[$i] == 'on' and !$this->post->password[$i]) ? $prev['password'] : $this->post->password[$i];
if(!validater::checkReg($users->password[$i], '|(.){6,}|')) die(js::error(sprintf($this->lang->user->error->password, $i + 1)));
$role = $users->role[$i] == 'ditto' ? (isset($prev['role']) ? $prev['role'] : '') : $users->role[$i];
$role = $users->role[$i] == 'ditto' ? (isset($prev['role']) ? $prev['role'] : '') : $users->role[$i];
$visions = in_array('ditto', $users->visions[$i]) ? (isset($prev['visions']) ? $prev['visions'] : array()) : $users->visions[$i];
/* Check weak and common weak password. */
if(isset($this->config->safe->mode) and $this->computePasswordStrength($users->password[$i]) < $this->config->safe->mode) die(js::error(sprintf($this->lang->user->error->weakPassword, $i + 1)));
@@ -424,6 +427,7 @@ class userModel extends model
$data[$i]->phone = $users->phone[$i];
$data[$i]->address = $users->address[$i];
$data[$i]->zipcode = $users->zipcode[$i];
$data[$i]->visions = join(',', $visions);
/* Check required fields. */
foreach(explode(',', $this->config->user->create->requiredFields) as $field)
@@ -454,6 +458,7 @@ class userModel extends model
$prev['dept'] = $data[$i]->dept;
$prev['role'] = $data[$i]->role;
$prev['group'] = $data[$i]->group;
$prev['visions'] = $users->visions[$i];
$prev['password'] = $users->password[$i];
}
}
@@ -509,8 +514,10 @@ class userModel extends model
$user = fixer::input('post')
->setDefault('join', '0000-00-00')
->setDefault('company', 0)
->setDefault('visions', '')
->setIF($this->post->password1 != false, 'password', substr($this->post->password1, 0, 32))
->setIF($this->post->email != false, 'email', trim($this->post->email))
->join('visions', ',')
->remove('new, password1, password2, groups,verifyPassword, passwordStrength')
->get();
@@ -552,6 +559,7 @@ class userModel extends model
->checkIF($this->post->mobile != '', 'mobile', 'mobile')
->where('id')->eq((int)$userID)
->exec();
if(dao::isError()) return false;
/* If account changed, update the privilege. */
if($this->post->account != $oldUser->account)
@@ -654,6 +662,7 @@ class userModel extends model
$users[$id]['phone'] = $data->phone[$id];
$users[$id]['address'] = $data->address[$id];
$users[$id]['zipcode'] = $data->zipcode[$id];
$users[$id]['visions'] = !empty($data->visions[$id]) ? join(',', $data->visions[$id]) : '';
$users[$id]['dept'] = $data->dept[$id] == 'ditto' ? (isset($prev['dept']) ? $prev['dept'] : 0) : $data->dept[$id];
$users[$id]['role'] = $data->role[$id] == 'ditto' ? (isset($prev['role']) ? $prev['role'] : 0) : $data->role[$id];
@@ -2656,4 +2665,21 @@ class userModel extends model
}
return $userDetails;
}
/**
* Get vision list.
*
* @access public
* @return array
*/
public function getVisionList()
{
$visionList = $this->lang->visionList;
foreach($visionList as $visionKey => $visionName)
{
if(strpos($this->config->visions, ",{$visionKey},") === false) unset($visionList[$visionKey]);
}
return $visionList;
}
}

View File

@@ -49,6 +49,7 @@
<th class='c-dept<?php echo zget($visibleFields, 'dept', ' hidden') . zget($requiredFields, 'dept', '', ' required');?>'> <?php echo $lang->user->dept;?></th>
<th class='accountThWidth required'><?php echo $lang->user->account;?></th>
<th class='c-realname required'><?php echo $lang->user->realname;?></th>
<th class='c-visions required'><?php echo $lang->user->visions;?></th>
<th class='c-role<?php echo zget($requiredFields, 'role', '', ' required')?>'><?php echo $lang->user->role;?></th>
<th class='c-group'><?php echo $lang->user->group;?></th>
<th class='<?php echo zget($visibleFields, 'email', "$minWidth hidden", $minWidth) . zget($requiredFields, 'email', '', ' required')?>'><?php echo $lang->user->email;?></th>
@@ -71,13 +72,15 @@
<tbody>
<?php $depts = $depts + array('ditto' => $lang->user->ditto)?>
<?php $lang->user->roleList = $lang->user->roleList + array('ditto' => $lang->user->ditto)?>
<?php $groupList = $groupList + array('ditto' => $lang->user->ditto)?>
<?php $groupList = $groupList + array('ditto' => $lang->user->ditto);?>
<?php $visionList = $this->user->getVisionList() + array('ditto' => $lang->user->ditto);?>
<?php for($i = 0; $i < $config->user->batchCreate; $i++):?>
<tr class='text-center'>
<td><?php echo $i+1;?></td>
<td><?php echo $i + 1;?></td>
<td class='text-left<?php echo zget($visibleFields, 'dept', ' hidden')?>' style='overflow:visible'><?php echo html::select("dept[$i]", $depts, $i > 0 ? 'ditto' : $deptID, "class='form-control chosen'");?></td>
<td><?php echo html::input("account[$i]", '', "class='form-control account_$i' onchange='changeEmail($i)'");?></td>
<td><?php echo html::input("realname[$i]", '', "class='form-control'");?></td>
<td class='text-left'><?php echo html::select("visions[$i][]", $visionList, $i > 0 ? 'ditto' : '', "class='form-control chosen' multiple");?></td>
<td><?php echo html::select("role[$i]", $lang->user->roleList, $i > 0 ? 'ditto' : '', "class='form-control' onchange='changeGroup(this.value, $i)'");?></td>
<td class='text-left' style='overflow:visible'><?php echo html::select("group[$i]", $groupList, $i > 0 ? 'ditto' : '', "class='form-control chosen'");?></td>
<td <?php echo zget($visibleFields, 'email', "class='hidden'")?>><?php echo html::input("email[$i]", '', "class='form-control email_$i' onchange='setDefaultEmail($i)'");?></td>

View File

@@ -44,10 +44,11 @@
<table class="table table-form">
<thead>
<tr class='text-center'>
<th class='w-30px'><?php echo $lang->idAB;?></th>
<th class='w-30px'><?php echo $lang->idAB;?></th>
<th class='w-150px<?php echo zget($visibleFields, 'dept', ' hidden')?>'> <?php echo $lang->user->dept;?></th>
<th class='<?php echo $minWidth?> required'><?php echo $lang->user->account;?></th>
<th class='<?php echo $minWidth?> required'><?php echo $lang->user->realname;?></th>
<th class='w-130px'><?php echo $lang->user->visions;?></th>
<th class='w-120px'><?php echo $lang->user->role;?></th>
<th class='w-120px'><?php echo $lang->user->type;?></th>
<th class='<?php echo $minWidth . zget($visibleFields, 'commiter', ' hidden')?>'><?php echo $lang->user->commiter;?></th>
@@ -71,8 +72,8 @@
<?php $first = true;?>
<?php foreach($users as $user):?>
<?php
$dept = ($first and empty($user->dept)) ? 0 : (empty($user->dept) ? 'ditto' : $user->dept);
$role = ($first and empty($user->role)) ? 0 : (empty($user->role) ? 'ditto' : $user->role);
$dept = ($first and empty($user->dept)) ? 0 : (empty($user->dept) ? 'ditto' : $user->dept);
$role = ($first and empty($user->role)) ? 0 : (empty($user->role) ? 'ditto' : $user->role);
$type = empty($user->type) ? 'inside' : $user->type;
$first = false;
?>
@@ -81,6 +82,8 @@
<td class='text-left<?php echo zget($visibleFields, 'dept', ' hidden')?>' style='overflow:visible'><?php echo html::select("dept[$user->id]", $depts, $dept, "class='form-control chosen'");?></td>
<td><?php echo html::input("account[$user->id]", $user->account, "class='form-control'");?></td>
<td><?php echo html::input("realname[$user->id]", $user->realname, "class='form-control'");?></td>
<?php $visionList = $this->user->getVisionList();?>
<td class='text-left'><?php echo html::select("visions[$user->id][]", $visionList, $user->visions, "class='form-control chosen' multiple");?></td>
<td><?php echo html::select("role[$user->id]", $lang->user->roleList, $role, "class='form-control'");?></td>
<td><?php echo html::select("type[$user->id]", $lang->user->typeList, $type, "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'commiter', 'hidden')?>'><?php echo html::input("commiter[$user->id]", $user->commiter, "class='form-control'");?></td>

View File

@@ -60,6 +60,11 @@
<th><?php echo $lang->user->password2;?></th>
<td><?php echo html::password('password2', '', "class='form-control'");?></td>
</tr>
<tr>
<th><?php echo $lang->user->visions;?></th>
<?php $visionList = $this->user->getVisionList();?>
<td><?php echo html::checkbox('visions', $visionList, key($visionList), "class='form-control'");?></td>
</tr>
<tr>
<th><?php echo $lang->user->realname;?></th>
<td><?php echo html::input('realname', '', "class='form-control'");?></td>

View File

@@ -81,6 +81,9 @@
<tr>
<th><?php echo $lang->user->commiter;?></th>
<td><?php echo html::input('commiter', $user->commiter, "class='form-control'");?></td>
<th><?php echo $lang->user->visions;?></th>
<?php $visionList = $this->user->getVisionList();?>
<td><?php echo html::select('visions[]', $visionList, $user->visions, "class='form-control chosen' multiple");?></td>
</tr>
</table>
<table align='center' class='table table-form'>

View File

@@ -43,9 +43,13 @@
<tr class='colhead'>
<th class='w-id'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th class='w-pri'> <?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<?php if($this->config->vision == 'lite'):?>
<th class='w-200px'><?php common::printOrderLink('product', $orderBy, $vars, $lang->story->project);?></th>
<?php else:?>
<th class='w-200px'><?php common::printOrderLink('product', $orderBy, $vars, $lang->story->product);?></th>
<?php endif;?>
<th> <?php common::printOrderLink('title', $orderBy, $vars, $lang->story->title);?></th>
<?php if($storyType != 'requirement'):?>
<?php if($storyType != 'requirement' and $this->config->vision != 'lite'):?>
<th class='w-150px'><?php common::printOrderLink('plan', $orderBy, $vars, $lang->story->plan);?></th>
<?php endif;?>
<th class='w-90px'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
@@ -56,13 +60,13 @@
</thead>
<tbody>
<?php foreach($stories as $key => $story):?>
<?php $storyLink = $this->createLink('story', 'view', "id=$story->id");?>
<?php $storyLink = $this->createLink('story', 'view', "id=$story->id");?>
<tr class='text-left'>
<td><?php echo html::a($storyLink, sprintf('%03d', $story->id));?></td>
<td><span class='<?php echo 'pri' . zget($lang->story->priList, $story->pri, $story->pri);?>'><?php echo zget($lang->story->priList, $story->pri, $story->pri);?></span></td>
<td><?php echo $story->productTitle;?></td>
<td class='text-left nobr'><?php echo html::a($storyLink, $story->title);?></td>
<?php if($storyType != 'requirement'):?>
<?php if($storyType != 'requirement' and $this->config->vision != 'lite'):?>
<td title='<?php echo $story->planTitle;?>'><?php echo $story->planTitle;?></td>
<?php endif;?>
<td><?php echo zget($users, $story->openedBy);?></td>