* Add execution kanban list.
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
CREATE TABLE `zt_kanbancardgroup` (
|
||||
`id` int(8) NOT NULL AUTO_INCREMENT,
|
||||
`kanban` mediumint(8) NOT NULL,
|
||||
`objectType` char(30) NOT NULL,
|
||||
`objectID` mediumint(8) NOT NULL,
|
||||
`lane` mediumint(8) NOT NULL,
|
||||
`column` mediumint(8) NOT NULL,
|
||||
`order` mediumint(8) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `card_group` (`kanban`,`objectType`,`objectID`,`lane`,`column`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
|
||||
ALTER TABLE `zt_kanban` ADD `displayCards` smallint(6) NOT NULL AFTER `order`;
|
||||
ALTER TABLE `zt_kanbancard` DROP COLUMN `lane`;
|
||||
ALTER TABLE `zt_kanbancard` DROP COLUMN `column`;
|
||||
@@ -677,6 +677,7 @@ CREATE TABLE `zt_kanban` (
|
||||
`archived` enum('0', '1') NOT NULL DEFAULT '0',
|
||||
`status` enum('active','closed') NOT NULL default 'active',
|
||||
`order` mediumint(8) NOT NULL DEFAULT '0',
|
||||
`displayCards` smallint(6) NOT NULL,
|
||||
`createdBy` char(30) NOT NULL,
|
||||
`createdDate` datetime NOT NULL,
|
||||
`lastEditedBy` char(30) NOT NULL,
|
||||
@@ -731,6 +732,18 @@ CREATE TABLE `zt_kanbancard` (
|
||||
`deleted` enum('0', '1') NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_kanbancardgroup`;
|
||||
CREATE TABLE `zt_kanbancardgroup` (
|
||||
`id` int(8) NOT NULL AUTO_INCREMENT,
|
||||
`kanban` mediumint(8) NOT NULL,
|
||||
`objectType` char(30) NOT NULL,
|
||||
`objectID` mediumint(8) NOT NULL,
|
||||
`lane` mediumint(8) NOT NULL,
|
||||
`column` mediumint(8) NOT NULL,
|
||||
`order` mediumint(8) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `card_group` (`kanban`,`objectType`,`objectID`,`lane`,`column`)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
|
||||
-- DROP TABLE IF EXISTS `zt_kanbangroup`;
|
||||
CREATE TABLE `zt_kanbangroup` (
|
||||
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
|
||||
|
||||
@@ -289,6 +289,11 @@ $lang->waterfall->menu->design['subMenu']->dbds = array('link' => "{$lang->d
|
||||
$lang->waterfall->menu->design['subMenu']->ads = array('link' => "{$lang->design->ADS}|design|browse|projectID=%s&productID=0&browseType=ADS");
|
||||
$lang->waterfall->menu->design['subMenu']->bysearch = array('link' => '<a href="javascript:;" class="querybox-toggle"><i class="icon-search icon"></i> ' . $lang->searchAB . '</a>');
|
||||
|
||||
/* Kanban project menu. */
|
||||
$lang->kanban->menu = new stdclass();
|
||||
$lang->kanban->menuOrder = array();
|
||||
$lang->kanban->dividerMenu = '';
|
||||
|
||||
/* Execution menu. */
|
||||
$lang->execution->homeMenu = new stdclass();
|
||||
$lang->execution->homeMenu->all = array('link' => "{$lang->execution->all}|execution|all|", 'alias' => 'batchedit');
|
||||
|
||||
@@ -528,7 +528,7 @@ class commonModel extends model
|
||||
$attr = "class='iframe' data-width='650px'";
|
||||
break;
|
||||
case 'project':
|
||||
if(isset($config->maxVersion) and!defined('TUTORIAL'))
|
||||
if(!defined('TUTORIAL'))
|
||||
{
|
||||
$params = "programID=0©ProjectID=0&extra=from=global";
|
||||
$createMethod = 'createGuide';
|
||||
|
||||
@@ -2478,6 +2478,23 @@ class executionModel extends model
|
||||
->fetchAll('account');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get members by execution id list.
|
||||
*
|
||||
* @param array $executionIdList
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function getMembersByIdList($executionIdList)
|
||||
{
|
||||
return $this->dao->select("t1.root, t1.account, t2.realname")->from(TABLE_TEAM)->alias('t1')
|
||||
->leftJoin(TABLE_USER)->alias('t2')->on('t1.account = t2.account')
|
||||
->where('t1.root')->in($executionIdList)
|
||||
->andWhere('t1.type')->eq('execution')
|
||||
->andWhere('t2.deleted')->eq('0')
|
||||
->fetchGroup('root');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the skip members of the team.
|
||||
*
|
||||
|
||||
@@ -222,10 +222,11 @@ class project extends control
|
||||
* Project index view.
|
||||
*
|
||||
* @param int $projectID
|
||||
* @param string $browseType
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function index($projectID = 0)
|
||||
public function index($projectID = 0, $browseType = 'all')
|
||||
{
|
||||
$projectID = $this->project->saveState($projectID, $this->project->getPairsByProgram());
|
||||
|
||||
@@ -240,6 +241,15 @@ class project extends control
|
||||
if(!$projectID) $this->locate($this->createLink('project', 'browse'));
|
||||
setCookie("lastProject", $projectID, $this->config->cookieLife, $this->config->webRoot, '', false, true);
|
||||
|
||||
if($project->model == 'kanban')
|
||||
{
|
||||
$kanbanList = $this->loadModel('execution')->getList($projectID, 'all', $browseType);
|
||||
$this->view->kanbanList = $kanbanList;
|
||||
$this->view->browseType = $browseType;
|
||||
$this->view->memberGroup = $this->execution->getMembersByIdList(array_keys($kanbanList));
|
||||
$this->view->usersAvatar = $this->loadModel('user')->getAvatarPairs();
|
||||
}
|
||||
|
||||
$this->view->title = $this->lang->project->common . $this->lang->colon . $this->lang->project->index;
|
||||
$this->view->position[] = $this->lang->project->index;
|
||||
$this->view->project = $project;
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#cards > .col {width: 25% !important;}
|
||||
#cards .panel {margin: 0 0; border: 1px solid #DCDCDC; border-radius: 4px; box-shadow: none; cursor: pointer; height: 160px; margin-bottom: 5px;}
|
||||
#cards .panel:hover {border-color: #006AF1; box-shadow: 0 0 10px 0 rgba(0,0,100,.25);}
|
||||
#cards .panel-heading {padding: 4px 2px 10px 16px;}
|
||||
#cards .kanban-name {overflow: hidden; white-space:nowrap; width: 88%; float: left; padding-top: 8px;}
|
||||
#cards .panel .label-closed {background: #AAA !important; color: #FFF; margin-top:-1px !important;}
|
||||
#cards .kanban-actions {float: right; visibility: hidden;}
|
||||
#cards .kanban-actions .dropdown-menu.pull-right {top:31px; right: -84px; left: auto;}
|
||||
#cards .kanban-actions .dropdown-menu.pull-left {top:31px; right:-1px; left: auto;}
|
||||
#cards .panel .label-closed {background: #AAA !important; color: #FFF; margin-top:-6px;}
|
||||
#cards .panel-body {padding: 0 16px 16px;}
|
||||
#cards .kanban-desc {color: #838a9d; word-break:break-all; height: 70px; overflow: hidden; display: -webkit-box; float:left;}
|
||||
#cards .kanban-footer {position: absolute; bottom: 10px; right: 10px; left: 15px;}
|
||||
#cards .kanban-members {float: left; height: 24px; line-height: 24px;}
|
||||
#cards .kanban-members > div {display: inline-block; height: 24px;}
|
||||
#cards .kanban-members > div + div {margin-left: -5px;}
|
||||
#cards .kanban-members > div > .avatar {display: inline-block; width: 24px; height: 24px; line-height: 24px; margin-right: 1px;}
|
||||
#cards .kanban-members > span {display: inline-block; color: transparent; width: 2px; height: 2px; background-color: #8990a2; position: relative; border-radius: 50%; top: 3px; margin: 0 3px;}
|
||||
#cards .kanban-members > span:before,
|
||||
#cards .kanban-members > span:after {content: ''; display: block; position: absolute; width: 2px; height: 2px; background-color: #8990a2; top: 0; border-radius: 50%}
|
||||
#cards .kanban-members > span:before {left: -4px;}
|
||||
#cards .kanban-members > span:after {right: -4px;}
|
||||
#cards .kanban-members-total {display: inline-block; margin-left: 6px; position: relative; top: 3px}
|
||||
#cards .kanbanAcl {position: absolute; right: 0px; bottom: 2px; color: #838a9d;}
|
||||
@@ -155,6 +155,8 @@ $lang->project->etc = " , etc";
|
||||
$lang->project->product = 'Product';
|
||||
$lang->project->branch = 'Branch';
|
||||
$lang->project->plan = 'Plan';
|
||||
$lang->project->kanban = 'Kanban';
|
||||
$lang->project->createKanban = 'Create Kanban';
|
||||
|
||||
/* Project Kanban. */
|
||||
$lang->project->typeList = array();
|
||||
@@ -220,6 +222,7 @@ $lang->project->currencySymbol['SGD'] = 'S$';
|
||||
|
||||
$lang->project->modelList['scrum'] = "Scrum";
|
||||
$lang->project->modelList['waterfall'] = "CMMI";
|
||||
$lang->project->modelList['kanban'] = "Kanban";
|
||||
|
||||
$lang->project->featureBar['all'] = 'All';
|
||||
$lang->project->featureBar['doing'] = 'Going';
|
||||
@@ -252,6 +255,10 @@ $lang->project->endList[186] = 'Half yearly';
|
||||
$lang->project->endList[365] = 'One year';
|
||||
$lang->project->endList[999] = 'Longtime';
|
||||
|
||||
$lang->project->scrumTitle = 'Agile Development Management';
|
||||
$lang->project->waterfallTitle = 'Waterfall Project Management';
|
||||
$lang->project->kanbanTitle = 'Kanban Project Management';
|
||||
|
||||
$lang->project->empty = 'No project.';
|
||||
$lang->project->nextStep = 'Next step';
|
||||
$lang->project->hoursUnit = '%s hours';
|
||||
@@ -260,7 +267,6 @@ $lang->project->lastIteration = "Recent {$lang->executionCommon}";
|
||||
$lang->project->ongoingStage = 'Ongoing stage';
|
||||
$lang->project->scrum = 'Scrum';
|
||||
$lang->project->waterfall = 'Waterfall';
|
||||
$lang->project->waterfallTitle = 'Waterfall Project Management';
|
||||
$lang->project->cannotCreateChild = 'It is not empty, so you cannot add a child. You can add a parent for it, and then create a child.';
|
||||
$lang->project->confirmDelete = "Do you want to delete [%s]?";
|
||||
$lang->project->emptyPM = 'No manager';
|
||||
@@ -278,7 +284,6 @@ $lang->project->programTitle['end'] = 'End-level project only';
|
||||
|
||||
$lang->project->accessDenied = 'Access denied to this project';
|
||||
$lang->project->chooseProgramType = 'Select management type';
|
||||
$lang->project->scrumTitle = 'Agile Development Management';
|
||||
$lang->project->cannotCreateChild = 'The project has contents, so you cannot add a child project. You can create a parent project for this one and then add a child project for the parent project.';
|
||||
$lang->project->hasChildren = 'This project has a child project, so it cannot be deleted.';
|
||||
$lang->project->confirmDelete = 'Do you want to delete this project?';
|
||||
|
||||
@@ -155,6 +155,8 @@ $lang->project->etc = "等";
|
||||
$lang->project->product = '所属产品';
|
||||
$lang->project->branch = '所属分支';
|
||||
$lang->project->plan = '所属计划';
|
||||
$lang->project->createKanban = '创建看板';
|
||||
$lang->project->kanban = '看板';
|
||||
|
||||
/* Project Kanban. */
|
||||
$lang->project->typeList = array();
|
||||
@@ -220,6 +222,7 @@ $lang->project->currencySymbol['SGD'] = 'S$';
|
||||
|
||||
$lang->project->modelList['scrum'] = "Scrum";
|
||||
$lang->project->modelList['waterfall'] = "瀑布";
|
||||
$lang->project->modelList['kanban'] = "看板";
|
||||
|
||||
$lang->project->featureBar['all'] = '所有';
|
||||
$lang->project->featureBar['doing'] = '进行中';
|
||||
@@ -252,6 +255,10 @@ $lang->project->endList[186] = '半年';
|
||||
$lang->project->endList[365] = '一年';
|
||||
$lang->project->endList[999] = '长期';
|
||||
|
||||
$lang->project->scrumTitle = '敏捷开发全流程项目管理';
|
||||
$lang->project->waterfallTitle = '瀑布式项目管理';
|
||||
$lang->project->kanbanTitle = '专业研发看板项目管理';
|
||||
|
||||
$lang->project->empty = '暂时没有项目';
|
||||
$lang->project->nextStep = '下一步';
|
||||
$lang->project->hoursUnit = '%s 工时';
|
||||
@@ -260,7 +267,6 @@ $lang->project->lastIteration = "近期{$lang->executionCommon}";
|
||||
$lang->project->ongoingStage = '进行中的阶段';
|
||||
$lang->project->scrum = 'Scrum';
|
||||
$lang->project->waterfall = '瀑布';
|
||||
$lang->project->waterfallTitle = '瀑布式项目管理';
|
||||
$lang->project->cannotCreateChild = '该项目已经有实际的内容,无法直接添加子项目。您可以为当前项目创建一个父项目,然后在新的父项目下面添加子项目。';
|
||||
$lang->project->confirmDelete = "您确定要删除吗?";
|
||||
$lang->project->emptyPM = '暂无';
|
||||
@@ -278,7 +284,6 @@ $lang->project->programTitle['end'] = '只显示最后一级项目集';
|
||||
|
||||
$lang->project->accessDenied = '您无权访问该项目!';
|
||||
$lang->project->chooseProgramType = '选择项目管理方式';
|
||||
$lang->project->scrumTitle = '敏捷开发全流程项目管理';
|
||||
$lang->project->cannotCreateChild = '该项目已经有实际的内容,无法直接添加子项目。您可以为当前项目创建一个父项目,然后在新的父项目下面添加子项目。';
|
||||
$lang->project->hasChildren = '该项目有子项目存在,不能删除。';
|
||||
$lang->project->confirmDelete = "您确定删除项目[%s]吗?";
|
||||
|
||||
@@ -632,7 +632,7 @@ class projectModel extends model
|
||||
/**
|
||||
* Get project pairs by model and project.
|
||||
*
|
||||
* @param string $model all|scrum|waterfall
|
||||
* @param string $model all|scrum|waterfall|kanban
|
||||
* @param int $programID
|
||||
* @access public
|
||||
* @return array
|
||||
@@ -1776,7 +1776,7 @@ class projectModel extends model
|
||||
$type = 'project';
|
||||
if($this->config->systemMode == 'new')
|
||||
{
|
||||
if($project->type == 'sprint' or $project->type == 'stage') $type = 'execution';
|
||||
if($project->type == 'sprint' or $project->type == 'stage' or $project->type == 'kanban') $type = 'execution';
|
||||
}
|
||||
|
||||
$members = $this->dao->select("t1.account, if(t2.deleted='0', t2.realname, t1.account) as realname")->from(TABLE_TEAM)->alias('t1')
|
||||
|
||||
@@ -72,9 +72,12 @@ foreach($projects as $programID => $programProjects)
|
||||
|
||||
foreach($programProjects as $index => $project)
|
||||
{
|
||||
$selected = $project->id == $projectID ? 'selected' : '';
|
||||
$link = helper::createLink('project', 'index', "projectID=%s", '', '', $project->id);
|
||||
$projectName = $project->model == 'scrum' ? '<i class="icon icon-sprint"></i> ' . $project->name : '<i class="icon icon-waterfall"></i> ' . $project->name;
|
||||
$selected = $project->id == $projectID ? 'selected' : '';
|
||||
$link = helper::createLink('project', 'index', "projectID=%s", '', '', $project->id);
|
||||
$icon = '<i class="icon icon-sprint"></i> ';
|
||||
|
||||
if($project->model != 'scrum') $icon = "<i class='icon icon-{$project->model}'></i> ";
|
||||
$projectName = $icon . $project->name;
|
||||
|
||||
if($project->status != 'done' and $project->status != 'closed' and $project->PM == $this->app->user->account)
|
||||
{
|
||||
|
||||
@@ -15,20 +15,27 @@
|
||||
<button class="close" data-dismiss="modal">x</button>
|
||||
<h2 class='text-center'><?php echo $lang->project->chooseProgramType; ?></h2>
|
||||
<div class='row'>
|
||||
<div class='col-xs-6'>
|
||||
<div class='col-xs-4'>
|
||||
<div class='project-type text-center'>
|
||||
<?php echo html::a($this->createLink("project", "create", "model=scrum&programID=$programID©ProjectID=0&extra=productID=$productID,branchID=$branchID"), "<img class='project-type-img' data-type='scrum' src='{$config->webRoot}theme/default/images/main/scrum.png'>", '', "data-app='project' class='createButton'")?>
|
||||
<h3><?php echo $lang->project->scrum; ?></h3>
|
||||
<p><?php echo $lang->project->scrumTitle; ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-6'>
|
||||
<div class='col-xs-4'>
|
||||
<div class='project-type text-center'>
|
||||
<?php echo html::a($this->createLink("project", "create", "model=waterfall&programID=$programID©ProjectID=0&extra=productID=$productID,branchID=$branchID"), "<img class='project-type-img' data-type='waterfall' src='{$config->webRoot}theme/default/images/main/waterfall.png'>", '', "data-app='project' class='createButton'")?>
|
||||
<h3><?php echo $lang->project->waterfall; ?></h3>
|
||||
<p><?php echo $lang->project->waterfallTitle; ?></p>
|
||||
</div>
|
||||
</div>
|
||||
<div class='col-xs-4'>
|
||||
<div class='project-type text-center'>
|
||||
<?php echo html::a($this->createLink("project", "create", "model=kanban&programID=$programID©ProjectID=0&extra=productID=$productID,branchID=$branchID"), "<img class='project-type-img' data-type='kanban' src='{$config->webRoot}theme/default/images/main/kanban.png'>", '', "data-app='project' class='createButton'")?>
|
||||
<h3><?php echo $lang->project->kanban;?></h3>
|
||||
<p><?php echo $lang->project->kanbanTitle;?></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -10,5 +10,74 @@
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php if($project->model != 'kanban'):?>
|
||||
<?php echo $this->fetch('block', 'dashboard', "module=project&type={$project->model}&projectID={$project->id}");?>
|
||||
<?php else:?>
|
||||
<div class='clearfix' id='mainMenu'>
|
||||
<div class='btn-toolbar pull-left'>
|
||||
<?php
|
||||
foreach($lang->project->featureBar as $label => $labelName)
|
||||
{
|
||||
$active = $browseType == $label ? 'btn-active-text' : '';
|
||||
echo html::a($this->createLink('project', 'index', "projectID=$project->id&browseType=" . $label), '<span class="text">' . $labelName . '</span> ' . ($browseType == $label ? "<span class='label label-light label-badge'>0</span>" : ''), '', "class='btn btn-link $active'");
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
<div class='btn-toolbar pull-right'>
|
||||
<?php echo html::a($this->createLink('execution', 'create', "projectID=$project->id"), "<i class='icon icon-sm icon-plus'></i> " . $lang->project->createKanban, '', "class='btn btn-primary create-execution-btn'");?>
|
||||
</div>
|
||||
</div>
|
||||
<div id="mainContent">
|
||||
<div class="row cell" id='cards'>
|
||||
<?php if(empty($kanbanList)):?>
|
||||
<div class="table-empty-tip">
|
||||
<p>
|
||||
<span class="text-muted"><?php echo $lang->noData;?></span>
|
||||
<?php common::printLink('execution', 'create', "projectID=$project->id", '<i class="icon icon-plus"></i> ' . $lang->project->createKanban, '', 'class="btn btn-info"');?>
|
||||
</p>
|
||||
</div>
|
||||
<?php else:?>
|
||||
<?php foreach ($kanbanList as $kanbanID => $kanban):?>
|
||||
<div class='col' data-id='<?php echo $kanbanID?>'>
|
||||
<div class='panel'>
|
||||
<div class='panel-heading'>
|
||||
<div class='kanban-name'>
|
||||
<span class="label label-closed"><?php echo zget($lang->execution->statusList, $kanban->status);?></span>
|
||||
<strong title='<?php echo $kanban->name;?>'><?php echo $kanban->name;?></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class='panel-body'>
|
||||
<div class='kanban-desc' title="<?php echo strip_tags(htmlspecialchars_decode($kanban->desc));?>"><?php echo strip_tags(htmlspecialchars_decode($kanban->desc));?></div>
|
||||
<div class='kanban-footer'>
|
||||
<div class="clearfix">
|
||||
<?php $members = zget($memberGroup, $kanbanID, array());?>
|
||||
<?php if(!empty($members)):?>
|
||||
<div class='kanban-members pull-left'>
|
||||
<?php $count = 0;?>
|
||||
<?php foreach($members as $member):?>
|
||||
<?php if($count > 2) break;?>
|
||||
<?php $count ++;?>
|
||||
<div title="<?php echo $member->realname;?>">
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$member->account], 'account' => $member->account)); ?>
|
||||
</div>
|
||||
<?php endforeach;?>
|
||||
<?php if(count($members) > 4):?>
|
||||
<?php echo '<span>…</span>';?>
|
||||
<?php $lastMember = end($members);?>
|
||||
<div title="<?php echo $lastMember->realname;?>">
|
||||
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$lastMember->account], 'account' => $lastMember->account)); ?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<?php endforeach;?>
|
||||
<?php endif;?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
|
||||
Reference in New Issue
Block a user