Merge branch 'master' of https://github.com/easysoft/zentaopms
This commit is contained in:
@@ -166,6 +166,7 @@ CREATE TABLE IF NOT EXISTS `zt_case` (
|
||||
`linkCase` varchar(255) NOT NULL,
|
||||
`fromBug` mediumint(8) unsigned NOT NULL,
|
||||
`fromCaseID` mediumint(8) unsigned NOT NULL,
|
||||
`fromCaseVersion` mediumint(8) unsigned NOT NULL,
|
||||
`deleted` enum('0','1') NOT NULL default '0',
|
||||
`lastRunner` varchar(30) NOT NULL,
|
||||
`lastRunDate` datetime NOT NULL,
|
||||
@@ -1251,6 +1252,7 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
|
||||
(1, 'story', 'create'),
|
||||
(1, 'story', 'delete'),
|
||||
(1, 'story', 'edit'),
|
||||
(1, 'story', 'assignTo'),
|
||||
(1, 'story', 'batchChangeModule'),
|
||||
(1, 'story', 'linkStory'),
|
||||
(1, 'story', 'unlinkStory'),
|
||||
@@ -2715,6 +2717,7 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
|
||||
(7, 'story', 'create'),
|
||||
(7, 'story', 'delete'),
|
||||
(7, 'story', 'edit'),
|
||||
(7, 'story', 'assignTo'),
|
||||
(7, 'story', 'batchChangeModule'),
|
||||
(7, 'story', 'linkStory'),
|
||||
(7, 'story', 'unlinkStory'),
|
||||
|
||||
@@ -740,7 +740,7 @@ class baseControl
|
||||
*/
|
||||
if(!is_file($file2Included)) $this->app->triggerError("The control file $file2Included not found", __FILE__, __LINE__, $exit = true);
|
||||
chdir(dirname($file2Included));
|
||||
if($moduleName != $this->moduleName) helper::import($file2Included);
|
||||
helper::import($file2Included);
|
||||
|
||||
/**
|
||||
* 设置调用的类名。
|
||||
|
||||
@@ -1631,7 +1631,7 @@ class baseRouter
|
||||
**/
|
||||
$file2Included = $this->setActionExtFile() ? $this->extActionFile : $this->controlFile;
|
||||
chdir(dirname($file2Included));
|
||||
include $file2Included;
|
||||
helper::import($file2Included);
|
||||
|
||||
/*
|
||||
* 设置control的类名。
|
||||
@@ -1650,7 +1650,7 @@ class baseRouter
|
||||
|
||||
/* include default value for module*/
|
||||
$defaultValueFiles = glob($this->getTmpRoot() . "defaultvalue/*.php");
|
||||
if($defaultValueFiles) foreach($defaultValueFiles as $file) include $file;
|
||||
if($defaultValueFiles) foreach($defaultValueFiles as $file) helper::import($file);
|
||||
|
||||
/*
|
||||
* 使用反射机制获取函数参数的默认值。
|
||||
|
||||
@@ -68,6 +68,7 @@ class router extends baseRouter
|
||||
}
|
||||
|
||||
$productCommon = $projectCommon = 0;
|
||||
if(!empty($this->config->isINT)) $projectCommon = 1;
|
||||
if($productProject)
|
||||
{
|
||||
$productProject = $productProject->value;
|
||||
|
||||
@@ -342,6 +342,12 @@ class actionModel extends model
|
||||
}
|
||||
}
|
||||
}
|
||||
elseif(($actionName == 'opened' or $actionName == 'managed') and $objectType == 'project')
|
||||
{
|
||||
$linkedProducts = $this->dao->select('id,name')->from(TABLE_PRODUCT)->where('id')->in($action->extra)->fetchPairs('id', 'name');
|
||||
$action->extra = '';
|
||||
if($linkedProducts) $action->extra = sprintf($this->lang->project->action->extra, '<strong>' . join(', ', $linkedProducts) . '</strong>');
|
||||
}
|
||||
$action->history = isset($histories[$actionID]) ? $histories[$actionID] : array();
|
||||
|
||||
$actionName = strtolower($action->action);
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
<th><?php echo $lang->user->company;?></th>
|
||||
<td><div class="required required-wrapper"></div><?php echo html::input('company', $register->company, "class='form-control'");?></td>
|
||||
</tr>
|
||||
<?php if(empty($config->isINT)):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->user->mobile;?></th>
|
||||
<td>
|
||||
@@ -55,6 +56,7 @@
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr>
|
||||
<th><?php echo $lang->user->email;?></th>
|
||||
<td>
|
||||
|
||||
@@ -249,8 +249,6 @@ class block extends control
|
||||
$block->actionLink = '';
|
||||
if($block->block == 'overview')
|
||||
{
|
||||
if($module == 'product' && common::hasPriv('product', 'create')) $block->actionLink = html::a($this->createLink('product', 'create'), "<i class='icon icon-sm icon-plus'></i> " . $this->lang->product->create, '', "class='btn btn-primary'");
|
||||
if($module == 'project' && common::hasPriv('project', 'create')) $block->actionLink = html::a($this->createLink('project', 'create'), "<i class='icon icon-sm icon-plus'></i> " . $this->lang->project->create, '', "class='btn btn-primary'");
|
||||
if($module == 'qa' && common::hasPriv('testcase', 'create'))
|
||||
{
|
||||
$this->app->loadLang('testcase');
|
||||
|
||||
@@ -18,6 +18,16 @@ $useGuest = $this->app->user->account == 'guest';
|
||||
?>
|
||||
<?php include '../../common/view/tablesorter.html.php';?>
|
||||
<div class='dashboard auto-fade-in fade' id='dashboard' data-confirm-remove-block='<?php echo $lang->block->confirmRemoveBlock;?>'>
|
||||
<?php if(empty($longBlocks) and empty($shortBlocks)):?>
|
||||
<div class="table-empty-tip">
|
||||
<p>
|
||||
<span class="text-muted"><?php echo $lang->block->noData. ',';?></span>
|
||||
<span class="text-muted"><?php echo $lang->youCould;?></span>
|
||||
<?php echo html::a($this->createLink("block", "admin", "id=0&module=$module"), "<i class='icon icon-plus'></i> {$lang->block->createBlock}", '', "data-toggle='modal' data-type='ajax' data-width='700' data-title='{$lang->block->createBlock}' class='btn btn-info'")?>
|
||||
<?php echo html::a($this->createLink("block", "ajaxReset", "module=$module"), "<i class='icon icon-refresh'></i> {$lang->block->reset}", 'hiddenwin', 'class="btn btn-info"')?>
|
||||
</p>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<div class="row">
|
||||
<div class='col-main'>
|
||||
<?php foreach($longBlocks as $index => $block):?>
|
||||
@@ -42,6 +52,8 @@ $useGuest = $this->app->user->account == 'guest';
|
||||
<?php endif;?>
|
||||
<li><a href='javascript:deleteBlock(<?php echo $index;?>);' class='remove-panel'><?php echo $lang->block->remove;?></a></li>
|
||||
<?php endif;?>
|
||||
<li><?php echo html::a($this->createLink("block", "admin", "id=0&module=$module"), "{$lang->block->createBlock}", '', "data-toggle='modal' data-type='ajax' data-width='700' data-title='{$lang->block->createBlock}'")?></li>
|
||||
<li><?php echo html::a($this->createLink("block", "ajaxReset", "module=$module"), "{$lang->block->reset}", 'hiddenwin')?></li>
|
||||
<?php if($this->app->user->admin):?>
|
||||
<li><?php echo html::a($this->createLink('block', 'close', "blockID={$block->id}"), $lang->block->closeForever, 'hiddenwin', "class='close-block' onclick=\"return confirm('{$lang->block->confirmClose}')\"")?>
|
||||
<?php endif;?>
|
||||
@@ -78,6 +90,8 @@ $useGuest = $this->app->user->account == 'guest';
|
||||
<?php endif;?>
|
||||
<li><a href='javascript:deleteBlock(<?php echo $index?>);' class='remove-panel'><?php echo $lang->block->remove; ?></a></li>
|
||||
<?php endif;?>
|
||||
<li><?php echo html::a($this->createLink("block", "admin", "id=0&module=$module"), "{$lang->block->createBlock}", '', "data-toggle='modal' data-type='ajax' data-width='700' data-title='{$lang->block->createBlock}'")?></li>
|
||||
<li><?php echo html::a($this->createLink("block", "ajaxReset", "module=$module"), "{$lang->block->reset}", 'hiddenwin')?></li>
|
||||
<?php if($this->app->user->admin):?>
|
||||
<li><?php echo html::a($this->createLink('block', 'close', "blockID={$block->id}"), $lang->block->closeForever, 'hiddenwin', "class='close-block' onclick=\"return confirm('{$lang->block->confirmClose}')\"")?>
|
||||
<?php endif;?>
|
||||
@@ -99,15 +113,6 @@ config.confirmRemoveBlock = '<?php echo $lang->block->confirmRemoveBlock; ?>';
|
||||
var module = '<?php echo $module?>';
|
||||
var useGuest = <?php echo $useGuest ? 'true' : 'false';?>;
|
||||
<?php if(!$useGuest):?>
|
||||
<?php
|
||||
$dropmenu = "<div class='btn-group'>";
|
||||
$dropmenu .= "<button type='button' class='btn dropdown-toggle' data-toggle='dropdown' style='padding-bottom:7px;'>{$lang->block->common} <span class='caret'></span></button>";
|
||||
$dropmenu .= "<ul class='dropdown-menu pull-right' role='menu'>";
|
||||
$dropmenu .= "<li>" . html::a($this->createLink("block", "admin", "id=0&module=$module"), "<i class='icon icon-plus'></i> {$lang->block->createBlock}", '', "data-toggle='modal' data-type='ajax' data-width='700' data-title='{$lang->block->createBlock}'") . "</li>";
|
||||
$dropmenu .= "<li>" . html::a($this->createLink("block", "ajaxReset", "module=$module"), "<i class='icon icon-refresh'></i> {$lang->block->reset}", 'hiddenwin') . "</li>";
|
||||
$dropmenu .= '</ul></div>';
|
||||
?>
|
||||
$('#subHeader #pageActions .btn-toolbar:last').append(<?php echo json_encode($dropmenu)?>);
|
||||
<?php if(!isset($config->$module->block->initVersion) or $config->$module->block->initVersion < '2'):?>
|
||||
$(function()
|
||||
{
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
<?php endif;?>
|
||||
<th class='c-num'><?php echo $lang->product->plans;?></th>
|
||||
<th class='c-num'><?php echo $lang->product->releases;?></th>
|
||||
<th class='c-num'><?php echo $lang->story->statusList['active'] . $lang->story->common;?></th>
|
||||
<th class='c-num w-90px'><?php echo $lang->bug->unResolved . $lang->bug->common;?></th>
|
||||
<th class='c-num w-100px'><?php echo $lang->story->statusList['active'] . $lang->story->common;?></th>
|
||||
<th class='c-num w-120px'><?php echo $lang->bug->unResolved . $lang->bug->common;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
@@ -20,8 +20,9 @@
|
||||
<th class='c-name text-left'><?php echo $lang->project->name;?></th>
|
||||
<th class="c-date"><?php echo $lang->project->end;?></th>
|
||||
<?php if($longBlock):?>
|
||||
<?php $thClass = (isset($config->isINT) and $config->isINT) ? 'w-85px' : 'c-hours';?>
|
||||
<th class="c-status"><?php echo $lang->statusAB;?></th>
|
||||
<th class="c-hours"><?php echo $lang->project->totalEstimate;?></th>
|
||||
<th class='<?php echo $thClass?>'><?php echo $lang->project->totalEstimate;?></th>
|
||||
<th class="c-hours"><?php echo $lang->project->totalConsumed;?></th>
|
||||
<th class="c-hours"><?php echo $lang->project->totalLeft;?></th>
|
||||
<?php endif;?>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
.types-line > li > div > span {display: block; color: #CBD0DB; font-size: 16px;}
|
||||
.product-info {position: relative; height: 65px;}
|
||||
.product-info + .product-info {margin-top: 10px;}
|
||||
.product-info .progress {position: absolute; left: 10px; top: 35px; right: 90px;}
|
||||
.product-info .progress {position: absolute; left: 10px; top: 35px; right: 100px;}
|
||||
.product-info .progress-info {position: absolute; left: 8px; top: 10px; width: 180px; font-size: 12px;}
|
||||
.product-info .type-info {color: #A6AAB8; text-align: center; position: absolute; right: 0; top: 6px; width: 100px;}
|
||||
html[lang="en"] .product-info .type-info {color: #A6AAB8; text-align: center; position: absolute; right: 0; top: 6px; width: 130px;}
|
||||
|
||||
@@ -384,7 +384,7 @@ $('#module' + moduleID).closest('li').addClass('active');
|
||||
<?php if($browseType == 'bysearch'):?>
|
||||
if($('#query li.active').size() == 0) $.toggleQueryBox(true);
|
||||
<?php endif;?>
|
||||
<?php if($useDatatable):?>
|
||||
<?php if(!empty($useDatatable)):?>
|
||||
$(function(){$('#bugForm').table();})
|
||||
<?php endif;?>
|
||||
<?php $this->app->loadConfig('qa', '', false);?>
|
||||
|
||||
@@ -9,6 +9,8 @@ function showLink(buildID, type, param)
|
||||
$linkBox.find('[data-ride="table"]').table();
|
||||
$.toggleQueryBox(true, $linkBox.find('#queryBox'));
|
||||
});
|
||||
|
||||
$('.actions').find("a[href*='" + type + "']").addClass('hidden');
|
||||
}
|
||||
|
||||
$(function()
|
||||
|
||||
@@ -60,8 +60,8 @@
|
||||
<?php if($unlinkedCount):?>
|
||||
<div class='table-footer'>
|
||||
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
|
||||
<div class="table-actions btn-toolbar show-always">
|
||||
<?php echo html::submitButton($lang->build->linkBug, '', 'btn');?>
|
||||
<div class="table-actions btn-toolbar">
|
||||
<?php echo html::submitButton($lang->build->linkBug, '', 'btn btn-secondary');?>
|
||||
</div>
|
||||
<div class="btn-toolbar">
|
||||
<?php echo html::a(inlink('view', "buildID={$build->id}&type=bug"), $lang->goback, '', "class='btn'");?>
|
||||
|
||||
@@ -64,7 +64,7 @@
|
||||
<?php if($unlinkedCount):?>
|
||||
<div class='table-footer'>
|
||||
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
|
||||
<div class="table-actions btn-toolbar show-always">
|
||||
<div class="table-actions btn-toolbar">
|
||||
<?php echo html::submitButton($lang->build->linkStory, '', 'btn btn-secondary');?>
|
||||
</div>
|
||||
<div class="btn-toolbar">
|
||||
|
||||
@@ -39,11 +39,6 @@ tbody tr td:first-child input{display:none;}
|
||||
<?php
|
||||
if(!$build->deleted)
|
||||
{
|
||||
if($config->global->flow != 'onlyTest')
|
||||
{
|
||||
if(common::hasPriv('build', 'linkStory')) echo html::a(inlink('view', "buildID=$build->id&type=story&link=true"), '<i class="icon-link"></i> ' . $lang->build->linkStory, '', "class='btn btn-link'");
|
||||
if(common::hasPriv('build', 'linkBug')) echo html::a(inlink('view', "buildID=$build->id&type=bug&link=true"), '<i class="icon-bug"></i> ' . $lang->build->linkBug, '', "class='btn btn-link'");
|
||||
}
|
||||
common::printIcon('build', 'edit', "buildID=$build->id", $build);
|
||||
common::printIcon('build', 'delete', "buildID=$build->id", $build, 'button', 'trash', 'hiddenwin');
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ js::set('confirmDelete', $lang->user->confirmDelete);
|
||||
<th class="c-url"><?php common::printOrderLink('email', $orderBy, $vars, $lang->user->email);?></th>
|
||||
<th class="c-type"><?php common::printOrderLink('gender', $orderBy, $vars, $lang->user->gender);?></th>
|
||||
<th><?php common::printOrderLink('phone', $orderBy, $vars, $lang->user->phone);?></th>
|
||||
<th><?php common::printOrderLink('qq', $orderBy, $vars, $lang->user->qq);?></th>
|
||||
<th><?php $this->app->getClientLang() == 'en' ? common::printOrderLink('skype', $orderBy, $vars, $lang->user->skype) : common::printOrderLink('qq', $orderBy, $vars, $lang->user->qq);?></th>
|
||||
<th class="c-date"><?php common::printOrderLink('last', $orderBy, $vars, $lang->user->last);?></th>
|
||||
<th class="w-90px"><?php common::printOrderLink('visits', $orderBy, $vars, $lang->user->visits);?></th>
|
||||
<th class='c-actions'><?php echo $lang->actions;?></th>
|
||||
@@ -95,7 +95,7 @@ js::set('confirmDelete', $lang->user->confirmDelete);
|
||||
<td class="c-url" title="<?php echo $user->email;?>"><?php echo html::mailto($user->email);?></td>
|
||||
<td class="c-type"><?php echo zget($lang->user->genderList, $user->gender, $user->gender);?></td>
|
||||
<td><?php echo $user->phone;?></td>
|
||||
<td><?php if($user->qq) echo html::a("tencent://message/?uin=$user->qq", $user->qq);?></td>
|
||||
<td><?php echo $this->app->getClientLang() == 'en' ? $user->skype : ($user->qq ? html::a("tencent://message/?uin=$user->qq", $user->qq) : '');?></td>
|
||||
<td class='c-date'><?php if($user->last) echo date('Y-m-d', $user->last);?></td>
|
||||
<td class='c-num text-center'><?php echo $user->visits;?></td>
|
||||
<td class='c-actions'>
|
||||
|
||||
@@ -93,6 +93,7 @@ $lang->custom->notice->longlife = 'Define longlife bugs.';
|
||||
$lang->custom->notice->invalidNumberKey = 'The key should be =< 255.';
|
||||
$lang->custom->notice->invalidStringKey = 'The key should be a combination of lowercase letters, numbers or underlines.';
|
||||
$lang->custom->notice->cannotSetTimezone = 'date_default_timezone_set does not exist or is disabled. Time zone cannot be set.';
|
||||
$lang->custom->notice->noClosedBlock = 'Blocks without permanent closure';
|
||||
|
||||
$lang->custom->notice->indexPage['product'] = "ZenTao 8.2+ has Product Homepage. Do you want to go to Product Homepage?";
|
||||
$lang->custom->notice->indexPage['project'] = "ZenTao 8.2+ has Project Homepage. Do you want to go to Project Homepage?";
|
||||
|
||||
@@ -93,6 +93,7 @@ $lang->custom->notice->longlife = 'Bug列表页面的久未
|
||||
$lang->custom->notice->invalidNumberKey = '键值应为不大于255的数字';
|
||||
$lang->custom->notice->invalidStringKey = '键值应当为小写英文字母、数字或下划线的组合';
|
||||
$lang->custom->notice->cannotSetTimezone = 'date_default_timezone_set方法不存在或禁用,不能设置时区。';
|
||||
$lang->custom->notice->noClosedBlock = '没有永久关闭的区块';
|
||||
|
||||
$lang->custom->notice->indexPage['product'] = "从8.2版本起增加了产品主页视图,是否默认进入产品主页?";
|
||||
$lang->custom->notice->indexPage['project'] = "从8.2版本起增加了项目主页视图,是否默认进入项目主页?";
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th class='w-120px text-top'><?php echo $lang->custom->select;?></th>
|
||||
<?php $checkedKey = isset($config->custom->productProject) ? $config->custom->productProject : '0_0' ?>
|
||||
<?php $checkedKey = isset($config->custom->productProject) ? $config->custom->productProject : (empty($config->isINT) ? '0_0' : '0_1');?>
|
||||
<td>
|
||||
<?php foreach($lang->custom->productProject->relation as $key => $value):?>
|
||||
<p><label class="radio-inline"><input type="radio" name="productProject" value="<?php echo $key?>"<?php echo $key == $checkedKey ? " checked='checked'" : ''?> id="productProject<?php echo $key;?>"><?php echo $value;?></label></p>
|
||||
|
||||
@@ -107,10 +107,23 @@ EOT;
|
||||
<table class='table table-form mw-600px'>
|
||||
<tr>
|
||||
<th class='w-100px'><?php echo $lang->custom->block->fields['closed'];?></th>
|
||||
<td><?php echo html::select('closed[]', $blockPairs, $closedBlock, "class='form-control chosen' multiple");?></td>
|
||||
<td>
|
||||
<?php
|
||||
if(empty($blockPairs))
|
||||
{
|
||||
echo $lang->custom->notice->noClosedBlock;
|
||||
}
|
||||
else
|
||||
{
|
||||
echo html::select('closed[]', $blockPairs, $closedBlock, "class='form-control chosen' multiple");
|
||||
}
|
||||
?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<?php if(!empty($blockPairs)):?>
|
||||
<td colspan='2' class='text-center'><?php echo html::submitButton();?></td>
|
||||
<?php endif;?>
|
||||
</tr>
|
||||
</table>
|
||||
<?php elseif($module == 'user' and $field == 'contactField'):?>
|
||||
|
||||
@@ -14,12 +14,11 @@ $config->doc->edit->requiredFields = 'title';
|
||||
|
||||
$config->doc->customObjectLibs = 'files,customFiles';
|
||||
$config->doc->notArticleType = '';
|
||||
$config->doc->canCreateOffice = false;
|
||||
$config->doc->officeTypes = 'word,ppt,excel';
|
||||
|
||||
$config->doc->custom = new stdclass();
|
||||
$config->doc->custom->objectLibs = $config->doc->customObjectLibs;
|
||||
$config->doc->custom->showLibs = 'zero';
|
||||
$config->doc->custom->showLibs = 'zero,children';
|
||||
|
||||
$config->doc->editor = new stdclass();
|
||||
$config->doc->editor->create = array('id' => 'content', 'tools' => 'fullTools');
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#docsTree li > a > .icon {opacity: .65;}
|
||||
|
||||
.files-grid {padding: 0 10px;}
|
||||
.files-grid .col {width: 167px; text-align: center; padding: 0; margin-bottom: 10px;}
|
||||
.files-grid .col {width: 20%; text-align: center; padding: 0; margin-bottom: 10px;}
|
||||
.files-grid .actions {position: absolute; bottom: -38px; height:50px; left: 0; right: 0; background: #E9F2FB; z-index: 10; opacity: 0; transition: opacity .2s; padding-bottom: 8px; border-radius: 0 0 3px 3px; padding-top: 8px;}
|
||||
.files-grid .col:hover .actions {opacity: 1;}
|
||||
.files-grid .file {padding: 10px; cursor: pointer; display: block; border-radius: 2px; transition: background-color .2s; border-radius: 3px 3px 0 0}
|
||||
|
||||
+11
-3
@@ -16,10 +16,13 @@ $(function()
|
||||
$('#urlBox').removeClass('hidden');
|
||||
}
|
||||
});
|
||||
window.editor['content'].addListener('ready', function()
|
||||
if(typeof(window.editor) != 'undefined')
|
||||
{
|
||||
$('div#content .edui-toolbar').append("<div class='edui-box edui-button edui-for-markdown edui-default'><div class='edui-default' onmouseover='toggleHover(this)' onmouseout='toggleHover(this)'><div class='edui-button-wrap edui-default' style='padding-right:4px;padding-left:4px;'><div class='edui-default' onclick='toggleEditor(\"markdown\")' title='Markdown'>Markdown</div></div></div></div>");
|
||||
});
|
||||
window.editor['content'].addListener('ready', function()
|
||||
{
|
||||
$('div#content .edui-toolbar').append("<div class='edui-box edui-button edui-for-markdown edui-default'><div class='edui-default' onmouseover='toggleHover(this)' onmouseout='toggleHover(this)'><div class='edui-button-wrap edui-default' style='padding-right:4px;padding-left:4px;'><div class='edui-default' onclick='toggleEditor(\"markdown\")' title='Markdown'>Markdown</div></div></div></div>");
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
function toggleHover(obj)
|
||||
@@ -59,4 +62,9 @@ function initPage(type)
|
||||
$('#contentBox').addClass('hidden');
|
||||
$('#urlBox').removeClass('hidden');
|
||||
}
|
||||
if(type == 'word' || type == 'ppt' || type == 'excel')
|
||||
{
|
||||
if($('#contentBox')).hide();
|
||||
if($('#urlBox')).hide();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
$(function()
|
||||
{
|
||||
$('#top-submit').click(function()
|
||||
{
|
||||
$(this).addClass('disabled');
|
||||
$('form').submit();
|
||||
})
|
||||
toggleAcl($('input[name="acl"]:checked').val(), 'doc');
|
||||
$('input[name="type"]').change(function()
|
||||
{
|
||||
|
||||
@@ -152,6 +152,7 @@ $lang->doc->customObjectLibs['customFiles'] = 'Show Custom Library';
|
||||
$lang->doc->orderLib = 'Library order settings';
|
||||
$lang->doc->customShowLibs = 'Library display settings';
|
||||
$lang->doc->customShowLibsList['zero'] = 'Display empty library';
|
||||
$lang->doc->customShowLibsList['children'] = 'Display sub-category documents';
|
||||
$lang->doc->customShowLibsList['unclosed'] = 'Only display projects that are not closed';
|
||||
|
||||
$lang->doc->confirmDelete = "Do you want to delete this document?";
|
||||
|
||||
@@ -152,6 +152,7 @@ $lang->doc->customObjectLibs['customFiles'] = '显示自定义文档库';
|
||||
$lang->doc->orderLib = '文档库排序';
|
||||
$lang->doc->customShowLibs = '显示设置';
|
||||
$lang->doc->customShowLibsList['zero'] = '显示空文档的库';
|
||||
$lang->doc->customShowLibsList['children'] = '显示子分类的文档';
|
||||
$lang->doc->customShowLibsList['unclosed'] = '只显示未关闭的项目';
|
||||
|
||||
$lang->doc->confirmDelete = "您确定删除该文档吗?";
|
||||
|
||||
@@ -493,7 +493,7 @@ class docModel extends model
|
||||
->where('deleted')->eq(0)
|
||||
->beginIF($this->config->doc->notArticleType)->andWhere('type')->notIN($this->config->doc->notArticleType)->fi()
|
||||
->beginIF($libID)->andWhere('lib')->in($libID)->fi()
|
||||
->beginIF(!empty($module))->andWhere('module')->in($module)->fi()
|
||||
->beginIF(!empty($module) or strpos($this->config->doc->custom->showLibs, 'children') === false)->andWhere('module')->in($module)->fi()
|
||||
->query();
|
||||
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php if(strpos($config->doc->officeTypes, $docType) !== false and !$config->doc->canCreateOffice):?>
|
||||
<?php if($docType != '' and strpos($config->doc->officeTypes, $docType) !== false):?>
|
||||
<?php include '../../common/view/header.lite.html.php';?>
|
||||
<div id="mainContent" class="main-content">
|
||||
<div class='center-block'>
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<?php echo html::a($this->createLink('doc', 'view', "docID=$doc->id"), $doc->title, '', "title='$doc->title'");?>
|
||||
<small> <?php echo $lang->arrow . ' ' . $lang->doc->edit;?></small>
|
||||
</h2>
|
||||
<div class='pull-right'><?php echo html::a('###', $lang->save, '', 'id="top-submit" class="btn btn-primary"');?></div>
|
||||
</div>
|
||||
<form class='load-indicator main-form form-ajax' method='post' enctype='multipart/form-data' id='dataform'>
|
||||
<table class='table table-form'>
|
||||
|
||||
@@ -53,8 +53,8 @@
|
||||
<thead>
|
||||
<tr class="text-center">
|
||||
<th class="w-80px"><?php echo $lang->doc->id;?></th>
|
||||
<th><?php echo $lang->doc->fileTitle;?></th>
|
||||
<th><?php echo $lang->doc->filePath;?></th>
|
||||
<th class='text-left'><?php echo $lang->doc->fileTitle;?></th>
|
||||
<th class='text-left'><?php echo $lang->doc->filePath;?></th>
|
||||
<th class="w-60px"><?php echo $lang->doc->extension;?></th>
|
||||
<th class="w-60px"><?php echo $lang->doc->size;?></th>
|
||||
<th class="w-100px"><?php echo $lang->doc->addedBy;?></th>
|
||||
|
||||
@@ -198,6 +198,7 @@ $lang->resource->story->view = 'view';
|
||||
$lang->resource->story->change = 'lblChange';
|
||||
$lang->resource->story->review = 'lblReview';
|
||||
$lang->resource->story->batchReview = 'batchReview';
|
||||
$lang->resource->story->assignTo = 'assignTo';
|
||||
$lang->resource->story->close = 'lblClose';
|
||||
$lang->resource->story->batchClose = 'batchClose';
|
||||
$lang->resource->story->activate = 'lblActivate';
|
||||
@@ -225,14 +226,15 @@ $lang->story->methodOrder[50] = 'close';
|
||||
$lang->story->methodOrder[55] = 'batchClose';
|
||||
$lang->story->methodOrder[60] = 'batchChangePlan';
|
||||
$lang->story->methodOrder[65] = 'batchChangeStage';
|
||||
$lang->story->methodOrder[70] = 'batchAssignTo';
|
||||
$lang->story->methodOrder[75] = 'activate';
|
||||
$lang->story->methodOrder[80] = 'tasks';
|
||||
$lang->story->methodOrder[85] = 'bugs';
|
||||
$lang->story->methodOrder[90] = 'cases';
|
||||
$lang->story->methodOrder[95] = 'zeroCase';
|
||||
$lang->story->methodOrder[100] = 'report';
|
||||
$lang->story->methodOrder[105] = 'linkStory';
|
||||
$lang->story->methodOrder[70] = 'assignTo';
|
||||
$lang->story->methodOrder[75] = 'batchAssignTo';
|
||||
$lang->story->methodOrder[80] = 'activate';
|
||||
$lang->story->methodOrder[85] = 'tasks';
|
||||
$lang->story->methodOrder[90] = 'bugs';
|
||||
$lang->story->methodOrder[95] = 'cases';
|
||||
$lang->story->methodOrder[100] = 'zeroCase';
|
||||
$lang->story->methodOrder[105] = 'report';
|
||||
$lang->story->methodOrder[110] = 'linkStory';
|
||||
$lang->story->methodOrder[115] = 'batchChangeBranch';
|
||||
$lang->story->methodOrder[120] = 'batchChangeModule';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?php
|
||||
$config->message->objectTypes = array();
|
||||
$config->message->objectTypes['product'] = array('opened', 'edited', 'closed', 'undeleted');
|
||||
$config->message->objectTypes['story'] = array('opened', 'edited', 'commented', 'frombug', 'changed', 'reviewed', 'closed', 'activated');
|
||||
$config->message->objectTypes['story'] = array('opened', 'edited', 'commented', 'frombug', 'changed', 'reviewed', 'closed', 'activated', 'assigned');
|
||||
$config->message->objectTypes['productplan'] = array('opened', 'edited');
|
||||
$config->message->objectTypes['project'] = array('opened', 'edited', 'started', 'delayed', 'suspended', 'closed', 'activated', 'undeleted');
|
||||
$config->message->objectTypes['task'] = array('opened', 'edited', 'commented', 'assigned', 'confirmed', 'started', 'finished', 'paused', 'canceled', 'restarted', 'closed', 'activated');
|
||||
|
||||
@@ -139,7 +139,7 @@ $lang->misc->feature->all['9.5.1'][] = array('title'=>'added Restricted Operatio
|
||||
|
||||
$lang->misc->feature->all['9.3.beta'][] = array('title'=>'upgraded framework,Enhanced security', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['9.1.stable'][] = array('title'=>'optimize Test View', 'desc' => '<p>added TestSuite,CaseLib and Test Statements</p>');
|
||||
$lang->misc->feature->all['9.1.stable'][] = array('title'=>'optimize Test View', 'desc' => '<p>added TestSuite,CaseLib and QA Report</p>');
|
||||
$lang->misc->feature->all['9.1.stable'][] = array('title'=>'support Group steps of TestCase', 'desc' => '');
|
||||
|
||||
$lang->misc->feature->all['9.0.beta'][] = array('title'=>'ZenTao CloudMail has been added.', 'desc' => '<p>ZenTao CloudMail is a free Email service launched jointly with SendCloud. Once binded with ZenTao and passed verification, users can use this service.</p>');
|
||||
|
||||
@@ -22,8 +22,9 @@
|
||||
</div>
|
||||
<form method='post' target='hiddenwin'>
|
||||
<table align='center' class='table table-form w-320px'>
|
||||
<?php $thWidth = (isset($config->isINT) and $config->isINT) ? 'w-130px' : 'w-90px';?>
|
||||
<tr>
|
||||
<th class='rowhead w-90px'><?php echo $lang->user->account;?></th>
|
||||
<th class='rowhead <?php echo $thWidth?>'><?php echo $lang->user->account;?></th>
|
||||
<td><?php echo $user->account . html::hidden('account',$user->account);?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -57,6 +57,8 @@ class product extends control
|
||||
$branch = (int)$this->cookie->preBranch;
|
||||
$this->product->setMenu($this->products, $productID, $branch);
|
||||
|
||||
if(common::hasPriv('product', 'create')) $this->lang->modulePageActions = html::a($this->createLink('product', 'create'), "<i class='icon icon-sm icon-plus'></i> " . $this->lang->product->create, '', "class='btn btn-primary'");
|
||||
|
||||
$this->view->title = $this->lang->product->index;
|
||||
$this->view->position[] = $this->lang->product->index;
|
||||
$this->display();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.branch-list {padding-left: 0; margin: 0;}
|
||||
.branch-list > li {float: left; list-style: none; width: 50%; margin: 5px 0;}
|
||||
.data-basic.table-data tbody > tr > th {width: 80px;}
|
||||
.data-basic.table-data tbody > tr > th {width: 100px;}
|
||||
.block-release .panel-body, .block-dynamic .panel-body {height: 240px; overflow-x: hidden; overflow-y: auto; position: relative;}
|
||||
.block-release .panel-body {padding-bottom: 50px;}
|
||||
.block-release .panel-body > .btn.pull-right {position: absolute; right: 20px; bottom: 20px;}
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php if($this->app->getClientLang() == 'en'):?>
|
||||
<style>.side-col .cell table th{width: 100px !important}</style>
|
||||
<?php endif;?>
|
||||
<div id='mainContent' class="main-row">
|
||||
<div class="col-8 main-col">
|
||||
<div class="row">
|
||||
@@ -134,7 +137,7 @@
|
||||
<table class="table table-data">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th><i class="icon icon-person icon-sm"></i> <?php echo $lang->productCommon;?></th>
|
||||
<th class='w-100px'><i class="icon icon-person icon-sm"></i> <?php echo $lang->productCommon;?></th>
|
||||
<td><em><?php echo zget($users, $product->PO);?></em></td>
|
||||
<th><i class="icon icon-person icon-sm"></i> <?php echo $lang->product->qa;?></th>
|
||||
<td><em><?php echo zget($users, $product->QD);?></em></td>
|
||||
@@ -191,8 +194,9 @@
|
||||
<div class="detail-content">
|
||||
<table class="table table-data data-basic">
|
||||
<tbody>
|
||||
<?php $space = $this->app->getClientLang() == 'en' ? ' ' : '';?>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->statusList['active'] . $lang->story->common;?></th>
|
||||
<th><?php echo $lang->story->statusList['active'] . $space . $lang->story->common;?></th>
|
||||
<td><em><?php echo $product->stories['active']?></em></td>
|
||||
<th><?php echo $lang->product->plans?></th>
|
||||
<td><em><?php echo $product->plans?></em></td>
|
||||
@@ -200,7 +204,7 @@
|
||||
<td><em><?php echo $product->bugs?></em></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->statusList['changed'] . $lang->story->common;?></th>
|
||||
<th><?php echo $lang->story->statusList['changed'] . $space . $lang->story->common;?></th>
|
||||
<td><em><?php echo $product->stories['changed']?></em></td>
|
||||
<th><?php echo $lang->product->projects?></th>
|
||||
<td><em><?php echo $product->projects?></em></td>
|
||||
@@ -208,7 +212,7 @@
|
||||
<td><em><?php echo $product->cases?></em></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->statusList['draft'] . $lang->story->common;?></th>
|
||||
<th><?php echo $lang->story->statusList['draft'] . $space . $lang->story->common;?></th>
|
||||
<td><em><?php echo $product->stories['draft']?></em></td>
|
||||
<th><?php echo $lang->product->builds?></th>
|
||||
<td><em><?php echo $product->builds?></em></td>
|
||||
@@ -216,7 +220,7 @@
|
||||
<td><em><?php echo $product->docs?></em></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->story->statusList['closed'] . $lang->story->common;?></th>
|
||||
<th><?php echo $lang->story->statusList['closed'] . $space . $lang->story->common;?></th>
|
||||
<td><em><?php echo $product->stories['closed']?></em></td>
|
||||
<th><?php echo $lang->product->releases?></th>
|
||||
<td><em><?php echo $product->releases?></em></td>
|
||||
@@ -232,7 +236,6 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="mainActions" class='main-actions'>
|
||||
<nav class="container"></nav>
|
||||
</div>
|
||||
|
||||
@@ -9,6 +9,8 @@ function showLink(planID, type, orderBy, param)
|
||||
$linkBox.find('[data-ride="table"]').table();
|
||||
$.toggleQueryBox(true, $linkBox.find('#queryBox'));
|
||||
});
|
||||
|
||||
$('.actions').find("a[href*='" + type + "']").addClass('hidden');
|
||||
}
|
||||
|
||||
$(function()
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
<?php if($unlinkedCount):?>
|
||||
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
|
||||
<div class="table-actions btn-toolbar">
|
||||
<?php echo html::submitButton($lang->productplan->linkBug, '', 'btn');?>
|
||||
<?php echo html::submitButton($lang->productplan->linkBug, '', 'btn btn-secondary');?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<div class="btn-toolbar">
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
<?php if($unlinkedCount):?>
|
||||
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
|
||||
<div class="table-actions btn-toolbar">
|
||||
<?php echo html::submitButton($lang->productplan->linkStory, '', 'btn');?>
|
||||
<?php echo html::submitButton($lang->productplan->linkStory, '', 'btn btn-secondary');?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<div class="btn-toolbar">
|
||||
|
||||
@@ -37,22 +37,7 @@
|
||||
<?php
|
||||
if(!$plan->deleted)
|
||||
{
|
||||
echo "<div class='btn-group' id='createActionMenu'>";
|
||||
$batchMisc = common::hasPriv('story', 'batchCreate') ? 'btn btn-link' : "disabled";
|
||||
$batchLink = common::hasPriv('story', 'batchCreate') ? $this->createLink('story', 'batchCreate', "productID=$plan->product&branch=$plan->branch&moduleID=0&story=0&project=0&plan={$plan->id}") : '#';
|
||||
echo html::a($batchLink, "<i class='icon icon-plus'></i><span class='text'>" . $lang->story->batchCreate . '</span>', '', "class='$batchMisc'");
|
||||
common::printIcon('story', 'create', "productID=$plan->product&branch=$plan->branch&moduleID=0&storyID=0&projectID=0&bugID=0&planID=$plan->id", $plan, 'button', 'plus');
|
||||
echo "</div>";
|
||||
|
||||
if(common::hasPriv('productplan', 'linkStory'))
|
||||
{
|
||||
echo html::a(inlink('view', "planID=$plan->id&type=story&orderBy=id_desc&link=true"), '<i class="icon-link"></i> ' . $lang->productplan->linkStory, '', "class='btn btn-link'");
|
||||
}
|
||||
if(common::hasPriv('productplan', 'linkBug') and $config->global->flow != 'onlyStory')
|
||||
{
|
||||
echo html::a(inlink('view', "planID=$plan->id&type=bug&orderBy=id_desc&link=true"), '<i class="icon-bug"></i> ' . $lang->productplan->linkBug, '', "class='btn btn-link'");
|
||||
}
|
||||
if(common::hasPriv('productplan', 'create') and $plan->parent <= '0') echo html::a($this->createLink('productplan', 'create', "product={$plan->product}&branch={$plan->branch}&parent={$plan->id}"), "<i class='icon-treemap-alt'></i>", '', "class='btn btn-link' title='{$this->lang->productplan->children}'");
|
||||
if(common::hasPriv('productplan', 'create') and $plan->parent <= '0') echo html::a($this->createLink('productplan', 'create', "product={$plan->product}&branch={$plan->branch}&parent={$plan->id}"), "<i class='icon-treemap-alt'></i>" . $this->lang->productplan->children , '', "class='btn btn-link' title='{$this->lang->productplan->children}'");
|
||||
common::printIcon('productplan', 'edit', "planID=$plan->id", $plan);
|
||||
common::printIcon('productplan', 'delete', "planID=$plan->id", $plan, 'button', 'trash', 'hiddenwin');
|
||||
}
|
||||
@@ -71,12 +56,22 @@
|
||||
<div class='tab-content'>
|
||||
<div id='stories' class='tab-pane <?php if($type == 'story') echo 'active'?>'>
|
||||
<?php $canOrder = common::hasPriv('project', 'storySort');?>
|
||||
<?php if(common::hasPriv('productplan', 'linkStory')):?>
|
||||
<div class='actions'>
|
||||
<?php echo html::a("javascript:showLink($plan->id, \"story\")", '<i class="icon-link"></i> ' . $lang->productplan->linkStory, '', "class='btn btn-primary'");?>
|
||||
<?php
|
||||
if(!$plan->deleted)
|
||||
{
|
||||
$batchMisc = common::hasPriv('story', 'batchCreate') ? 'btn btn-link' : "disabled";
|
||||
$batchLink = common::hasPriv('story', 'batchCreate') ? $this->createLink('story', 'batchCreate', "productID=$plan->product&branch=$plan->branch&moduleID=0&story=0&project=0&plan={$plan->id}") : '#';
|
||||
echo html::a($batchLink, "<i class='icon icon-sitemap'></i><span class='text'>" . $lang->story->batchCreate . '</span>', '', "class='$batchMisc'");
|
||||
common::printIcon('story', 'create', "productID=$plan->product&branch=$plan->branch&moduleID=0&storyID=0&projectID=0&bugID=0&planID=$plan->id", $plan, 'button', 'plus');
|
||||
}
|
||||
if(common::hasPriv('productplan', 'linkStory')) echo html::a("javascript:showLink($plan->id, \"story\")", '<i class="icon-link"></i> ' . $lang->productplan->linkStory, '', "class='btn btn-primary'");
|
||||
?>
|
||||
</div>
|
||||
<?php if(common::hasPriv('productplan', 'linkStory')):?>
|
||||
<div class='linkBox cell hidden'></div>
|
||||
<?php endif;?>
|
||||
|
||||
<form class='main-table table-story' data-ride='table' method='post' target='hiddenwin' action="<?php echo inlink('batchUnlinkStory', "planID=$plan->id&orderBy=$orderBy");?>">
|
||||
<table class='table has-sort-head' id='storyList'>
|
||||
<?php
|
||||
|
||||
@@ -45,6 +45,8 @@ class project extends control
|
||||
if($this->app->viewType != 'mhtml') unset($this->lang->project->menu->index);
|
||||
$this->commonAction($projectID);
|
||||
//$this->project->setMenu($this->projects, key($this->projects));
|
||||
|
||||
if(common::hasPriv('project', 'create')) $this->lang->modulePageActions = html::a($this->createLink('project', 'create'), "<i class='icon icon-sm icon-plus'></i> " . $this->lang->project->create, '', "class='btn btn-primary'");
|
||||
|
||||
$this->view->title = $this->lang->project->index;
|
||||
$this->view->position[] = $this->lang->project->index;
|
||||
@@ -1051,7 +1053,7 @@ class project extends control
|
||||
$this->project->updateProducts($projectID);
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
|
||||
$this->loadModel('action')->create('project', $projectID, 'opened');
|
||||
$this->loadModel('action')->create('project', $projectID, 'opened', '', join(',', $_POST['products']));
|
||||
|
||||
$planID = reset($_POST['plans']);
|
||||
if(!empty($planID))
|
||||
@@ -1709,7 +1711,7 @@ class project extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function manageProducts($projectID, $from='')
|
||||
public function manageProducts($projectID, $from = '')
|
||||
{
|
||||
/* use first project if projectID does not exist. */
|
||||
if(!isset($this->projects[$projectID])) $projectID = key($this->projects);
|
||||
@@ -1721,6 +1723,8 @@ class project extends control
|
||||
|
||||
$this->project->updateProducts($projectID);
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
|
||||
$this->loadModel('action')->create('project', $projectID, 'Managed', '', join(',', $_POST['products']));
|
||||
die(js::locate($browseProjectLink));
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
.board-item .btn {padding: 2px 10px 2px 23px; font-size: 12px; position: relative; left: -2px; height: 24px;}
|
||||
.board-item .btn-icon-left > .icon {width: 22px; height: 22px; line-height: 20px; font-size: 14px; opacity: 1; top: 1px}
|
||||
.board-item .btn-icon-left > span {max-width: 80px; white-space: nowrap; text-overflow: ellipsis; overflow: hidden; display: inline-block;}
|
||||
.board-title {padding-right: 20px;}
|
||||
.board-actions {position: absolute; right: 3px; top: 3px;}
|
||||
.board-actions.nav > li > a {padding: 3px 3px;}
|
||||
#kanban {overflow-y: auto}
|
||||
#kanban > .table {min-width: 1100px;}
|
||||
#kanban.dragging .boards.dragging .board {background: #eee; opacity: .35; border-color: #f1f1f1}
|
||||
@@ -43,4 +46,4 @@
|
||||
#kanban .group-title {word-break: break-all; line-height: 16px; padding: 3px 0; display: block;}
|
||||
|
||||
.table-grouped > tbody > tr,
|
||||
.table-grouped > tbody > tr:hover {background: #fff!important;}
|
||||
.table-grouped > tbody > tr:hover {background: #fff!important;}
|
||||
|
||||
@@ -8,3 +8,4 @@
|
||||
#burnLegend > div.line-real:before {background: #006AF1;}
|
||||
|
||||
.block-dynamic .panel-body {height: 230px; overflow: auto; position: relative;}
|
||||
.block-team div.col-xs-6{white-space: nowrap; overflow: hidden;}
|
||||
|
||||
@@ -196,18 +196,4 @@ $(function()
|
||||
});
|
||||
return false;
|
||||
});
|
||||
|
||||
$.extend({'closeModal':function(callback, location)
|
||||
{
|
||||
var ref = $('#triggerModal.modal').attr('ref');
|
||||
if(ref.indexOf('export') > 0 && ref.indexOf('kanban') > 0)
|
||||
{
|
||||
$('#triggerModal').modal('hide');
|
||||
}
|
||||
else
|
||||
{
|
||||
kanbanModalTrigger.close();
|
||||
}
|
||||
if(callback && $.isFunction(callback)) callback();
|
||||
}});
|
||||
});
|
||||
|
||||
@@ -208,7 +208,7 @@ $lang->project->timeSummary = '<div class="table-col"><div class="clearf
|
||||
$lang->project->groupSummaryAB = "<div>Tasks <strong>%s :</strong><span class='text-muted'>Wait</span> %s <span class='text-muted'>Doing</span> %s</div><div>Est. <strong>%s :</strong><span class='text-muted'>Cost</span> %s <span class='text-muted'>Left</span> %s</div>";
|
||||
$lang->project->wbs = "Decompose Task";
|
||||
$lang->project->batchWBS = "Batch Decompose";
|
||||
$lang->project->howToUpdateBurn = "<a href='https://api.zentao.net/goto.php?item=burndown&lang=zh-cn' target='_blank' title='How to Update the Burndown Chart?' class='btn btn-link'>Help <i class='icon icon-help'></i></a>";
|
||||
$lang->project->howToUpdateBurn = "<a href='https://api.zentao.pm/goto.php?item=burndown' target='_blank' title='How to Update the Burndown Chart?' class='btn btn-link'>Help <i class='icon icon-help'></i></a>";
|
||||
$lang->project->whyNoStories = "No Story can be linked. Please check whether there is Story in {$lang->projectCommon} linked {$lang->productCommon} and make sure it has been reviewed.";
|
||||
$lang->project->productStories = "{$lang->projectCommon} linked story is the subeset of {$lang->productCommon}, which can only be linked after review. Please <a href='%s'> Link Story</a>。";
|
||||
$lang->project->haveDraft = "There are %s draft stories can't be linked.";
|
||||
@@ -246,6 +246,11 @@ $lang->project->withweekend = 'incl. Weekend';
|
||||
$lang->project->interval = 'Intervals';
|
||||
$lang->project->fixFirstWithLeft = 'Modify the left';
|
||||
|
||||
$lang->project->action = new stdclass();
|
||||
$lang->project->action->opened = '$date, created by <strong>$actor</strong> .' . "\n";
|
||||
$lang->project->action->managed = '$date, managed by <strong>$actor</strong> .' . "\n";
|
||||
$lang->project->action->extra = 'The related products are %s.';
|
||||
|
||||
/* 统计。*/
|
||||
$lang->project->charts = new stdclass();
|
||||
$lang->project->charts->burn = new stdclass();
|
||||
|
||||
@@ -246,6 +246,11 @@ $lang->project->withweekend = '显示周末';
|
||||
$lang->project->interval = '间隔';
|
||||
$lang->project->fixFirstWithLeft = '修改剩余工时';
|
||||
|
||||
$lang->project->action = new stdclass();
|
||||
$lang->project->action->opened = '$date, 由 <strong>$actor</strong> 创建。$extra' . "\n";
|
||||
$lang->project->action->managed = '$date, 由 <strong>$actor</strong> 维护。$extra' . "\n";
|
||||
$lang->project->action->extra = '相关产品为 %s。';
|
||||
|
||||
/* 统计。*/
|
||||
$lang->project->charts = new stdclass();
|
||||
$lang->project->charts->burn = new stdclass();
|
||||
|
||||
@@ -1698,6 +1698,7 @@ class projectModel extends model
|
||||
foreach($users as $account => $realName)
|
||||
{
|
||||
$firstLetter = ucfirst(substr($account, 0, 1)) . ':';
|
||||
if(isset($this->config->isINT) and $this->config->isINT) $firstLetter = '';
|
||||
$users[$account] = $firstLetter . ($realName ? $realName : $account);
|
||||
}
|
||||
return array('' => '') + $users;
|
||||
|
||||
@@ -113,7 +113,24 @@ $account = $this->app->user->account;
|
||||
<?php if($type == 'story'):?>
|
||||
<?php $story = $group;?>
|
||||
<div class='board-story' data-id='<?php echo $story->id;?>'>
|
||||
<?php echo html::a($this->createLink('story', 'view', "storyID=$story->id", '', true), $story->title, '', 'class="kanbaniframe group-title" title="' . $story->title . '"');?>
|
||||
<div class='board-title'>
|
||||
<?php echo html::a($this->createLink('story', 'view', "storyID=$story->id", '', true), $story->title, '', 'class="kanbaniframe group-title" title="' . $story->title . '"');?>
|
||||
<nav class='board-actions nav nav-default'>
|
||||
<li class='dropdown'>
|
||||
<a href='javascript:;' data-toggle='dropdown' class='panel-action'><i class='icon icon-ellipsis-v'></i></a>
|
||||
<ul class='dropdown-menu pull-right'>
|
||||
<?php
|
||||
$misc = "data-toggle='modal' data-type='iframe' data-width='95%'";
|
||||
echo (common::hasPriv('task', 'create')) ? '<li>' . html::a($this->createLink('task', 'create', "projectID=$story->project&storyID=$story->id&moduleID=$story->module", '', true), $lang->project->wbs, '', $misc) : '' . '</li>';
|
||||
echo (common::hasPriv('task', 'batchCreate')) ? '<li>' . html::a($this->createLink('task', 'batchCreate', "projectID=$story->project&storyID=$story->id&moduleID=0&taskID=0&iframe=true", '', true), $lang->project->batchWBS, '', $misc) : '' . '</li>';
|
||||
echo (common::hasPriv('project', 'unlinkStory')) ? '<li>' . html::a($this->createLink('project', 'unlinkStory', "projectID=$story->project&storyID=$story->story&confirm=no", '', true), $lang->project->unlinkStory, 'hiddenwin') : '' . '</li>';
|
||||
$misc = "data-toggle='modal' data-type='iframe'";
|
||||
echo (common::hasPriv('story', 'close')) ? '<li>' . html::a($this->createLink('story', 'close', "storyID=$story->id", '', true), $lang->story->close, '', $misc) : '' . '</li>';
|
||||
?>
|
||||
</ul>
|
||||
</li>
|
||||
</nav>
|
||||
</div>
|
||||
<div class="small group-info">
|
||||
<span class='story-id board-id' title='<?php echo $lang->story->id?>'>#<?php echo $story->id?></span>
|
||||
<span class='label-pri label-pri-<?php echo $story->pri?>' title='<?php echo $lang->story->pri?>'><?php echo zget($lang->story->priList, $story->pri);?></span>
|
||||
|
||||
@@ -11,6 +11,8 @@ function showLink(releaseID, type, param)
|
||||
$linkBox.find('[data-ride="table"]').table();
|
||||
$.toggleQueryBox(true, $linkBox.find('#queryBox'));
|
||||
});
|
||||
|
||||
$('.actions').find("a[href*='" + type + "']").addClass('hidden');
|
||||
}
|
||||
|
||||
$(function()
|
||||
|
||||
@@ -64,7 +64,7 @@ $formID = $type == 'leftBug' ? 'unlinkedLeftBugsForm' : 'unlinkedBugsForm';
|
||||
<?php if($unlinkedCount):?>
|
||||
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
|
||||
<div class="table-actions btn-toolbar">
|
||||
<?php echo html::submitButton($lang->release->linkBug, '', 'btn');?>
|
||||
<?php echo html::submitButton($lang->release->linkBug, '', 'btn btn-secondary');?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<div class="btn-toolbar">
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
<?php if($unlinkedCount):?>
|
||||
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
|
||||
<div class='table-actions btn-toolbar'>
|
||||
<?php echo html::submitButton($lang->release->linkStory, '', 'btn');?>
|
||||
<?php echo html::submitButton($lang->release->linkStory, '', 'btn btn-secondary');?>
|
||||
</div>
|
||||
<?php endif;?>
|
||||
<div class="btn-toolbar">
|
||||
|
||||
@@ -33,9 +33,6 @@
|
||||
<?php
|
||||
if(!$release->deleted)
|
||||
{
|
||||
if(common::hasPriv('release', 'linkStory')) echo html::a(inlink('view', "releaseID=$release->id&type=story&link=true"), '<i class="icon-link"></i> ' . $lang->release->linkStory, '', "class='btn btn-link'");
|
||||
if(common::hasPriv('release', 'linkBug') and $config->global->flow != 'onlyStory') echo html::a(inlink('view', "releaseID=$release->id&type=bug&link=true"), '<i class="icon-bug"></i> ' . $lang->release->linkBug, '', "class='btn btn-link'");
|
||||
|
||||
if(common::hasPriv('release', 'changeStatus', $release))
|
||||
{
|
||||
$changedStatus = $release->status == 'normal' ? 'terminate' : 'normal';
|
||||
|
||||
@@ -24,7 +24,7 @@ class reportModel extends model
|
||||
{
|
||||
$sum = 0;
|
||||
foreach($datas as $data) $sum += $data->value;
|
||||
foreach($datas as $data) $data->percent = round($data->value / $sum, 2);
|
||||
foreach($datas as $data) $data->percent = round($data->value / $sum, 4);
|
||||
return $datas;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,15 +15,17 @@ $jsRoot = $this->app->getWebRoot() . "js/";
|
||||
include '../../common/view/datepicker.html.php';
|
||||
include '../../common/view/chosen.html.php';
|
||||
$formId = 'searchForm-' . uniqid('');
|
||||
$fieldWidth = $app->getClientLang() == 'en' ? 'w-130px' : 'w-110px';
|
||||
$operatorWidth = $app->getClientLang() == 'en' ? 'w-110px' : 'w-100px';
|
||||
?>
|
||||
<style>
|
||||
#selectPeriod {padding: 4px 0; height: 197px; min-width: 120px}
|
||||
#selectPeriod > .dropdown-header {background: #f1f1f1; display: block; text-align: center; padding: 4px 0; line-height: 20px; margin: 5px 10px; font-size: 14px; border-radius: 2px; color: #333; font-size: 12px}
|
||||
#groupAndOr {display: inline-block;}
|
||||
#<?php echo $formId;?> > table {margin: 0 auto;}
|
||||
#<?php echo $formId;?> > table > tbody > tr > td {padding: 10px 15px;}
|
||||
#<?php echo $formId;?> > table > tbody > tr > td {padding: 8px;}
|
||||
#<?php echo $formId;?> .form-actions {padding-bottom: 20px; padding-top: 0;}
|
||||
#<?php echo $formId;?> .chosen-container[id^="field"] .chosen-drop {min-width: 140px;}
|
||||
#<?php echo $formId;?> .chosen-container[id^="field"] .chosen-drop {min-width: 180px;}
|
||||
#<?php echo $formId;?> [id^="valueBox"] .chosen-container .chosen-single {min-width: 100px;}
|
||||
#<?php echo $formId;?> [id^="valueBox"] .chosen-container .chosen-drop {min-width: 300px;}
|
||||
#<?php echo $formId;?> .chosen-container .chosen-drop ul.chosen-results li {white-space:normal}
|
||||
@@ -91,16 +93,16 @@ foreach($fieldParams as $fieldName => $param)
|
||||
$param = $fieldParams[$currentField];
|
||||
|
||||
/* Print and or. */
|
||||
echo "<td class='text-right w-80px'>";
|
||||
echo "<td class='text-right w-70px'>";
|
||||
if($i == 1) echo "<span id='searchgroup1'><strong>{$lang->search->group1}</strong></span>" . html::hidden("andOr$fieldNO", 'AND');
|
||||
if($i > 1) echo html::select("andOr$fieldNO", $lang->search->andor, $formSession["andOr$fieldNO"], "class='form-control'");
|
||||
echo '</td>';
|
||||
|
||||
/* Print field. */
|
||||
echo "<td class='w-110px' style='overflow: visible'>" . html::select("field$fieldNO", $searchFields, $formSession["field$fieldNO"], "onchange='setField(this, $fieldNO, {$module}params)' class='form-control chosen'") . '</td>';
|
||||
echo "<td class='{$fieldWidth}' style='overflow: visible'>" . html::select("field$fieldNO", $searchFields, $formSession["field$fieldNO"], "onchange='setField(this, $fieldNO, {$module}params)' class='form-control chosen'") . '</td>';
|
||||
|
||||
/* Print operator. */
|
||||
echo "<td class='w-90px'>" . html::select("operator$fieldNO", $lang->search->operators, $formSession["operator$fieldNO"], "class='form-control'") . '</td>';
|
||||
echo "<td class='{$operatorWidth}'>" . html::select("operator$fieldNO", $lang->search->operators, $formSession["operator$fieldNO"], "class='form-control'") . '</td>';
|
||||
|
||||
/* Print value. */
|
||||
echo "<td id='valueBox$fieldNO' style='overflow:visible'>";
|
||||
@@ -129,7 +131,7 @@ foreach($fieldParams as $fieldName => $param)
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
<td class='text-center nobr w-90px'><?php echo html::select('groupAndOr', $lang->search->andor, $formSession['groupAndOr'], "class='form-control'")?></td>
|
||||
<td class='text-center nobr w-80px'><?php echo html::select('groupAndOr', $lang->search->andor, $formSession['groupAndOr'], "class='form-control'")?></td>
|
||||
<td class='w-400px'>
|
||||
<table class='table table-form'>
|
||||
<tbody>
|
||||
@@ -151,16 +153,16 @@ foreach($fieldParams as $fieldName => $param)
|
||||
$param = $fieldParams[$currentField];
|
||||
|
||||
/* Print and or. */
|
||||
echo "<td class='text-right w-80px'>";
|
||||
echo "<td class='text-right w-70px'>";
|
||||
if($i == 1) echo "<span id='searchgroup2'><strong>{$lang->search->group2}</strong></span>" . html::hidden("andOr$fieldNO", 'AND');
|
||||
if($i > 1) echo html::select("andOr$fieldNO", $lang->search->andor, $formSession["andOr$fieldNO"], "class='form-control'");
|
||||
echo '</td>';
|
||||
|
||||
/* Print field. */
|
||||
echo "<td class='w-110px' style='overflow: visible'>" . html::select("field$fieldNO", $searchFields, $formSession["field$fieldNO"], "onchange='setField(this, $fieldNO, {$module}params)' class='form-control chosen'") . '</td>';
|
||||
echo "<td class='{$fieldWidth}' style='overflow: visible'>" . html::select("field$fieldNO", $searchFields, $formSession["field$fieldNO"], "onchange='setField(this, $fieldNO, {$module}params)' class='form-control chosen'") . '</td>';
|
||||
|
||||
/* Print operator. */
|
||||
echo "<td class='w-90px'>" . html::select("operator$fieldNO", $lang->search->operators, $formSession["operator$fieldNO"], "class='form-control'") . '</td>';
|
||||
echo "<td class='{$operatorWidth}'>" . html::select("operator$fieldNO", $lang->search->operators, $formSession["operator$fieldNO"], "class='form-control'") . '</td>';
|
||||
|
||||
/* Print value. */
|
||||
echo "<td id='valueBox$fieldNO'>";
|
||||
|
||||
@@ -3,7 +3,7 @@ $config->story = new stdclass();
|
||||
|
||||
$config->story->batchCreate = 10;
|
||||
$config->story->affectedFixedNum = 7;
|
||||
$config->story->needReview = 1;
|
||||
$config->story->needReview = 1;
|
||||
|
||||
$config->story->batchClose = new stdclass();
|
||||
$config->story->batchClose->columns = 10;
|
||||
@@ -26,6 +26,7 @@ $config->story->editor->view = array('id' => 'comment,lastComment', 'tools'
|
||||
$config->story->editor->close = array('id' => 'comment', 'tools' => 'simpleTools');
|
||||
$config->story->editor->review = array('id' => 'comment', 'tools' => 'simpleTools');
|
||||
$config->story->editor->activate = array('id' => 'comment', 'tools' => 'simpleTools');
|
||||
$config->story->editor->assignto = array('id' => 'comment', 'tools' => 'simpleTools');
|
||||
|
||||
$config->story->list = new stdclass();
|
||||
$config->story->list->exportFields = '
|
||||
|
||||
@@ -1037,6 +1037,44 @@ class story extends control
|
||||
if(!dao::isError()) $this->loadModel('score')->create('ajax', 'batchOther');
|
||||
die(js::locate($this->session->storyList, 'parent'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign to.
|
||||
*
|
||||
* @param int $storyID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function assignTo($storyID)
|
||||
{
|
||||
if(!empty($_POST))
|
||||
{
|
||||
$changes = $this->story->assign($storyID);
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
if($changes)
|
||||
{
|
||||
$actionID = $this->loadModel('action')->create('story', $storyID, 'Assigned', $this->post->comment, $this->post->assignedTo);
|
||||
$this->action->logHistory($actionID, $changes);
|
||||
}
|
||||
|
||||
if(isonlybody()) die(js::closeModal('parent.parent', 'this'));
|
||||
die(js::locate($this->createLink('story', 'view', "storyID=$storyID"), 'parent'));
|
||||
}
|
||||
|
||||
/* Get story and product. */
|
||||
$story = $this->story->getById($storyID);
|
||||
$products = $this->product->getPairs();
|
||||
|
||||
/* Set menu. */
|
||||
$this->product->setMenu($products, $story->product, $story->branch);
|
||||
|
||||
$this->view->title = zget($products, $story->product, '') . $this->lang->colon . $this->lang->story->assign;
|
||||
$this->view->position[] = $this->lang->story->assign;
|
||||
$this->view->story = $story;
|
||||
$this->view->actions = $this->action->getList('story', $storyID);
|
||||
$this->view->users = $this->loadModel('user')->getPairs('nodeleted|noclosed|pofirst|noletter');
|
||||
$this->display();
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch assign to.
|
||||
|
||||
@@ -13,6 +13,7 @@ $lang->story->create = "Add Story";
|
||||
$lang->story->batchCreate = "Batch Add";
|
||||
$lang->story->change = "Change";
|
||||
$lang->story->changed = 'Change';
|
||||
$lang->story->assignTo = 'Assign';
|
||||
$lang->story->review = 'Review';
|
||||
$lang->story->batchReview = 'Batch Review';
|
||||
$lang->story->edit = "Edit";
|
||||
@@ -58,6 +59,7 @@ $lang->story->sourceNote = 'Note';
|
||||
$lang->story->fromBug = 'From Bug';
|
||||
$lang->story->title = 'Title';
|
||||
$lang->story->spec = 'Description';
|
||||
$lang->story->assign = 'Assign';
|
||||
$lang->story->verify = 'Acceptance';
|
||||
$lang->story->pri = 'Priority';
|
||||
$lang->story->estimate = 'Est.(h)';
|
||||
|
||||
@@ -13,6 +13,7 @@ $lang->story->create = "提需求";
|
||||
$lang->story->batchCreate = "批量创建";
|
||||
$lang->story->change = "变更";
|
||||
$lang->story->changed = '需求变更';
|
||||
$lang->story->assignTo = '指派';
|
||||
$lang->story->review = '评审';
|
||||
$lang->story->batchReview = '批量评审';
|
||||
$lang->story->edit = "编辑";
|
||||
@@ -58,6 +59,7 @@ $lang->story->sourceNote = '来源备注';
|
||||
$lang->story->fromBug = '来源Bug';
|
||||
$lang->story->title = '需求名称';
|
||||
$lang->story->spec = '需求描述';
|
||||
$lang->story->assign = '指派给';
|
||||
$lang->story->verify = '验收标准';
|
||||
$lang->story->pri = '优先级';
|
||||
$lang->story->estimate = '预计工时';
|
||||
|
||||
@@ -1056,6 +1056,31 @@ class storyModel extends model
|
||||
return $allChanges;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign story.
|
||||
*
|
||||
* @param int $storyID
|
||||
* @access public
|
||||
* @return array
|
||||
*/
|
||||
public function assign($storyID)
|
||||
{
|
||||
$oldStory = $this->dao->findById($storyID)->from(TABLE_STORY)->fetch();
|
||||
$now = helper::now();
|
||||
$assignedTo = $this->post->assignedTo;
|
||||
if($assignedTo == $oldStory->assignedTo) return array();
|
||||
|
||||
$story = new stdclass();
|
||||
$story->lastEditedBy = $this->app->user->account;
|
||||
$story->lastEditedDate = $now;
|
||||
$story->assignedTo = $assignedTo;
|
||||
$story->assignedDate = $now;
|
||||
|
||||
$this->dao->update(TABLE_STORY)->data($story)->autoCheck()->where('id')->eq((int)$storyID)->exec();
|
||||
if(!dao::isError()) return common::createChanges($oldStory, $story);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Batch assign to.
|
||||
*
|
||||
@@ -2254,6 +2279,7 @@ class storyModel extends model
|
||||
if($action == 'review') return $story->status == 'draft' or $story->status == 'changed';
|
||||
if($action == 'close') return $story->status != 'closed';
|
||||
if($action == 'activate') return $story->status == 'closed';
|
||||
if($action == 'assignto') return $story->status != 'closed';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* The complete file of story 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 Yidong Wang <yidong@cnezsoft.com>
|
||||
* @package story
|
||||
* @version $Id: complete.html.php 935 2010-07-06 07:49:24Z jajacn@126.com $
|
||||
* @link http://www.zentao.net
|
||||
*/
|
||||
?>
|
||||
<?php include '../../common/view/header.html.php';?>
|
||||
<?php include '../../common/view/kindeditor.html.php';?>
|
||||
<div id='mainContent' class='main-content'>
|
||||
<div class='center-block'>
|
||||
<div class='main-header'>
|
||||
<h2>
|
||||
<span class='label label-id'><?php echo $story->id;?></span>
|
||||
<?php echo isonlybody() ? ("<span title='$story->title'>" . $story->title . '</span>') : html::a($this->createLink('story', 'view', 'story=' . $story->id), $story->title);?>
|
||||
<?php if(!isonlybody()):?>
|
||||
<small> <?php echo $lang->arrow . $lang->story->assignTo;?></small>
|
||||
<?php endif;?>
|
||||
</h2>
|
||||
</div>
|
||||
<form method='post' target='hiddenwin'>
|
||||
<table class='table table-form'>
|
||||
<tr>
|
||||
<th class='w-80px'><?php echo $lang->story->assign;?></th>
|
||||
<td class='w-p25-f'><?php echo html::select('assignedTo', $users, $story->assignedTo, "class='form-control chosen'");?></td><td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->comment;?></th>
|
||||
<td colspan='2'><?php echo html::textarea('comment', '', "rows='6' class='form-control w-p98'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan='3' class='text-center form-actions'>
|
||||
<?php echo html::submitButton();?>
|
||||
<?php echo html::linkButton($lang->goback, $this->session->storyList, '', '', 'btn btn-wide');?>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<hr class='small' />
|
||||
<?php include '../../common/view/action.html.php';?>
|
||||
</div>
|
||||
</div>
|
||||
<?php include '../../common/view/footer.html.php';?>
|
||||
@@ -78,6 +78,7 @@
|
||||
if(common::hasPriv('story', 'batchCreate')) echo html::a($link, "<i class='icon icon-sitemap'></i> " . $lang->story->subdivide, '', $misc);
|
||||
}
|
||||
|
||||
common::printIcon('story', 'assignTo', "storyID=$story->id", $story, 'button', '', '', 'iframe showinonlybody', true);
|
||||
common::printIcon('story', 'close', "storyID=$story->id", $story, 'button', '', '', 'iframe showinonlybody', true);
|
||||
common::printIcon('story', 'activate', "storyID=$story->id", $story, 'button', '', '', 'iframe showinonlybody', true);
|
||||
|
||||
|
||||
+12
-7
@@ -125,12 +125,7 @@ class task extends control
|
||||
}
|
||||
|
||||
/* If link from no head then reload*/
|
||||
if(isonlybody())
|
||||
{
|
||||
$response['locate'] = 'reload';
|
||||
$response['target'] = 'parent';
|
||||
$this->send($response);
|
||||
}
|
||||
if(isonlybody()) $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true));
|
||||
|
||||
if($todoID > 0)
|
||||
{
|
||||
@@ -177,6 +172,14 @@ class task extends control
|
||||
$members = $this->project->getTeamMemberPairs($projectID, 'nodeleted');
|
||||
$moduleOptionMenu = $this->tree->getTaskOptionMenu($projectID);
|
||||
|
||||
/* Get no test stories. */
|
||||
$testStoryIdList = $this->dao->select('story')->from(TABLE_TASK)->where('project')->eq($projectID)->andWhere('story')->in(array_keys($stories))->fetchPairs('story', 'story');
|
||||
$noTestStories = array();
|
||||
foreach($stories as $id => $title)
|
||||
{
|
||||
if(!isset($testStoryIdList[$id])) $noTestStories[$id] = $title;
|
||||
}
|
||||
|
||||
$title = $project->name . $this->lang->colon . $this->lang->task->create;
|
||||
$position[] = html::a($taskLink, $project->name);
|
||||
$position[] = $this->lang->task->common;
|
||||
@@ -196,6 +199,7 @@ class task extends control
|
||||
$this->view->task = $task;
|
||||
$this->view->users = $users;
|
||||
$this->view->stories = $stories;
|
||||
$this->view->noTestStories = $noTestStories;
|
||||
$this->view->members = $members;
|
||||
$this->view->moduleOptionMenu = $moduleOptionMenu;
|
||||
$this->display();
|
||||
@@ -235,7 +239,7 @@ class task extends control
|
||||
if(dao::isError()) $this->send(array('result' => 'fail', 'message' => dao::getError()));
|
||||
|
||||
/* Locate the browser. */
|
||||
if(!empty($iframe)) $this->send(array('result' => 'success', 'locate' => 'parent'));
|
||||
if(!empty($iframe)) $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent'));
|
||||
$this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $storyLink));
|
||||
}
|
||||
|
||||
@@ -1271,6 +1275,7 @@ class task extends control
|
||||
if($this->session->taskOnlyCondition)
|
||||
{
|
||||
$tasks = $this->dao->select('*')->from(TABLE_TASK)->alias('t1')->where($this->session->taskQueryCondition)
|
||||
->andWhere('parent')->le(0)
|
||||
->beginIF($this->post->exportType == 'selected')->andWhere('t1.id')->in($this->cookie->checkedItem)->fi()
|
||||
->orderBy($sort)->fetchAll('id');
|
||||
|
||||
|
||||
@@ -7,3 +7,8 @@
|
||||
|
||||
.pri-selector > .btn {padding: 5px 8px!important; width: 100%;}
|
||||
.pri-selector > .dropdown-menu {padding: 10px;}
|
||||
|
||||
#testStoryBox table tr td{padding:0px;}
|
||||
#testStoryBox table tr td .chosen-container .chosen-single{border:0px;}
|
||||
#testStoryBox table tr td input{border:0px;}
|
||||
#testStoryBox table tr td .input-group .input-group-addon{border-left:1px solid #dcdcdc;border-right:1px solid #dcdcdc;}
|
||||
|
||||
@@ -230,6 +230,48 @@ function setStories(moduleID, projectID)
|
||||
});
|
||||
}
|
||||
|
||||
function toggleSelectTestStory()
|
||||
{
|
||||
if(!$('#selectTestStoryBox').hasClass('hidden') && $('#selectTestStory').prop('checked'))
|
||||
{
|
||||
$('#module').closest('tr').addClass('hidden');
|
||||
$('#multipleBox').closest('td').addClass('hidden');
|
||||
$('#story').closest('tr').addClass('hidden');
|
||||
$('#estStarted').closest('tr').addClass('hidden');
|
||||
$('#estimate').closest('.table-col').addClass('hidden');
|
||||
$('#testStoryBox').removeClass('hidden');
|
||||
}
|
||||
else
|
||||
{
|
||||
$('#module').closest('tr').removeClass('hidden');
|
||||
$('#multipleBox').closest('td').removeClass('hidden');
|
||||
$('#story').closest('tr').removeClass('hidden');
|
||||
$('#estStarted').closest('tr').removeClass('hidden');
|
||||
$('#estimate').closest('.table-col').removeClass('hidden');
|
||||
$('#testStoryBox').addClass('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
function addItem(obj)
|
||||
{
|
||||
var $tr = $(obj).closest('tr');
|
||||
$tr.after($tr.clone());
|
||||
var $nextTr = $tr.next();
|
||||
$nextTr.find('#testAssignedTo').val($('#assignedTo').val());
|
||||
$nextTr.find('#testStory').closest('td').find('.chosen-container').remove();
|
||||
$nextTr.find('#testStory').closest('td').find('select').chosen();
|
||||
$nextTr.find('#testPri').closest('td').find('.chosen-container').remove();
|
||||
$nextTr.find('#testPri').closest('td').find('select').chosen();
|
||||
$nextTr.find('#testAssignedTo').closest('td').find('.chosen-container').remove();
|
||||
$nextTr.find('#testAssignedTo').closest('td').find('select').chosen();
|
||||
$nextTr.find('.form-date').datepicker();
|
||||
}
|
||||
|
||||
function removeItem(obj)
|
||||
{
|
||||
if($(obj).closest('table').find('tbody tr').size() > 1) $(obj).closest('tr').remove();
|
||||
}
|
||||
|
||||
$(document).ready(function()
|
||||
{
|
||||
$('#pri').on('change', function()
|
||||
@@ -239,11 +281,16 @@ $(document).ready(function()
|
||||
var value = $select.val();
|
||||
$selector.find('.pri-text').html('<span class="label-pri label-pri-' + value + '" title="' + value + '">' + value + '</span>');
|
||||
});
|
||||
$('#type').change(function()
|
||||
{
|
||||
$('#selectTestStoryBox').toggleClass('hidden', $(this).val() != 'test');
|
||||
toggleSelectTestStory();
|
||||
});
|
||||
|
||||
setStoryRelated();
|
||||
|
||||
$('#selectAllUser').on('click', function()
|
||||
{
|
||||
{
|
||||
var $assignedTo = $('#assignedTo');
|
||||
if($assignedTo.attr('multiple'))
|
||||
{
|
||||
@@ -273,7 +320,6 @@ $(document).ready(function()
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/* Init task team manage dialog */
|
||||
var $taskTeamEditor = $('#taskTeamEditor').batchActionForm(
|
||||
{
|
||||
|
||||
+11
-8
@@ -68,8 +68,8 @@ $lang->task->datePlan = 'Plan';
|
||||
$lang->task->estStarted = 'Plan Start';
|
||||
$lang->task->realStarted = 'Actual Start';
|
||||
$lang->task->date = 'Date';
|
||||
$lang->task->deadline = 'Deadline';
|
||||
$lang->task->deadlineAB = 'Deadline';
|
||||
$lang->task->deadline = 'Plan End';
|
||||
$lang->task->deadlineAB = 'Plan End';
|
||||
$lang->task->status = 'Status';
|
||||
$lang->task->desc = 'Description';
|
||||
$lang->task->assign = 'Assign';
|
||||
@@ -81,10 +81,10 @@ $lang->task->assignedDate = 'Assigned';
|
||||
$lang->task->openedBy = 'Created by';
|
||||
$lang->task->openedDate = 'Created';
|
||||
$lang->task->openedDateAB = 'Add';
|
||||
$lang->task->finishedBy = 'Finished by';
|
||||
$lang->task->finishedByAB = 'Finisher';
|
||||
$lang->task->finishedDate = 'Finished';
|
||||
$lang->task->finishedDateAB = 'Finished';
|
||||
$lang->task->finishedBy = 'End By';
|
||||
$lang->task->finishedByAB = 'End By';
|
||||
$lang->task->finishedDate = 'Actual End';
|
||||
$lang->task->finishedDateAB = 'Actual End';
|
||||
$lang->task->finishedList = 'FinishedBy list';
|
||||
$lang->task->canceledBy = 'Cancelled by';
|
||||
$lang->task->canceledDate = 'Cancelled';
|
||||
@@ -106,14 +106,17 @@ $lang->task->team = 'Team';
|
||||
$lang->task->transfer = 'Transfer';
|
||||
$lang->task->transferTo = 'Transfer To';
|
||||
$lang->task->children = 'Child Task';
|
||||
$lang->task->unlinkParent = 'Unlink Parent';
|
||||
$lang->task->childrenAB = 'Child';
|
||||
$lang->task->parent = 'Parent Task';
|
||||
$lang->task->parentAB = 'Parent Task';
|
||||
$lang->task->lblPri = 'P';
|
||||
$lang->task->lblHour = '(h)';
|
||||
$lang->task->lblTestStory = 'Test Story';
|
||||
|
||||
$lang->task->ditto = 'Ditto';
|
||||
$lang->task->dittoNotice = "This Task does not belong to the Project as the previous one does!";
|
||||
$lang->task->selectTestStory = 'Select Test Story';
|
||||
$lang->task->selectAllUser = 'All';
|
||||
$lang->task->noStory = 'No Story';
|
||||
$lang->task->noAssigned = 'Unassigned';
|
||||
@@ -270,5 +273,5 @@ $lang->task->report->tasksPerConsumed->graph->xAxisName = 'Cost';
|
||||
$lang->task->report->tasksPerFinishedBy->graph->xAxisName = 'User';
|
||||
$lang->task->report->tasksPerClosedReason->graph->xAxisName = 'Close Reason';
|
||||
|
||||
$lang->task->report->finishedTasksPerDay->type = 'bar';
|
||||
$lang->task->report->finishedTasksPerDay->graph->xAxisName = 'Date';
|
||||
$lang->task->report->finishedTasksPerDay->type = 'bar';
|
||||
$lang->task->report->finishedTasksPerDay->graph->xAxisName = 'Date';
|
||||
|
||||
@@ -68,7 +68,7 @@ $lang->task->datePlan = '日程规划';
|
||||
$lang->task->estStarted = '预计开始';
|
||||
$lang->task->realStarted = '实际开始';
|
||||
$lang->task->date = '日期';
|
||||
$lang->task->deadline = '截止日期';
|
||||
$lang->task->deadline = '计划完成';
|
||||
$lang->task->deadlineAB = '截止';
|
||||
$lang->task->status = '任务状态';
|
||||
$lang->task->desc = '任务描述';
|
||||
@@ -83,8 +83,8 @@ $lang->task->openedDate = '创建日期';
|
||||
$lang->task->openedDateAB = '创建';
|
||||
$lang->task->finishedBy = '由谁完成';
|
||||
$lang->task->finishedByAB = '完成者';
|
||||
$lang->task->finishedDate = '完成时间';
|
||||
$lang->task->finishedDateAB = '完成时间';
|
||||
$lang->task->finishedDate = '实际完成';
|
||||
$lang->task->finishedDateAB = '实际完成';
|
||||
$lang->task->finishedList = '完成者列表';
|
||||
$lang->task->canceledBy = '由谁取消';
|
||||
$lang->task->canceledDate = '取消时间';
|
||||
@@ -106,14 +106,17 @@ $lang->task->team = '团队';
|
||||
$lang->task->transfer = '转交';
|
||||
$lang->task->transferTo = '转交给';
|
||||
$lang->task->children = '子任务';
|
||||
$lang->task->unlinkParent = '取消子任务';
|
||||
$lang->task->childrenAB = '子';
|
||||
$lang->task->parent = '父任务';
|
||||
$lang->task->parentAB = '父';
|
||||
$lang->task->lblPri = 'P';
|
||||
$lang->task->lblHour = '(h)';
|
||||
$lang->task->lblTestStory = '测试需求';
|
||||
|
||||
$lang->task->ditto = '同上';
|
||||
$lang->task->dittoNotice = "该任务与上一任务不属于同一项目!";
|
||||
$lang->task->selectTestStory = '选择测试需求';
|
||||
$lang->task->selectAllUser = '全部';
|
||||
$lang->task->noStory = '无需求';
|
||||
$lang->task->noAssigned = '未指派';
|
||||
|
||||
+53
-6
@@ -42,7 +42,7 @@ class taskModel extends model
|
||||
->setDefault('openedDate', helper::now())
|
||||
->stripTags($this->config->task->editor->create['id'], $this->config->allowedTags)
|
||||
->join('mailto', ',')
|
||||
->remove('after,files,labels,assignedTo,uid,storyEstimate,storyDesc,storyPri,team,teamEstimate,teamMember,multiple,teams,contactListMenu')
|
||||
->remove('after,files,labels,assignedTo,uid,storyEstimate,storyDesc,storyPri,team,teamEstimate,teamMember,multiple,teams,contactListMenu,selectTestStory,testStory,testPri,testEstStarted,testDeadline,testAssignedTo,testEstimate')
|
||||
->get();
|
||||
|
||||
foreach($this->post->assignedTo as $assignedTo)
|
||||
@@ -67,11 +67,20 @@ class taskModel extends model
|
||||
$task = $this->file->processImgURL($task, $this->config->task->editor->create['id'], $this->post->uid);
|
||||
|
||||
/* Fix Bug #1525 */
|
||||
$projectType =$this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($projectID)->fetch('type');
|
||||
$requiredFields =explode(',', $this->config->task->create->requiredFields);
|
||||
if($projectType == 'ops')unset($requiredFields[array_search("story", $requiredFields)]);
|
||||
$requiredFields =implode(',', $requiredFields);
|
||||
$projectType = $this->dao->select('*')->from(TABLE_PROJECT)->where('id')->eq($projectID)->fetch('type');
|
||||
$requiredFields = "," . $this->config->task->create->requiredFields . ",";
|
||||
if($projectType == 'ops') $requiredFields = str_replace(",story,", ',', "$requiredFields");
|
||||
if($this->post->selectTestStory)
|
||||
{
|
||||
$requiredFields = str_replace(",estimate,", ',', "$requiredFields");
|
||||
$requiredFields = str_replace(",story,", ',', "$requiredFields");
|
||||
$requiredFields = str_replace(",estStarted,", ',', "$requiredFields");
|
||||
$requiredFields = str_replace(",deadline,", ',', "$requiredFields");
|
||||
}
|
||||
$requiredFields = trim($requiredFields, ',');
|
||||
|
||||
/* Fix Bug #2466 */
|
||||
if($this->post->multiple) $task->assignedTo = '';
|
||||
$this->dao->insert(TABLE_TASK)->data($task)
|
||||
->autoCheck()
|
||||
->batchCheck($requiredFields, 'notempty')
|
||||
@@ -83,6 +92,37 @@ class taskModel extends model
|
||||
|
||||
$taskID = $this->dao->lastInsertID();
|
||||
if($this->post->story) $this->loadModel('story')->setStage($this->post->story);
|
||||
if($this->post->selectTestStory)
|
||||
{
|
||||
$testStoryIdList = array();
|
||||
$this->loadModel('action');
|
||||
foreach($this->post->testStory as $storyID)
|
||||
{
|
||||
if($storyID) $testStoryIdList[$storyID] = $storyID;
|
||||
}
|
||||
$testStories = $this->dao->select('id,title')->from(TABLE_STORY)->where('id')->in($testStoryIdList)->fetchPairs('id', 'title');
|
||||
foreach($this->post->testStory as $i => $storyID)
|
||||
{
|
||||
if(!isset($testStories[$storyID])) continue;
|
||||
|
||||
$task->parent = $taskID;
|
||||
$task->story = $storyID;
|
||||
$task->name = $this->lang->task->lblTestStory . " #{$storyID} " . zget($testStories, $storyID);
|
||||
$task->pri = $this->post->testPri[$i];
|
||||
$task->estStarted = $this->post->testEstStarted[$i];
|
||||
$task->deadline = $this->post->testDeadline[$i];
|
||||
$task->assignedTo = $this->post->testAssignedTo[$i];
|
||||
$task->estimate = $this->post->testEstimate[$i];
|
||||
$this->dao->insert(TABLE_TASK)->data($task)->exec();
|
||||
|
||||
$childTaskID = $this->dao->lastInsertID();
|
||||
$this->action->create('task', $childTaskID, 'Opened');
|
||||
}
|
||||
|
||||
$this->computeWorkingHours($taskID);
|
||||
$this->computeBeginAndEnd($taskID);
|
||||
$this->dao->update(TABLE_TASK)->set('parent')->eq(-1)->where('id')->eq($taskID)->exec();
|
||||
}
|
||||
$this->file->updateObjectID($this->post->uid, $taskID, 'task');
|
||||
if(!empty($taskFiles))
|
||||
{
|
||||
@@ -615,12 +655,13 @@ class taskModel extends model
|
||||
->setIF($this->post->assignedTo != $oldTask->assignedTo, 'assignedDate', $now)
|
||||
|
||||
->setIF($this->post->status == 'wait' and $this->post->left == $oldTask->left and $this->post->consumed == 0 and $this->post->estimate, 'left', $this->post->estimate)
|
||||
->setIF(isset($_POST['unlinkParent']), 'parent', 0)
|
||||
|
||||
->setDefault('lastEditedBy', $this->app->user->account)
|
||||
->add('lastEditedDate', $now)
|
||||
->stripTags($this->config->task->editor->edit['id'], $this->config->allowedTags)
|
||||
->join('mailto', ',')
|
||||
->remove('comment,files,labels,uid,multiple,team,teamEstimate,teamConsumed,teamLeft,contactListMenu')
|
||||
->remove('comment,files,labels,uid,multiple,team,teamEstimate,teamConsumed,teamLeft,contactListMenu,unlinkParent')
|
||||
->get();
|
||||
|
||||
if($task->consumed < $oldTask->consumed) die(js::error($this->lang->task->error->consumedSmall));
|
||||
@@ -696,6 +737,7 @@ class taskModel extends model
|
||||
|
||||
if($oldTask->parent > 0)
|
||||
{
|
||||
if($task->parent == 0) $this->computeWorkingHours($oldTask->parent);
|
||||
$this->updateParentStatus($taskID);
|
||||
$this->computeBeginAndEnd($oldTask->parent);
|
||||
}
|
||||
@@ -1650,6 +1692,11 @@ class taskModel extends model
|
||||
->andWhere('project')->eq($projectID)
|
||||
->fetchPairs();
|
||||
|
||||
foreach($tasks as $id => $name)
|
||||
{
|
||||
$taskTeam = $this->dao->select('*')->from(TABLE_TEAM)->where('root')->eq($id)->andWhere('type')->eq('task')->fetch();
|
||||
if(!empty($taskTeam)) unset($tasks[$id]);
|
||||
}
|
||||
return array('' => '') + $tasks ;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,12 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->task->type;?></th>
|
||||
<td><?php echo html::select('type', $lang->task->typeList, $task->type, "class='form-control chosen' onchange='setOwners(this.value)' required");?></td><td></td><td></td>
|
||||
<td><?php echo html::select('type', $lang->task->typeList, $task->type, "class='form-control chosen' onchange='setOwners(this.value)' required");?></td>
|
||||
<td>
|
||||
<div class="checkbox-primary hidden" id='selectTestStoryBox'>
|
||||
<input type="checkbox" name='selectTestStory' id="selectTestStory" value='1' onchange='toggleSelectTestStory()' /><label for="selectTestStory" class="no-margin"><?php echo $lang->task->selectTestStory;?></label>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->task->module;?></th>
|
||||
@@ -69,6 +74,46 @@
|
||||
</td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr id='testStoryBox' class='hidden'>
|
||||
<th><?php echo $lang->task->selectTestStory;?></th>
|
||||
<td colspan='3'>
|
||||
<?php if($noTestStories):?>
|
||||
<table class='table table-form mg-0 table-bordered'>
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo $lang->task->storyAB;?></th>
|
||||
<th class='w-100px'><?php echo $lang->task->pri;?></th>
|
||||
<th class='w-300px'><?php echo $lang->task->datePlan;?></th>
|
||||
<th class='w-150px'><?php echo $lang->task->assignedTo;?></th>
|
||||
<th class='w-80px'><?php echo $lang->task->estimate;?></th>
|
||||
<th class='w-80px'><?php echo $lang->actions;?></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><?php echo html::select("testStory[]", $noTestStories, '', "class='form-control chosen'");?></td>
|
||||
<td><?php echo html::select("testPri[]", $lang->task->priList, $task->pri, "class='form-control chosen'");?></td>
|
||||
<td>
|
||||
<div class='input-group'>
|
||||
<?php echo html::input("testEstStarted[]", $task->estStarted, "class='form-control form-date' placeholder='{$lang->task->estStarted}'");?>
|
||||
<span class='input-group-addon fix-border'>~</span>
|
||||
<?php echo html::input("testDeadline[]", $task->deadline, "class='form-control form-date' placeholder='{$lang->task->deadline}'");?>
|
||||
</div>
|
||||
</td>
|
||||
<td><?php echo html::select("testAssignedTo[]", $members, $task->assignedTo, "class='form-control chosen'");?></td>
|
||||
<td><?php echo html::input("testEstimate[]", '', "class='form-control'");?></td>
|
||||
<td class='text-center'>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-sm" tabindex="-1" onclick='addItem(this)'><i class="icon icon-plus"></i></button>
|
||||
<button type="button" class="btn btn-sm" tabindex="-1" onclick='removeItem(this)'><i class="icon icon-close"></i></button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<?php endif;?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->task->name;?></th>
|
||||
<td colspan='3'>
|
||||
|
||||
@@ -109,6 +109,12 @@
|
||||
<td><?php echo html::select('parent', $tasks, $task->parent, "class='form-control chosen'");?></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<?php if($task->parent > 0):?>
|
||||
<tr>
|
||||
<th><?php echo $lang->task->unlinkParent;?></th>
|
||||
<td><?php echo html::checkbox('unlinkParent', '');?></td>
|
||||
</tr>
|
||||
<?php endif;?>
|
||||
<tr>
|
||||
<th><?php echo $lang->task->assignedTo;?></th>
|
||||
<td><span id="assignedToIdBox"><?php echo html::select('assignedTo', $members, $task->assignedTo, "class='form-control chosen'");?></span></td>
|
||||
|
||||
@@ -258,6 +258,10 @@
|
||||
<th><?php echo $lang->task->status;?></th>
|
||||
<td><span class='status-task status-<?php echo $task->status;?>'><span class="label label-dot"></span> <?php echo zget($lang->task->statusList, $task->status);?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->task->progress;?></th>
|
||||
<td><?php echo $task->progress . '%';?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><?php echo $lang->task->pri;?></th>
|
||||
<td><span class='label-pri <?php echo 'label-pri-' . $task->pri;?>' title='<?php echo zget($lang->task->priList, $task->pri);?>'><?php echo $task->pri == '0' ? $lang->noData : zget($lang->task->priList, $task->pri)?></span></td>
|
||||
|
||||
@@ -239,12 +239,7 @@ class testcase extends control
|
||||
$this->action->create('case', $caseID, 'Opened');
|
||||
|
||||
/* If link from no head then reload. */
|
||||
if(isonlybody())
|
||||
{
|
||||
$response['locate'] = 'reload';
|
||||
$response['target'] = 'parent';
|
||||
$this->send($response);
|
||||
}
|
||||
if(isonlybody()) $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'closeModal' => true));
|
||||
|
||||
setcookie('caseModule', (int)$this->post->module, 0, $this->config->webRoot);
|
||||
$response['locate'] = $this->createLink('testcase', 'browse', "productID={$this->post->product}&branch={$this->post->branch}&browseType=all¶m=0&orderBy=id_desc");
|
||||
@@ -988,9 +983,10 @@ class testcase extends control
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function confirmLibcaseChange($caseID, $libcaseID, $version)
|
||||
public function confirmLibcaseChange($caseID, $libcaseID)
|
||||
{
|
||||
$case = $this->testcase->getById($caseID);
|
||||
$case = $this->testcase->getById($caseID);
|
||||
$version = $case->fromCaseVersion;
|
||||
$this->dao->update(TABLE_CASE)->set('version')->eq($version)->where('id')->eq($caseID)->exec();
|
||||
$steps = $this->dao->select('*')->from(TABLE_CASESTEP)->where('`case`')->eq($libcaseID)->andWhere('version')->eq($version)->fetchAll();
|
||||
foreach($steps as $step)
|
||||
@@ -1002,6 +998,20 @@ class testcase extends control
|
||||
die(js::reload('parent'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignore libcase changed.
|
||||
*
|
||||
* @param int $caseID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function ignoreLibcaseChange($caseID)
|
||||
{
|
||||
$case = $this->testcase->getById($caseID);
|
||||
$this->dao->update(TABLE_CASE)->set('fromCaseVersion')->eq($case->version)->where('id')->eq($caseID)->exec();
|
||||
die(js::reload('parent'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Confirm story changes.
|
||||
*
|
||||
|
||||
@@ -65,6 +65,7 @@ $lang->testcase->createBug = 'Convert to Bug';
|
||||
$lang->testcase->fromModule = 'Source Module';
|
||||
$lang->testcase->fromCase = 'Source Case';
|
||||
$lang->testcase->sync = 'Sync Case';
|
||||
$lang->testcase->ignore = 'Ignore';
|
||||
$lang->testcase->fromTesttask = 'From Testtask';
|
||||
$lang->testcase->fromCaselib = 'From Caselib';
|
||||
$lang->case = $lang->testcase; // For dao checking using. Because 'case' is a php keywords, so the module name is testcase, table name is still case.
|
||||
|
||||
@@ -65,6 +65,7 @@ $lang->testcase->createBug = '转Bug';
|
||||
$lang->testcase->fromModule = '来源模块';
|
||||
$lang->testcase->fromCase = '来源用例';
|
||||
$lang->testcase->sync = '同步';
|
||||
$lang->testcase->ignore = '忽略';
|
||||
$lang->testcase->fromTesttask = '测试单用例';
|
||||
$lang->testcase->fromCaselib = '用例库用例';
|
||||
$lang->case = $lang->testcase; // 用于DAO检查时使用。因为case是系统关键字,所以无法定义该模块为case,只能使用testcase,但表还是使用的case。
|
||||
|
||||
@@ -396,7 +396,6 @@ class testcaseModel extends model
|
||||
$case->latestStoryVersion = $story->version;
|
||||
}
|
||||
if($case->fromBug) $case->fromBugTitle = $this->dao->findById($case->fromBug)->from(TABLE_BUG)->fields('title')->fetch('title');
|
||||
if($case->fromCaseID) $case->libCaseVersion = $this->dao->findById($case->fromCaseID)->from(TABLE_CASE)->fetch('version');
|
||||
|
||||
$case->toBugs = array();
|
||||
$toBugs = $this->dao->select('id, title')->from(TABLE_BUG)->where('`case`')->eq($caseID)->fetchAll();
|
||||
@@ -672,6 +671,8 @@ class testcaseModel extends model
|
||||
if($stepChanged)
|
||||
{
|
||||
$parentStepID = 0;
|
||||
$isLibCase = ($oldCase->lib and empty($oldCase->product));
|
||||
if($isLibCase) $this->dao->update(TABLE_CASE)->set('`fromCaseVersion`')->eq($version)->where('`fromCaseID`')->eq($caseID)->exec();
|
||||
foreach($this->post->steps as $stepID => $stepDesc)
|
||||
{
|
||||
if(empty($stepDesc)) continue;
|
||||
@@ -1253,7 +1254,8 @@ class testcaseModel extends model
|
||||
$libSteps = $this->dao->select('*')->from(TABLE_CASESTEP)->where('`case`')->in($data->caseIdList)->orderBy('id')->fetchGroup('case');
|
||||
foreach($libCases as $libCaseID => $case)
|
||||
{
|
||||
$case->fromCaseID = $case->id;
|
||||
$case->fromCaseID = $case->id;
|
||||
$case->fromCaseVersion = $case->version;
|
||||
$case->product = $productID;
|
||||
if(isset($data->module[$case->id])) $case->module = $data->module[$case->id];
|
||||
if(isset($data->branch[$case->id])) $case->branch = $data->branch[$case->id];
|
||||
@@ -1339,7 +1341,6 @@ class testcaseModel extends model
|
||||
$caseLink = helper::createLink('testcase', 'view', "caseID=$case->id&version=$case->version");
|
||||
$account = $this->app->user->account;
|
||||
$fromCaseID = $case->fromCaseID;
|
||||
if($fromCaseID) $libCaseVersion = $this->dao->findById($fromCaseID)->from(TABLE_CASE)->fetch('version');
|
||||
$id = $col->id;
|
||||
if($col->show)
|
||||
{
|
||||
@@ -1392,7 +1393,7 @@ class testcaseModel extends model
|
||||
{
|
||||
print("<span class='status-story status-changed' title={$this->lang->testcase->fromTesttask}>{$this->lang->story->changed}</span>");
|
||||
}
|
||||
elseif(isset($libCaseVersion) and $libCaseVersion > $case->version and !$case->needconfirm)
|
||||
elseif(isset($case->fromCaseVersion) and $case->fromCaseVersion > $case->version and !$case->needconfirm)
|
||||
{
|
||||
print("<span class='status-story status-changed' title={$this->lang->testcase->fromCaselib}>{$this->lang->testcase->changed}</span>");
|
||||
}
|
||||
|
||||
@@ -223,10 +223,11 @@
|
||||
echo html::a($this->createLink('testcase', 'confirmchange', "caseID=$case->id"), $lang->testcase->sync, 'hiddenwin', "class='btn btn-mini btn-info'");
|
||||
echo ")";
|
||||
}
|
||||
if(isset($case->libCaseVersion) and $case->libCaseVersion > $case->version and $from != 'testtask')
|
||||
if(isset($case->fromCaseVersion) and $case->fromCaseVersion > $case->version and $from != 'testtask')
|
||||
{
|
||||
echo "(<span class='warning' title={$lang->testcase->fromCaselib}>{$lang->testcase->changed}</span> ";
|
||||
echo html::a($this->createLink('testcase', 'confirmLibcaseChange', "caseID=$case->id&libcaseID=$case->fromCaseID&version=$case->libCaseVersion"), $lang->testcase->sync, 'hiddenwin', "class='btn btn-mini btn-info'");
|
||||
echo html::a($this->createLink('testcase', 'confirmLibcaseChange', "caseID=$case->id&libcaseID=$case->fromCaseID"), $lang->testcase->sync, 'hiddenwin', "class='btn btn-mini btn-info'");
|
||||
echo html::a($this->createLink('testcase', 'ignoreLibcaseChange', "caseID=$case->id"), $lang->testcase->ignore, 'hiddenwin', "class='btn btn-mini btn-info'");
|
||||
echo ")";
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -60,7 +60,7 @@ $lang->testreport->buildSummary = 'Tested <strong>%s</strong> build.';
|
||||
$lang->testreport->confirmDelete = 'Do you want to delete this report?';
|
||||
$lang->testreport->moreNotice = 'More features can be extended with reference to the ZenTao manual, or you can contact us at renee@easysoft.ltd for customization.';
|
||||
$lang->testreport->exportNotice = "Exported By <a href='https://www.zentao.pm' target='_blank' style='color:grey'>ZenTao</a>";
|
||||
$lang->testreport->noReport = "No report has been generated. Please check later.";
|
||||
$lang->testreport->noReport = "No report has been generated yet.";
|
||||
$lang->testreport->foundBugTip = "Bugs reported in this build and in this test.";
|
||||
$lang->testreport->legacyBugTip = "Active Bugs, or bugs that are resolved after this test is done.";
|
||||
$lang->testreport->fromCaseBugTip = "Bugs reported due to failed cases in this test.";
|
||||
|
||||
@@ -60,7 +60,7 @@ $lang->testreport->buildSummary = '共测试了<strong>%s</strong>个版本。
|
||||
$lang->testreport->confirmDelete = '是否删除该报告?';
|
||||
$lang->testreport->moreNotice = '更多功能可以参考禅道扩展机制进行扩展,也可以联系我们进行定制。';
|
||||
$lang->testreport->exportNotice = "由<a href='https://www.zentao.net' target='_blank' style='color:grey'>禅道项目管理软件</a>导出";
|
||||
$lang->testreport->noReport = "报表还没有生成,请稍候查看。";
|
||||
$lang->testreport->noReport = "报表还没有生成。";
|
||||
$lang->testreport->foundBugTip = "影响版本在测试轮次内,并且创建时间在测试时间范围内产生的Bug数。";
|
||||
$lang->testreport->legacyBugTip = "Bug状态是激活,或Bug的解决时间在测试结束时间之后。";
|
||||
$lang->testreport->fromCaseBugTip = "测试时间范围内,用例执行失败后创建的Bug。";
|
||||
|
||||
@@ -832,7 +832,8 @@ class testtask extends control
|
||||
$caseResult = $this->testtask->createResult($runID);
|
||||
if(dao::isError()) die(js::error(dao::getError()));
|
||||
|
||||
if($caseResult == 'fail') {
|
||||
if($caseResult == 'fail')
|
||||
{
|
||||
|
||||
$response['result'] = 'success';
|
||||
$response['locate'] = $this->createLink('testtask', 'results',"runID=$runID&caseID=$caseID&version=$version");
|
||||
|
||||
+11
-11
@@ -38,29 +38,29 @@ $lang->tutorial->tasks['createAccount'] = array('title' => 'Create a Use
|
||||
$lang->tutorial->tasks['createAccount']['nav'] = array('module' => 'user', 'method' => 'create', 'menuModule' => 'company', 'menu' => 'browseUser', 'form' => '#createForm', 'submit' => '#submit', 'target' => '.create-user-btn', 'targetPageName' => 'Add User');
|
||||
$lang->tutorial->tasks['createAccount']['desc'] = "<p>Create a User: </p><ul><li data-target='nav'>Open <span class='task-nav'>Company <i class='icon icon-angle-right'></i> Users<i class='icon icon-angle-right'></i> New;</span></li><li data-target='form'>Fill the form with user information;</li><li data-target='submit'>Save</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['createProduct'] = array('title' => 'Create a Product');
|
||||
$lang->tutorial->tasks['createProduct']['nav'] = array('module' => 'product', 'method' => 'create', 'menu' => '#pageNav', 'form' => '#createForm', 'submit' => '#submit', 'target' => '.create-product-btn', 'targetPageName' => 'Product');
|
||||
$lang->tutorial->tasks['createProduct']['desc'] = "<p>Create a product: </p><ul><li data-target='nav'> Open <span class='task-nav'>Product <i class='icon icon-angle-right'></i> New;</span></li><li data-target='form'>Fill the form with product information;</li><li data-target='submit'>Save</li></ul>";
|
||||
$lang->tutorial->tasks['createProduct'] = array('title' => 'Create a ' . $lang->productCommon);
|
||||
$lang->tutorial->tasks['createProduct']['nav'] = array('module' => 'product', 'method' => 'create', 'menu' => '#pageNav', 'form' => '#createForm', 'submit' => '#submit', 'target' => '.create-product-btn', 'targetPageName' => $lang->projectCommon);
|
||||
$lang->tutorial->tasks['createProduct']['desc'] = "<p>Create a {$lang->productCommon}: </p><ul><li data-target='nav'> Open <span class='task-nav'>{$lang->productCommon} <i class='icon icon-angle-right'></i> New;</span></li><li data-target='form'>Fill the form with {$lang->productCommon} information;</li><li data-target='submit'>Save</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['createStory'] = array('title' => 'Create a Story');
|
||||
$lang->tutorial->tasks['createStory']['nav'] = array('module' => 'story', 'method' => 'create', 'menuModule' => 'product', 'menu' => 'story', 'target' => '.create-story-btn', 'form' => '#dataform', 'submit' => '#submit', 'targetPageName' => 'Create Story');
|
||||
$lang->tutorial->tasks['createStory']['desc'] = "<p>Create a story: </p><ul><li data-target='nav'>Open <span class='task-nav'>Product <i class='icon icon-angle-right'></i>Story <i class='icon icon-angle-right'></i>Create;</span></li><li data-target='form'>Fill the form with story information;</li><li data-target='submit'>Save</li></ul>";
|
||||
$lang->tutorial->tasks['createStory']['desc'] = "<p>Create a story: </p><ul><li data-target='nav'>Open <span class='task-nav'>{$lang->productCommon} <i class='icon icon-angle-right'></i>Story <i class='icon icon-angle-right'></i>Create;</span></li><li data-target='form'>Fill the form with story information;</li><li data-target='submit'>Save</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['createProject'] = array('title' => 'Create a Project');
|
||||
$lang->tutorial->tasks['createProject']['nav'] = array('module' => 'project', 'method' => 'create', 'menu' => '#pageNav', 'form' => '#dataform', 'submit' => '#submit', 'target' => '.create-project-btn', 'targetPageName' => 'Create Project');
|
||||
$lang->tutorial->tasks['createProject']['desc'] = "<p>Create a project: </p><ul><li data-target='nav'>Open <span class='task-nav'> Project <i class='icon icon-angle-right'></i> New</span> Page;</li><li data-target='form'>Fill the form with project information;</li><li data-target='submit'>Save</li></ul>";
|
||||
$lang->tutorial->tasks['createProject'] = array('title' => 'Create a ' . $lang->projectCommon);
|
||||
$lang->tutorial->tasks['createProject']['nav'] = array('module' => 'project', 'method' => 'create', 'menu' => '#pageNav', 'form' => '#dataform', 'submit' => '#submit', 'target' => '.create-project-btn', 'targetPageName' => 'Create ' . $lang->projectCommon);
|
||||
$lang->tutorial->tasks['createProject']['desc'] = "<p>Create a {$lang->projectCommon}: </p><ul><li data-target='nav'>Open <span class='task-nav'> {$lang->projectCommon} <i class='icon icon-angle-right'></i> New</span> Page;</li><li data-target='form'>Fill the form with {$lang->projectCommon} information;</li><li data-target='submit'>Save</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['manageTeam'] = array('title' => 'Manage Project Team');
|
||||
$lang->tutorial->tasks['manageTeam'] = array('title' => "Manage {$lang->projectCommon} Team");
|
||||
$lang->tutorial->tasks['manageTeam']['nav'] = array('module' => 'project', 'method' => 'managemembers', 'menu' => 'team', 'target' => '.manage-team-btn', 'form' => '#teamForm', 'requiredFields' => 'account1', 'submit' => '#submit', 'targetPageName' => 'Manage team members');
|
||||
$lang->tutorial->tasks['manageTeam']['desc'] = "<p>Manage project team members: </p><ul><li data-target='nav'>Open <span class='task-nav'> Project <i class='icon icon-angle-right'></i> Team <i class='icon icon-angle-right'></i> Manage Team Members</span> Page;</li><li data-target='form'>Choose users for the team.</li><li data-target='submit'>Save</li></ul>";
|
||||
$lang->tutorial->tasks['manageTeam']['desc'] = "<p>Manage {$lang->projectCommon} team members: </p><ul><li data-target='nav'>Open <span class='task-nav'> {$lang->projectCommon} <i class='icon icon-angle-right'></i> Team <i class='icon icon-angle-right'></i> Manage Team Members</span> Page;</li><li data-target='form'>Choose users for the team.</li><li data-target='submit'>Save</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['linkStory'] = array('title' => 'Link Story');
|
||||
$lang->tutorial->tasks['linkStory']['nav'] = array('module' => 'project', 'method' => 'linkStory', 'menu' => 'story', 'target' => '.link-story-btn', 'form' => '#linkStoryForm', 'formType' => 'table', 'submit' => '#submit', 'targetPageName' => 'Relate Story');
|
||||
$lang->tutorial->tasks['linkStory']['desc'] = "<p>Link Story to Project: </p><ul><li data-target='nav'>Open <span class='task-nav'> Project <i class='icon icon-angle-right'></i> Story <i class='icon icon-angle-right'></i>Relate Story;</span></li><li data-target='form'>Select stories from story list to relate;</li><li data-target='submit'>Save</li></ul>";
|
||||
$lang->tutorial->tasks['linkStory']['desc'] = "<p>Link Story to {$lang->projectCommon}: </p><ul><li data-target='nav'>Open <span class='task-nav'> {$lang->projectCommon} <i class='icon icon-angle-right'></i> Story <i class='icon icon-angle-right'></i>Relate Story;</span></li><li data-target='form'>Select stories from story list to relate;</li><li data-target='submit'>Save</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['createTask'] = array('title' => 'Subdivide Tasks');
|
||||
$lang->tutorial->tasks['createTask']['nav'] = array('module' => 'task', 'method' => 'create', 'menuModule' => 'project', 'menu' => 'story', 'target' => '.btn-task-create', 'form' => '#dataform', 'submit' => '#submit', 'targetPageName' => 'Create Task');
|
||||
$lang->tutorial->tasks['createTask']['desc'] = "<p>Subdivide tasks for Story: </p><ul><li data-target='nav'>Open <span class='task-nav'> Project <i class='icon icon-angle-right'></i> Story <i class='icon icon-angle-right'></i> WBS;</span></li><li data-target='form'>Fill the form with task information;</li><li data-target='submit'>Save</li></ul>";
|
||||
$lang->tutorial->tasks['createTask']['desc'] = "<p>Subdivide tasks for Story: </p><ul><li data-target='nav'>Open <span class='task-nav'> {$lang->projectCommon} <i class='icon icon-angle-right'></i> Story <i class='icon icon-angle-right'></i> WBS;</span></li><li data-target='form'>Fill the form with task information;</li><li data-target='submit'>Save</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['createBug'] = array('title' => 'Report a Bug');
|
||||
$lang->tutorial->tasks['createBug']['nav'] = array('module' => 'bug', 'method' => 'create', 'menuModule' => 'qa', 'menu' => 'bug', 'target' => '.btn-bug-create', 'form' => '#dataform', 'submit' => '#submit', 'targetPageName' => 'Create Bug');
|
||||
|
||||
@@ -38,29 +38,29 @@ $lang->tutorial->tasks['createAccount'] = array('title' => '创建帐号
|
||||
$lang->tutorial->tasks['createAccount']['nav'] = array('module' => 'user', 'method' => 'create', 'menuModule' => 'company', 'menu' => 'browseUser', 'form' => '#createForm', 'submit' => '#submit', 'target' => '.create-user-btn', 'targetPageName' => '添加用户');
|
||||
$lang->tutorial->tasks['createAccount']['desc'] = "<p>在系统创建一个新的用户帐号:</p><ul><li data-target='nav'>打开 <span class='task-nav'>组织 <i class='icon icon-angle-right'></i> 用户 <i class='icon icon-angle-right'></i> 添加用户</span> 页面;</li><li data-target='form'>在添加用户表单中填写新用户信息;</li><li data-target='submit'>保存用户信息。</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['createProduct'] = array('title' => '创建产品');
|
||||
$lang->tutorial->tasks['createProduct']['nav'] = array('module' => 'product', 'method' => 'create', 'menu' => '#pageNav', 'form' => '#createForm', 'submit' => '#submit', 'target' => '.create-product-btn', 'targetPageName' => '添加产品');
|
||||
$lang->tutorial->tasks['createProduct']['desc'] = "<p>在系统创建一个新的产品:</p><ul><li data-target='nav'>打开 <span class='task-nav'>产品 <i class='icon icon-angle-right'></i> 添加产品</span> 页面;</li><li data-target='form'>在表单中填写要创建的产品信息;</li><li data-target='submit'>保存产品信息。</li></ul>";
|
||||
$lang->tutorial->tasks['createProduct'] = array('title' => '创建' . $lang->productCommon);
|
||||
$lang->tutorial->tasks['createProduct']['nav'] = array('module' => 'product', 'method' => 'create', 'menu' => '#pageNav', 'form' => '#createForm', 'submit' => '#submit', 'target' => '.create-product-btn', 'targetPageName' => '添加' . $lang->productCommon);
|
||||
$lang->tutorial->tasks['createProduct']['desc'] = "<p>在系统创建一个新的{$lang->productCommon}:</p><ul><li data-target='nav'>打开 <span class='task-nav'>{$lang->productCommon} <i class='icon icon-angle-right'></i> 添加{$lang->productCommon}</span> 页面;</li><li data-target='form'>在表单中填写要创建的{$lang->productCommon}信息;</li><li data-target='submit'>保存{$lang->productCommon}信息。</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['createStory'] = array('title' => '创建需求');
|
||||
$lang->tutorial->tasks['createStory']['nav'] = array('module' => 'story', 'method' => 'create', 'menuModule' => 'product', 'menu' => 'story', 'target' => '.create-story-btn', 'form' => '#dataform', 'submit' => '#submit', 'targetPageName' => '提需求');
|
||||
$lang->tutorial->tasks['createStory']['desc'] = "<p>在系统创建一个新的需求:</p><ul><li data-target='nav'>打开 <span class='task-nav'>产品 <i class='icon icon-angle-right'></i> 需求 <i class='icon icon-angle-right'></i> 添加需求</span> 页面;</li><li data-target='form'>在表单中填写要创建的需求信息;</li><li data-target='submit'>保存需求信息。</li></ul>";
|
||||
$lang->tutorial->tasks['createStory']['desc'] = "<p>在系统创建一个新的需求:</p><ul><li data-target='nav'>打开 <span class='task-nav'>{$lang->productCommon} <i class='icon icon-angle-right'></i> 需求 <i class='icon icon-angle-right'></i> 添加需求</span> 页面;</li><li data-target='form'>在表单中填写要创建的需求信息;</li><li data-target='submit'>保存需求信息。</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['createProject'] = array('title' => '创建项目');
|
||||
$lang->tutorial->tasks['createProject']['nav'] = array('module' => 'project', 'method' => 'create', 'menu' => '#pageNav', 'form' => '#dataform', 'submit' => '#submit', 'target' => '.create-project-btn', 'targetPageName' => '添加项目');
|
||||
$lang->tutorial->tasks['createProject']['desc'] = "<p>在系统创建一个新的项目:</p><ul><li data-target='nav'>打开 <span class='task-nav'> 项目 <i class='icon icon-angle-right'></i> 添加项目</span> 页面;</li><li data-target='form'>在表单中填写要创建的项目信息;</li><li data-target='submit'>保存项目信息。</li></ul>";
|
||||
$lang->tutorial->tasks['createProject'] = array('title' => '创建' . $lang->projectCommon);
|
||||
$lang->tutorial->tasks['createProject']['nav'] = array('module' => 'project', 'method' => 'create', 'menu' => '#pageNav', 'form' => '#dataform', 'submit' => '#submit', 'target' => '.create-project-btn', 'targetPageName' => '添加' . $lang->projectCommon);
|
||||
$lang->tutorial->tasks['createProject']['desc'] = "<p>在系统创建一个新的{$lang->projectCommon}:</p><ul><li data-target='nav'>打开 <span class='task-nav'> {$lang->projectCommon} <i class='icon icon-angle-right'></i> 添加{$lang->projectCommon}</span> 页面;</li><li data-target='form'>在表单中填写要创建的{$lang->projectCommon}信息;</li><li data-target='submit'>保存{$lang->projectCommon}信息。</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['manageTeam'] = array('title' => '管理团队');
|
||||
$lang->tutorial->tasks['manageTeam']['nav'] = array('module' => 'project', 'method' => 'managemembers', 'menu' => 'team', 'target' => '.manage-team-btn', 'form' => '#teamForm', 'requiredFields' => 'account1', 'submit' => '#submit', 'targetPageName' => '团队管理');
|
||||
$lang->tutorial->tasks['manageTeam']['desc'] = "<p>管理项目团队成员:</p><ul><li data-target='nav'>打开 <span class='task-nav'> 项目 <i class='icon icon-angle-right'></i> 团队 <i class='icon icon-angle-right'></i> 团队管理</span> 页面;</li><li data-target='form'>选择要加入团队的成员;</li><li data-target='submit'>保存团队成员信息。</li></ul>";
|
||||
$lang->tutorial->tasks['manageTeam']['desc'] = "<p>管理{$lang->projectCommon}团队成员:</p><ul><li data-target='nav'>打开 <span class='task-nav'> {$lang->projectCommon} <i class='icon icon-angle-right'></i> 团队 <i class='icon icon-angle-right'></i> 团队管理</span> 页面;</li><li data-target='form'>选择要加入团队的成员;</li><li data-target='submit'>保存团队成员信息。</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['linkStory'] = array('title' => '关联需求');
|
||||
$lang->tutorial->tasks['linkStory']['nav'] = array('module' => 'project', 'method' => 'linkStory', 'menu' => 'story', 'target' => '.link-story-btn', 'form' => '#linkStoryForm', 'formType' => 'table', 'submit' => '#submit', 'targetPageName' => '关联需求');
|
||||
$lang->tutorial->tasks['linkStory']['desc'] = "<p>将需求关联到项目:</p><ul><li data-target='nav'>打开 <span class='task-nav'> 项目 <i class='icon icon-angle-right'></i> 需求 <i class='icon icon-angle-right'></i> 关联需求</span> 页面;</li><li data-target='form'>在需求列表中勾选要关联的需求;</li><li data-target='submit'>保存关联的需求信息。</li></ul>";
|
||||
$lang->tutorial->tasks['linkStory']['desc'] = "<p>将需求关联到{$lang->projectCommon}:</p><ul><li data-target='nav'>打开 <span class='task-nav'> {$lang->projectCommon} <i class='icon icon-angle-right'></i> 需求 <i class='icon icon-angle-right'></i> 关联需求</span> 页面;</li><li data-target='form'>在需求列表中勾选要关联的需求;</li><li data-target='submit'>保存关联的需求信息。</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['createTask'] = array('title' => '分解任务');
|
||||
$lang->tutorial->tasks['createTask']['nav'] = array('module' => 'task', 'method' => 'create', 'menuModule' => 'project', 'menu' => 'story', 'target' => '.btn-task-create', 'form' => '#dataform', 'submit' => '#submit', 'targetPageName' => '建任务');
|
||||
$lang->tutorial->tasks['createTask']['desc'] = "<p>将项目需求分解为任务:</p><ul><li data-target='nav'>打开 <span class='task-nav'> 项目 <i class='icon icon-angle-right'></i> 需求 <i class='icon icon-angle-right'></i> 分解任务</span> 页面;</li><li data-target='form'>在表单中填写任务信息;</li><li data-target='submit'>保存任务信息。</li></ul>";
|
||||
$lang->tutorial->tasks['createTask']['desc'] = "<p>将{$lang->projectCommon}需求分解为任务:</p><ul><li data-target='nav'>打开 <span class='task-nav'> {$lang->projectCommon} <i class='icon icon-angle-right'></i> 需求 <i class='icon icon-angle-right'></i> 分解任务</span> 页面;</li><li data-target='form'>在表单中填写任务信息;</li><li data-target='submit'>保存任务信息。</li></ul>";
|
||||
|
||||
$lang->tutorial->tasks['createBug'] = array('title' => '提Bug');
|
||||
$lang->tutorial->tasks['createBug']['nav'] = array('module' => 'bug', 'method' => 'create', 'menuModule' => 'qa', 'menu' => 'bug', 'target' => '.btn-bug-create', 'form' => '#dataform', 'submit' => '#submit', 'targetPageName' => '提Bug');
|
||||
|
||||
@@ -77,7 +77,7 @@
|
||||
<?php
|
||||
$nav = $task['nav'];
|
||||
$task['name'] = $name;
|
||||
$task['id'] = $idx+1;
|
||||
$task['id'] = $idx + 1;
|
||||
$task['url'] = helper::createLink($nav['module'], $nav['method'], isset($nav['vars']) ? $nav['vars'] : '', 'tutorial');
|
||||
$tasks[$name] = $task;
|
||||
?>
|
||||
@@ -224,11 +224,15 @@ $(function()
|
||||
tipClass: 'tooltip-warning tooltip-max'
|
||||
}, options);
|
||||
$e = $e.first();
|
||||
if(!$e.data('zui.tooltip')) $e.addClass('tooltip-tutorial').attr('data-toggle', 'tooltip').tooltip(options);
|
||||
$e.tooltip('show');
|
||||
if($e[0].getBoundingClientRect().top > $(window).height() || $e[0].getBoundingClientRect().top < 0)
|
||||
if($e.css('display') == 'none')
|
||||
{
|
||||
$e[0].scrollIntoView();
|
||||
$e.parent().addClass('tooltip-tutorial').after("<div id='typeLabel' class='text-danger help-text'>" + options.title + "</div>");
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!$e.data('zui.tooltip')) $e.addClass('tooltip-tutorial').attr('data-toggle', 'tooltip').tooltip(options);
|
||||
$e.tooltip('show');
|
||||
if($e[0].getBoundingClientRect().top > $(window).height() || $e[0].getBoundingClientRect().top < 0) $e[0].scrollIntoView();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -277,7 +281,7 @@ $(function()
|
||||
var $checkboxes = $form.find(fieldSelector);
|
||||
targetStatus.form = $checkboxes.filter(':checked').length > 0;
|
||||
if(!targetStatus.form) {
|
||||
targetStatus.waitFeild = $checkboxes.filter(':not(:checked):first').closest('td');
|
||||
targetStatus.waitField = $checkboxes.filter(':not(:checked):first').closest('td');
|
||||
}
|
||||
}
|
||||
else if(requiredFields)
|
||||
@@ -294,7 +298,7 @@ $(function()
|
||||
if(val === undefined || val === null || val === '' || val === '0')
|
||||
{
|
||||
targetStatus.form = false;
|
||||
if(!targetStatus.waitFeild) targetStatus.waitFeild = $required;
|
||||
if(!targetStatus.waitField) targetStatus.waitField = $required;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -310,15 +314,17 @@ $(function()
|
||||
var status = checkTask();
|
||||
if(!status.submitOK)
|
||||
{
|
||||
if(status.waitFeild)
|
||||
if(status.waitField)
|
||||
{
|
||||
var feildName = status.waitFeild.closest('td').prev('th').text();
|
||||
if(feildName) showToolTip(status.waitFeild, lang.requiredTip.replace('%s', feildName));
|
||||
highlight(status.waitFeild, function()
|
||||
var fieldName = status.waitField.closest('td').prev('th').text();
|
||||
if(!fieldName) fieldName = status.waitField.closest('.input-group').find('.input-group-addon:first').text();
|
||||
if(fieldName) showToolTip(status.waitField, lang.requiredTip.replace('%s', fieldName));
|
||||
highlight(status.waitField, function()
|
||||
{
|
||||
clearTimeout(showToolTipTask);
|
||||
showToolTipTask = setTimeout(function()
|
||||
{
|
||||
status.waitField.closest('td').find('#typeLabel').remove();
|
||||
showToolTip($formWrapper, $formTarget.text());
|
||||
highlight($formWrapper);
|
||||
}, 2000);
|
||||
|
||||
@@ -367,6 +367,9 @@ class upgradeModel extends model
|
||||
$this->saveLogs('Execute 11_2');
|
||||
$this->execSQL($this->getUpgradeFile('11.2'));
|
||||
$this->processDocLibAcl();
|
||||
case '11_3':
|
||||
$this->saveLogs('Execute 11_2');
|
||||
$this->addPriv11_4();
|
||||
}
|
||||
|
||||
$this->deletePatch();
|
||||
@@ -2218,6 +2221,28 @@ class upgradeModel extends model
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust priv for 11.4.
|
||||
*
|
||||
* @access public
|
||||
* @return bool
|
||||
*/
|
||||
public function adjustPriv11_4()
|
||||
{
|
||||
$this->saveLogs('Run Method ' . __FUNCTION__);
|
||||
$groups = $this->dao->select('`group`')->from(TABLE_GROUPPRIV)->where('module')->eq('story')->andWhere('method')->eq('edit')->fetchPairs('group', 'group');
|
||||
foreach($groups as $groupID)
|
||||
{
|
||||
$data = new stdclass();
|
||||
$data->group = $groupID;
|
||||
$data->module = 'story';
|
||||
$data->method = 'assignTo';
|
||||
$this->dao->replace(TABLE_GROUPPRIV)->data($data)->exec();
|
||||
$this->saveLogs($this->dao->get());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Judge any error occers.
|
||||
*
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
#featurebar ul.nav li .chosen-container .chosen-drop {min-width: 200px;!important}
|
||||
#dept_chosen.chosen-container .chosen-drop {min-width: 400px;!important}
|
||||
.w-verifyPassword {width: 120px !important;}
|
||||
.w-enVerifyPassword {width: 150px !important;}
|
||||
|
||||
@@ -99,7 +99,7 @@ class userModel extends model
|
||||
foreach($users as $account => $user)
|
||||
{
|
||||
$firstLetter = ucfirst(substr($account, 0, 1)) . ':';
|
||||
if(strpos($params, 'noletter') !== false) $firstLetter = '';
|
||||
if((strpos($params, 'noletter') !== false) or (isset($this->config->isINT) and $this->config->isINT)) $firstLetter = '';
|
||||
$users[$account] = $firstLetter . (($user->deleted and strpos($params, 'realname') === false) ? $account : ($user->realname ? $user->realname : $account));
|
||||
}
|
||||
|
||||
|
||||
@@ -23,8 +23,9 @@
|
||||
</div>
|
||||
<form class="load-indicator main-form form-ajax" id="createForm" method="post" target='hiddenwin'>
|
||||
<table align='center' class="table table-form">
|
||||
<?php $thClass = (isset($config->isINT) and $config->isINT) ? 'w-enVerifyPassword' : 'w-verifyPassword';?>
|
||||
<tr>
|
||||
<th class='w-verifyPassword'><?php echo $lang->user->dept;?></th>
|
||||
<th class='<?php echo $thClass?>'><?php echo $lang->user->dept;?></th>
|
||||
<td class='w-p40'><?php echo html::select('dept', $depts, $deptID, "class='form-control chosen'");?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
||||
@@ -48,10 +48,11 @@
|
||||
</table>
|
||||
<table align='center' class='table table-form'>
|
||||
<caption class='text-left text-muted'><?php echo $lang->user->accountInfo;?></caption>
|
||||
<?php $thClass = (isset($config->isINT) and $config->isINT) ? 'w-130px' : 'w-90px';?>
|
||||
<tr>
|
||||
<th class='w-100px'><?php echo $lang->user->account;?></th>
|
||||
<td class='w-p40'><?php echo html::input('account', $user->account, "class='form-control'");?></td>
|
||||
<th class='w-90px'><?php echo $lang->user->email;?></th>
|
||||
<th class='<?php echo $thClass?>'><?php echo $lang->user->email;?></th>
|
||||
<td>
|
||||
<?php echo html::input('email', $user->email, "class='form-control'");?>
|
||||
<input type='text' style="display:none"> <!-- Disable input account by browser automatically. -->
|
||||
@@ -93,8 +94,9 @@
|
||||
</table>
|
||||
<table align='center' class='table table-form'>
|
||||
<caption class='text-left text-muted'><?php echo $lang->user->verify;?></caption>
|
||||
<?php $thClass = (isset($config->isINT) and $config->isINT) ? 'w-enVerifyPassword' : 'w-verifyPassword';?>
|
||||
<tr>
|
||||
<th class='w-verifyPassword'><?php echo $lang->user->verifyPassword;?></th>
|
||||
<th class='<?php echo $thClass?>'><?php echo $lang->user->verifyPassword;?></th>
|
||||
<td>
|
||||
<div class="required required-wrapper"></div>
|
||||
<?php echo html::password('verifyPassword', '', "class='form-control disabled-ie-placeholder' placeholder='{$lang->user->placeholder->verify}'");?>
|
||||
|
||||
@@ -721,6 +721,30 @@ function getFingerprint()
|
||||
return fingerprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert plain text URLs into HTML hyperlinks
|
||||
*
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
function convertURL()
|
||||
{
|
||||
if($('.article-content, .article>.content').size() == 0) return;
|
||||
|
||||
var aTags = new Array();
|
||||
var content = $('.article-content, .article>.content').html();
|
||||
$('.article-content, .article>.content').find('a').each(function(i)
|
||||
{
|
||||
aTags[i] = $(this).prop('outerHTML');
|
||||
content = content.replace(aTags[i], '<REPLACE_' + i + '>');
|
||||
});
|
||||
|
||||
var regexp = /(http:\/\/|https:\/\/)((\w|=|\?|\.|\/|\&|-|%|;)+)/g;
|
||||
content = content.replace(regexp, function($url){ return "<a href='" + $url + "' target='_blank'>" + $url + "</a>";});
|
||||
for(i in aTags) content = content.replace('<REPLACE_' + i + '>', aTags[i]);
|
||||
$('.article-content, .article>.content').html(content);
|
||||
}
|
||||
|
||||
/* Ping the server every some minutes to keep the session. */
|
||||
needPing = true;
|
||||
|
||||
@@ -731,6 +755,7 @@ $(document).ready(function()
|
||||
|
||||
checkTutorial();
|
||||
revertModuleCookie();
|
||||
convertURL();
|
||||
|
||||
$(document).on('click', '#helpMenuItem .close-help-tab', function(){$('#helpMenuItem').prev().remove();$('#helpMenuItem').remove();});
|
||||
});
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
.main-table .table{cursor:pointer;}
|
||||
|
||||
#dropMenu.show-right-col{width:502px;max-width:520px;}
|
||||
#dropMenu.has-search-text{width:250px;max-width:260px;}
|
||||
#dropMenu.has-search-text .col-right{margin-left:0px;}
|
||||
#dropMenu>.search-box{max-width:240px;}
|
||||
#dropMenu .list-group{width:250px; max-width:260px;}
|
||||
#dropMenu.show-right-col>.list-group{width:502px;max-width:520px;}
|
||||
|
||||
@@ -86,7 +86,19 @@ class xuanxuanChat extends chatModel
|
||||
public function getServer($backend = 'xxb')
|
||||
{
|
||||
$server = commonModel::getSysURL();
|
||||
if(!empty($this->config->xuanxuan->server)) $server = $this->config->xuanxuan->server;
|
||||
if(!empty($this->config->xuanxuan->server))
|
||||
{
|
||||
$host = $this->server->http_host;
|
||||
$position = strrpos($host, ':');
|
||||
$port = $position === false ? '' : substr($host, $position + 1);
|
||||
$server = $this->config->xuanxuan->server;
|
||||
if($port and strpos($server, ":$port") === false)
|
||||
{
|
||||
$server = rtrim($server, '/');
|
||||
$server = "{$server}:{$port}";
|
||||
}
|
||||
}
|
||||
$server = rtrim($server, '/');
|
||||
|
||||
return $server;
|
||||
}
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user