This commit is contained in:
wangyidong
2021-07-13 13:30:15 +08:00
13 changed files with 199 additions and 22 deletions
+1 -1
View File
@@ -522,7 +522,7 @@ class custom extends control
if(!isset($this->config->maxVersion)) $this->loadModel('setting')->setItem('system.custom.hourPoint', $this->post->hourPoint);
$this->app->loadLang('common');
$locate = inlink('flow');
$locate = $this->config->systemMode == 'new' ? inlink('flow') : 'top';
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $locate));
}
+1 -1
View File
@@ -66,7 +66,7 @@
<td></td>
<td class='form-actions'>
<?php echo html::submitButton();?>
<?php echo html::backButton();?>
<?php echo html::a($this->createLink('company', 'browse'), $lang->goback, '', "class='btn btn-back btn-wide'");?>
<?php echo html::hidden('maxOrder', $maxOrder);?>
<?php echo html::hidden('parentDeptID', $deptID);?>
</td>
+37
View File
@@ -1872,6 +1872,43 @@ class execution extends control
*/
public function executionKanban()
{
$this->loadModel('project');
$projects = $this->project->getPairsByProgram(0, 'noclosed');
$executions = $this->project->getStats();
$teams = $this->dao->select('root,account')->from(TABLE_TEAM)
->where('root')->in($this->app->user->view->sprints)
->andWhere('type')->eq('execution')
->fetchGroup('root', 'account');
$projectCount = 0;
$kanbanGroup = array();
$statusCount = array();
foreach(array_keys($projects) as $projectID)
{
foreach(array_keys($this->lang->execution->statusList) as $status)
{
if(!isset($statusCount[$status])) $statusCount[$status] = 0;
foreach($executions as $execution)
{
if($execution->status == $status)
{
if(isset($teams[$execution->id][$this->app->user->account])) $kanbanGroup[0][$status][$execution->id] = $execution;
if($execution->project == $projectID) $kanbanGroup[$projectID][$status][$execution->id] = $execution;
}
}
$statusCount[$status] += isset($kanbanGroup[$projectID][$status]) ? count($kanbanGroup[$projectID][$status]) : 0;
}
$projectCount++;
}
ksort($kanbanGroup);
$this->view->title = $this->lang->execution->executionKanban;
$this->view->kanbanGroup = $kanbanGroup;
$this->view->projects = $projects;
$this->view->projectCount = $projectCount;
$this->view->statusCount = $statusCount;
$this->display();
}
+29
View File
@@ -0,0 +1,29 @@
.main-table tbody > tr > td {border-bottom: 2px solid #fff;}
.boards {display: table; table-layout: fixed; width: 100%; min-width: 140px;}
.boards .board:not(:last-child), .board-project {border-right: 2px solid #fff;}
.board {display: table-cell; width: 25%; padding: 10px; transition: background-color .2s, opacity .2s; vertical-align: top;}
.board-item {border: 1px solid #EBEBEB; padding: 5px 10px; cursor: move; border-radius: 2px; background-color: #fff;}
.board-item.disabled {cursor: not-allowed;}
.board-item:hover {border-color: #ccc;}
.board-item > .title {line-height: 25px; max-height: 40px; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; text-overflow: ellipsis; word-break: break-all;}
.board-item + .board-item {margin-top: 10px;}
.boards-wrapper {overflow: auto;}
.board-item .btn {padding: 2px 10px 2px 23px; font-size: 12px; position: relative; left: -2px; height: 24px;}
#kanban {overflow-y: auto;}
#kanban .label-pri {width: 16px; height: 16px; line-height: 12px; min-width: 16px; font-size: 12px; padding: 0;}
#kanban tbody > tr > td {line-height: 24px;}
#kanban .table-grouped tbody > tr:hover {background: transparent;}
#kanban .group-info > span + span {display: inline-block; margin-left: 8px;}
#kanban th.c-board {color: #3c4353; font-weight: bold;}
#kanban .fix-table-copy-wrapper {overflow: visible !important;}
#kanban .fix-table-copy-wrapper th.c-board {color: #ddd;}
#kanban .group-title {word-break: break-all; line-height: 16px; padding: 3px 0; display: block;}
#kanban thead > tr > th:not(:last-child) {border-right: 2px solid #efefef;}
.table-grouped > tbody > tr,
.table-grouped > tbody > tr:hover {background: #fff !important;}
.table-row .table-col:last-child {width: 30px;}
.table-row .table-col:first-child {overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
+15
View File
@@ -405,6 +405,13 @@ $lang->execution->featureBar['all']['doing'] = $lang->execution->statusList[
$lang->execution->featureBar['all']['suspended'] = $lang->execution->statusList['suspended'];
$lang->execution->featureBar['all']['closed'] = $lang->execution->statusList['closed'];
$lang->execution->myExecutions = '我参与的';
$lang->execution->doingProject = '进行中的项目';
$lang->execution->kanbanColType['wait'] = $lang->execution->statusList['wait'] . '的' . $lang->execution->common;
$lang->execution->kanbanColType['doing'] = $lang->execution->statusList['doing'] . '的' . $lang->execution->common;
$lang->execution->kanbanColType['suspended'] = $lang->execution->statusList['suspended'] . '的' . $lang->execution->common;
$lang->execution->kanbanColType['closed'] = $lang->execution->statusList['closed'] . '的' . $lang->execution->common;
$lang->execution->treeLevel = array();
$lang->execution->treeLevel['all'] = '全部展开';
$lang->execution->treeLevel['root'] = '全部折叠';
@@ -416,3 +423,11 @@ $lang->execution->action->opened = '$date, 由 <strong>$actor</strong> 创建
$lang->execution->action->managed = '$date, 由 <strong>$actor</strong> 维护。$extra' . "\n";
$lang->execution->action->edited = '$date, 由 <strong>$actor</strong> 编辑。$extra' . "\n";
$lang->execution->action->extra = '相关产品为 %s。';
$lang->execution->statusColorList = array();
$lang->execution->statusColorList['wait'] = '#0991FF';
$lang->execution->statusColorList['doing'] = '#0BD986';
$lang->execution->statusColorList['suspended'] = '#fdc137';
$lang->execution->statusColorList['closed'] = '#838A9D';
$lang->execution->boardColorList = '#F1F3F5,#ECF4FD,#F6EDF7,#FFEDED,#FFF7EB,#FFF7E1';
@@ -0,0 +1,94 @@
<?php
/**
* The execution kanban view file of execution module of ZenTaoPMS.
*
* @copyright Copyright 2009-2021 青岛易软天创网络科技有限公司 (QingDao Nature Easy Soft Network Technology Co,LTD www.cnezsoft.com)
* @author Qiyu Xie
* @package execution
* @version $Id: executionkanban.html.php $
*/
?>
<?php include '../../common/view/header.html.php';?>
<div id="kanban" class="main-table fade auto-fade-in" data-ride="table" data-checkable="false" data-group="true">
<table class="table no-margin table-grouped text-center">
<thead>
<tr>
<th><?php echo $lang->execution->doingProject . ' (' . $projectCount . ')';?></th>
<?php foreach($lang->execution->kanbanColType as $status => $col):?>
<th><?php echo $col . ' (' . $statusCount[$status] . ')';?></th>
<?php endforeach;?>
</tr>
</thead>
<tbody>
<?php $rowIndex = 0; ?>
<?php foreach($kanbanGroup as $projectID => $executionList):?>
<tr>
<td class='board-project text-left color-<?php echo $rowIndex;?>'>
<div data-id='<?php echo $projectID;?>'>
<div class='text-center'>
<?php $projectTitle = empty($projectID) ? $lang->execution->myExecutions : zget($projects, $projectID);?>
<span class='group-title' title='<?php echo $projectTitle;?>'><?php echo $projectTitle;?></span>
</div>
</div>
</td>
<td class="c-boards no-padding text-left color-<?php echo $rowIndex;?>" colspan='4'>
<div class="boards-wrapper">
<div class="boards">
<?php foreach($lang->execution->kanbanColType as $colStatus => $col):?>
<div class="board s-<?php echo $colStatus?>" data-type="<?php echo $colStatus;?>">
<?php if(!empty($executionList[$colStatus])):?>
<?php foreach($executionList[$colStatus] as $execution):?>
<div class='board-item' data-id='<?php echo $execution->id?>' id='task-<?php echo $execution->id?>' data-type='execution' <?php if(isset($execution->delay)) echo "style='border-left: 3px solid #ff0000';";?>>
<div class='table-row'>
<div class='table-col'>
<?php
if(common::hasPriv('execution', 'task'))
{
echo html::a($this->createLink('execution', 'task', "executionID=$execution->id"), $execution->name, '', 'class="title kanbaniframe" title="' . $execution->name . '"');
}
else
{
echo "<span class='title' title='{$execution->name}'>{$execution->name}</span>";
}
?>
</div>
<div class='table-col'>
<?php if($colStatus == 'doing'):?>
<div class="c-progress">
<div class='progress-pie' data-doughnut-size='90' data-color='#00da88' data-value='<?php echo $execution->hours->progress;?>' data-width='24' data-height='24' data-back-color='#e8edf3'>
<div class='progress-info'><?php echo $execution->hours->progress;?></div>
</div>
</div>
<?php endif?>
</div>
</div>
</div>
<?php endforeach?>
<?php endif?>
</div>
<?php endforeach;?>
</div>
</div>
</td>
</tr>
<?php $rowIndex++; ?>
<?php endforeach;?>
</tbody>
</table>
</div>
<style>
<?php foreach(array_keys($lang->execution->kanbanColType) as $status):?>
<?php echo ".s-$status .board-item {border-left: 3px solid {$lang->execution->statusColorList[$status]};}";?>
<?php endforeach;?>
<?php
$boardColorList = explode(',', $lang->execution->boardColorList);
$colorCounts = count($boardColorList);
$colorIndex = 0;
for($i = 0; $i <= $rowIndex; $i++)
{
$colorIndex = $i % $colorCounts == 0 ? 0 : ++$colorIndex;
echo "#kanban tbody > tr > td.color-$i {background-color: {$boardColorList[$colorIndex]};}";
}
?>
</style>
<?php include '../../common/view/footer.html.php';?>
+4 -3
View File
@@ -587,11 +587,11 @@ class product extends control
if(!empty($this->config->user->moreLink)) $this->config->moreLinks["RD"] = $this->config->user->moreLink;
/* Get product lines by programs.*/
$programs = $this->program->getPairs();
$programs = $this->program->getTopPairs();
$lines = array();
foreach($programs as $programID => $program)
foreach($programs as $id => $program)
{
$lines[$programID] = array('') + $this->product->getLinePairs($programID);
$lines[$id] = array('') + $this->product->getLinePairs($id);
}
$this->view->title = $this->lang->product->batchEdit;
@@ -602,6 +602,7 @@ class product extends control
$this->view->poUsers = $poUsers;
$this->view->qdUsers = $qdUsers;
$this->view->rdUsers = $rdUsers;
$this->view->programID = $programID;
$this->view->programs = array('') + $programs;
unset($this->lang->product->typeList['']);
+8 -7
View File
@@ -58,7 +58,7 @@
<th class='w-150px<?php echo zget($visibleFields, 'PO', ' hidden') . zget($requiredFields, 'PO', '', ' required');?>'><?php echo $lang->product->PO;?></th>
<th class='w-150px<?php echo zget($visibleFields, 'QD', ' hidden') . zget($requiredFields, 'QD', '', ' required');?>'><?php echo $lang->product->QD;?></th>
<th class='w-150px<?php echo zget($visibleFields, 'RD', ' hidden') . zget($requiredFields, 'RD', '', ' required');?>'><?php echo $lang->product->RD;?></th>
<th class='w-200px<?php echo zget($visibleFields, 'type', ' hidden') . zget($requiredFields, 'type', '', ' required');?>'><?php echo $lang->product->type;?></th>
<th class='w-120px<?php echo zget($visibleFields, 'type', ' hidden') . zget($requiredFields, 'type', '', ' required');?>'><?php echo $lang->product->type;?></th>
<th class='w-100px<?php echo zget($visibleFields, 'status', ' hidden') . zget($requiredFields, 'status', '', ' required');?>'><?php echo $lang->product->status;?></th>
<th class='w-200px<?php echo zget($visibleFields, 'desc', ' hidden') . zget($requiredFields, 'desc', '', ' required');?>'><?php echo $lang->product->desc;?></th>
<th class='w-120px<?php echo zget($visibleFields, 'acl', ' hidden');?>'><?php echo $lang->product->acl;?></th>
@@ -73,12 +73,12 @@
?>
<tr>
<td><?php echo sprintf('%03d', $productID) . html::hidden("productIDList[$productID]", $productID);?></td>
<td class='text-left<?php echo zget($visibleFields, 'program', ' hidden')?>' style='overflow:visible'><?php echo html::select("programs[$productID]", $programs, $products[$productID]->program, "class='form-control chosen' onchange='loadProductLines(this.value, $productID)'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'program', ' hidden')?>' style='overflow:visible'><?php echo html::select("programs[$productID]", $programs, $products[$productID]->program, "class='form-control picker-select' onchange='loadProductLines(this.value, $productID)'");?></td>
<td title='<?php echo $products[$productID]->name?>'><?php echo html::input("names[$productID]", $products[$productID]->name, "class='form-control'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'line', ' hidden')?>' style='overflow:visible' id="line_<?php echo $productID;?>"><?php echo html::select("lines[$productID]", isset($lines[$products[$productID]->program]) ? $lines[$products[$productID]->program] : '', $products[$productID]->line, "class='form-control chosen'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'PO', ' hidden')?>' style='overflow:visible'><?php echo html::select("POs[$productID]", $poUsers, $products[$productID]->PO, "class='form-control chosen'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'QD', ' hidden')?>' style='overflow:visible'><?php echo html::select("QDs[$productID]", $qdUsers, $products[$productID]->QD, "class='form-control chosen'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'RD', ' hidden')?>' style='overflow:visible'><?php echo html::select("RDs[$productID]", $rdUsers, $products[$productID]->RD, "class='form-control chosen'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'line', ' hidden')?>' style='overflow:visible' id="line_<?php echo $productID;?>"><?php echo html::select("lines[$productID]", isset($lines[$products[$productID]->program]) ? $lines[$products[$productID]->program] : '', $products[$productID]->line, "class='form-control picker-select'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'PO', ' hidden')?>' style='overflow:visible'><?php echo html::select("POs[$productID]", $poUsers, $products[$productID]->PO, "class='form-control picker-select'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'QD', ' hidden')?>' style='overflow:visible'><?php echo html::select("QDs[$productID]", $qdUsers, $products[$productID]->QD, "class='form-control picker-select'");?></td>
<td class='text-left<?php echo zget($visibleFields, 'RD', ' hidden')?>' style='overflow:visible'><?php echo html::select("RDs[$productID]", $rdUsers, $products[$productID]->RD, "class='form-control picker-select'");?></td>
<td class='<?php echo zget($visibleFields, 'type', 'hidden')?>'><?php echo html::select("types[$productID]", $lang->product->typeList, $products[$productID]->type, "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'status', 'hidden')?>'><?php echo html::select("statuses[$productID]", $lang->product->statusList, $products[$productID]->status, "class='form-control'");?></td>
<td class='<?php echo zget($visibleFields, 'desc', 'hidden')?>'><?php echo html::textarea("descs[$productID]", htmlspecialchars($products[$productID]->desc), "rows='1' class='form-control autosize'");?></td>
@@ -95,7 +95,8 @@
<tr>
<td colspan="<?php echo count($visibleFields) + 4?>" class="text-center form-actions">
<?php echo html::submitButton();?>
<?php echo html::backButton();?>
<?php $browseLink = $this->app->openApp == 'product' ? $this->createLink('product', 'all') : $this->createLink('program', 'product', "programID=$programID");?>
<?php echo html::a($browseLink, $lang->goback, '', 'class="btn btn-back btn-wide"');?>
</td>
</tr>
</tfoot>
+2 -2
View File
@@ -121,8 +121,8 @@ $lang->user->testTask2Him = 'Build';
$lang->user->case2Him = 'Fall zugeordnet';
$lang->user->caseByHim = 'Fall geöffnet';
$lang->user->errorDeny = "Sorry, Ihr Zugang zu <b>%s</b> von <b>%s</b> wurde verweigert. Bitte kontaktieren Sie Ihren Administrator um Zugriff zu erhalten. Klicken Sie auf Zurück.";
$lang->user->errorView = "Sorry, your access view <b>%s</b> is denied. Please contact your Admin to get privileges. Click Back to return.";
$lang->user->errorDeny = "Sorry, your access to <b>%s</b> of <b>%s</b> is denied. Please contact your Admin to get privileges. Return to home page or login again.";
$lang->user->errorView = "Sorry, your access view <b>%s</b> is denied. Please contact your Admin to get privileges. Return to home page or login again.";
$lang->user->loginFailed = "Login fehlgeschlagen. Bitte prüfen Sie Ihren Benutzernamen und das Passwort.";
$lang->user->lockWarning = "Sie haben %s Versuche.";
$lang->user->loginLocked = "Bitte kontaktieren Sie den Administrator um Ihr Konto entsperren zu lassen oder versuchen Sie in %s Minuten noch ein mal.";
+2 -2
View File
@@ -122,8 +122,8 @@ $lang->user->testTask2Him = 'RequestsAssignedTo%s';
$lang->user->case2Him = 'CasesAssignedTo%s';
$lang->user->caseByHim = 'CasesCreatedBy%s';
$lang->user->errorDeny = "Sorry, your access to <b>%s</b> of <b>%s</b> is denied. Please contact your Admin to get privileges. Click Back to return.";
$lang->user->errorView = "Sorry, your access view <b>%s</b> is denied. Please contact your Admin to get privileges. Click Back to return.";
$lang->user->errorDeny = "Sorry, your access to <b>%s</b> of <b>%s</b> is denied. Please contact your Admin to get privileges. Return to home page or login again.";
$lang->user->errorView = "Sorry, your access view <b>%s</b> is denied. Please contact your Admin to get privileges. Return to home page or login again.";
$lang->user->loginFailed = "Login failed. Please check your account and password.";
$lang->user->lockWarning = "You can try %s times.";
$lang->user->loginLocked = "Please contact the administrator to unlock your account or try %s minutes later.";
+2 -2
View File
@@ -121,8 +121,8 @@ $lang->user->testTask2Him = 'Recette assignée à %s';
$lang->user->case2Him = 'CasTest assigné à %s';
$lang->user->caseByHim = 'CasTest créé par %s';
$lang->user->errorDeny = "Désolé, votre accès à <b>%s</b> of <b>%s</b> est refusé. Veuillez contacter votre administrateur pour obtenir des privilèges. Cliquez sur Retour pour revenir.";
$lang->user->errorView = "Désolé, votre accès en consultation <b>%s</b> est refusé. Veuillez contacter votre administrateur pour obtenir des privilèges. Cliquez sur Retour pour revenir.";
$lang->user->errorDeny = "Sorry, your access to <b>%s</b> of <b>%s</b> is denied. Please contact your Admin to get privileges. Return to home page or login again.";
$lang->user->errorView = "Sorry, your access view <b>%s</b> is denied. Please contact your Admin to get privileges. Return to home page or login again.";
$lang->user->loginFailed = "Echec de connexion. Vérifiez votre login et mot de passe.";
$lang->user->lockWarning = "Vous avez %s essais.";
$lang->user->loginLocked = "Votre compte est bloqué. Contactez l'administrateur pour débloquer votre compte ou attendez %s minutes pour une nouvelle tentative.";
+2 -2
View File
@@ -121,8 +121,8 @@ $lang->user->testTask2Him = 'Nhận yêu cầu';
$lang->user->case2Him = 'Nhận tình huống';
$lang->user->caseByHim = 'Tạo tình huống';
$lang->user->errorDeny = "Xin lỗi, truy cập của bạn tới <b>%s</b> of <b>%s</b> bị từ chối. Vui lòng liên lạc quản trị của bạn để nhận quyền. Click Trở lại.";
$lang->user->errorView = "Xin lỗi, truy cập của bạn xem <b>%s</b> bị từ chối. Vui lòng liên lạc quản trị của bạn để nhận quyền. Click Trở lại.";
$lang->user->errorDeny = "Sorry, your access to <b>%s</b> of <b>%s</b> is denied. Please contact your Admin to get privileges. Return to home page or login again.";
$lang->user->errorView = "Sorry, your access view <b>%s</b> is denied. Please contact your Admin to get privileges. Return to home page or login again.";
$lang->user->loginFailed = "Đăng nhập thất bại. Vui lòng kiểm tra tài khoản và mật khẩu của bạn.";
$lang->user->lockWarning = "Bạn có thể thử %s lần.";
$lang->user->loginLocked = "Vui lòng liên hệ với quản trị viên để mở khóa tài khoản của bạn hoặc thử lại %s phút sau.";
+2 -2
View File
@@ -122,8 +122,8 @@ $lang->user->testTask2Him = '%s负责的';
$lang->user->case2Him = '指派给%s';
$lang->user->caseByHim = '由%s创建';
$lang->user->errorDeny = "抱歉,您无权访问『<b>%s</b>』模块的『<b>%s</b>』功能。请联系管理员获取权限。点击后退返回上页";
$lang->user->errorView = "抱歉,您无权访问『<b>%s</b>』视图。请联系管理员获取权限。点击后退返回上页";
$lang->user->errorDeny = "抱歉,您无权访问『<b>%s</b>』模块的『<b>%s</b>』功能。请联系管理员获取权限。请回到地盘或重新登录";
$lang->user->errorView = "抱歉,您无权访问『<b>%s</b>』视图。请联系管理员获取权限。请回到地盘或重新登录";
$lang->user->loginFailed = "登录失败,请检查您的用户名或密码是否填写正确。";
$lang->user->lockWarning = "您还有%s次尝试机会。";
$lang->user->loginLocked = "密码尝试次数太多,请联系管理员解锁,或%s分钟后重试。";