Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms into release/zentaopms_18.3

This commit is contained in:
tianshujie
2023-03-17 08:28:02 +08:00
53 changed files with 249 additions and 156 deletions
+2 -2
View File
@@ -102,10 +102,10 @@ zentaoxx:
mkdir zentaoxx/db/
cp zentaoxx/db_bak/upgradexuanxuan*.sql zentaoxx/db_bak/xuanxuan.sql zentaoxx/db/
rm -rf zentaoxx/db_bak/
sed -i "s/\$$accountAdmin = \$$this->dao->select('account, admin')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch();/\$$accountAdmin = \$$this->dao->select('account')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch();\n\$$admins = \$$this->dao->select('admins')->from(TABLE_COMPANY)->where('id')->eq(\$$this->app->company->id)->fetch('admins');\n\$$adminArray = explode(',', \$$admins);\n\$$accountAdmin->admin = in_array(\$$accountAdmin->account, \$$adminArray) ? 'super' : '';\n/" zentaoxx/extension/xuan/im/model/chat.php
sed -i "s/\$$accountAdmin = \$$this->dao->select('account, admin')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch();/\$$accountAdmin = \$$this->dao->select('account')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch();\n\$$sysAdmins = \$$this->dao->select('admins')->from(TABLE_COMPANY)->where('id')->eq(\$$this->app->company->id)->fetch('admins');\n\$$sysAdminArray = explode(',', \$$sysAdmins);\n\$$accountAdmin->admin = in_array(\$$accountAdmin->account, \$$sysAdminArray) ? 'super' : '';\n/" zentaoxx/extension/xuan/im/model/chat.php
sed -i "s/\$$sysAdmins = \$$this->dao->select('id')->from(TABLE_USER)->where('admin')->eq('super')->fetchPairs();/\$$account = \$$this->loadModel('user')->getById(\$$userID);\n\$$admins = \$$this->dao->select('admins')->from(TABLE_COMPANY)->where('id')->eq(\$$this->app->company->id)->fetch('admins');\n\$$adminArray = explode(',', \$$admins);\nreturn in_array(\$$account, \$$adminArray);\n/" zentaoxx/extension/xuan/im/model/chat.php
sed -i "/->on('tc.ownedBy=tu.account')/{ N ; s/type/tc.type/}" zentaoxx/extension/xuan/im/model/chat.php
sed -i "s/\$$super = \$$this->dao->select('admin')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch('admin');/\$$account = \$$this->dao->select('account')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch('account');\n\$$admins = \$$this->dao->select('admins')->from(TABLE_COMPANY)->where('id')->eq(\$$this->app->company->id)->fetch('admins');\n\$$adminArray = explode(',', \$$admins);\n\$$super = in_array(\$$account, \$$adminArray) ? 'super' : '';/g" zentaoxx/extension/xuan/im/control.php
sed -i "s/\$$super = \$$this->dao->select('admin')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch('admin');/\$$account = \$$this->dao->select('account')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch('account');\n\$$sysAdmins = \$$this->dao->select('admins')->from(TABLE_COMPANY)->where('id')->eq(\$$this->app->company->id)->fetch('admins');\n\$$sysAdminArray = explode(',', \$$sysAdmins);\n\$$super = in_array(\$$account, \$$sysAdminArray) ? 'super' : '';/g" zentaoxx/extension/xuan/im/control.php
sed -i "/foreach(\$$users as \$$user)/i \$$admins = \$$this->dao->select('admins')->from(TABLE_COMPANY)->where('id')->eq(\$$this->app->company->id)->fetch('admins');\$$adminArray = explode(',', \$$admins);" zentaoxx/extension/xuan/im/model/user.php
sed -i "/if(\!isset(\$$user->signed)) \$$user->signed = 0;/a \$$user->admin = in_array(\$$user->account, \$$adminArray) ? 'super' : '';" zentaoxx/extension/xuan/im/model/user.php
sed -i "/updateUser->ping/d" zentaoxx/extension/xuan/im/model/user.php
+1 -1
View File
@@ -48,7 +48,7 @@ class hostSubmitEntry extends baseEntry
{
if(in_array($image->status, array('failed', 'completed'))) $image->status = $image->status == 'completed' ? 'restore_completed' : 'restore_failed';
}
else if($imageInfo->from == 'snapshot' && $imageInfo->status == 'creating')
else if($imageInfo->from == 'snapshot')
{
if($image->status == 'failed')
{
+11
View File
@@ -2,3 +2,14 @@ ALTER TABLE `zt_lang` MODIFY COLUMN `section` varchar(50) NOT NULL;
DELETE FROM `zt_grouppriv` WHERE `module` = 'dev' AND `method` = 'editor';
REPLACE INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system','common','','setPercent','1');
DROP TABLE IF EXISTS `zt_dimension`;
REPLACE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `system`) VALUES
('zh-tw', 'custom', 'URSRList', '1', '{"SRName":"\\u8edf\\u4ef6\\u9700\\u6c42","URName":"\\u7528\\u6236\\u9700\\u6c42"}', '0'),
('zh-tw', 'custom', 'URSRList', '2', '{"SRName":"\\u7814\\u767c\\u9700\\u6c42","URName":"\\u7528\\u6236\\u9700\\u6c42"}', '0'),
('zh-tw', 'custom', 'URSRList', '3', '{"SRName":"\\u8edf\\u9700","URName":"\\u7528\\u9700"}', '0'),
('zh-tw', 'custom', 'URSRList', '4', '{"SRName":"\\u6545\\u4e8b","URName":"\\u53f2\\u8a69"}', '0'),
('zh-tw', 'custom', 'URSRList', '5', '{"SRName":"\\u9700\\u6c42","URName":"\\u7528\\u6236\\u9700\\u6c42"}', '0'),
('fr', 'custom', 'URSRList', '1', '{\"SRName\":\"Story\",\"URName\":\"Epic\"}', '0'),
('fr', 'custom', 'URSRList', '2', '{\"SRName\":\"Software Requirement\",\"URName\":\"User Requirement\"}', '0'),
('de', 'custom', 'URSRList', '1', '{\"SRName\":\"Story\",\"URName\":\"Epic\"}', '0'),
('de', 'custom', 'URSRList', '2', '{\"SRName\":\"Software Requirement\",\"URName\":\"User Requirement\"}', '0');
+14 -3
View File
@@ -6381,11 +6381,22 @@ INSERT INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
(12,'my','limited');
REPLACE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `system`) VALUES
('zh-cn', 'custom', 'URSRList', '1', '{\"SRName\":\"\\u8f6f\\u4ef6\\u9700\\u6c42\",\"URName\":\"\\u7528\\u6237\\u9700\\u6c42\"}', '1'),('zh-cn', 'custom', 'URSRList', '2', '{\"SRName\":\"\\u7814\\u53d1\\u9700\\u6c42\",\"URName\":\"\\u7528\\u6237\\u9700\\u6c42\"}', '1'),
('zh-cn', 'custom', 'URSRList', '3', '{\"SRName\":\"\\u8f6f\\u9700\",\"URName\":\"\\u7528\\u9700\"}', '1'),('zh-cn', 'custom', 'URSRList', '4', '{\"SRName\":\"\\u6545\\u4e8b\",\"URName\":\"\\u53f2\\u8bd7\"}', '1'),
('zh-cn', 'custom', 'URSRList', '1', '{\"SRName\":\"\\u8f6f\\u4ef6\\u9700\\u6c42\",\"URName\":\"\\u7528\\u6237\\u9700\\u6c42\"}', '1'),
('zh-cn', 'custom', 'URSRList', '2', '{\"SRName\":\"\\u7814\\u53d1\\u9700\\u6c42\",\"URName\":\"\\u7528\\u6237\\u9700\\u6c42\"}', '1'),
('zh-cn', 'custom', 'URSRList', '3', '{\"SRName\":\"\\u8f6f\\u9700\",\"URName\":\"\\u7528\\u9700\"}', '1'),
('zh-cn', 'custom', 'URSRList', '4', '{\"SRName\":\"\\u6545\\u4e8b\",\"URName\":\"\\u53f2\\u8bd7\"}', '1'),
('zh-cn', 'custom', 'URSRList', '5', '{\"SRName\":\"\\u9700\\u6c42\",\"URName\":\"\\u7528\\u6237\\u9700\\u6c42\"}', '1'),
('zh-tw', 'custom', 'URSRList', '1', '{"SRName":"\\u8edf\\u4ef6\\u9700\\u6c42","URName":"\\u7528\\u6236\\u9700\\u6c42"}', '0'),
('zh-tw', 'custom', 'URSRList', '2', '{"SRName":"\\u7814\\u767c\\u9700\\u6c42","URName":"\\u7528\\u6236\\u9700\\u6c42"}', '0'),
('zh-tw', 'custom', 'URSRList', '3', '{"SRName":"\\u8edf\\u9700","URName":"\\u7528\\u9700"}', '0'),
('zh-tw', 'custom', 'URSRList', '4', '{"SRName":"\\u6545\\u4e8b","URName":"\\u53f2\\u8a69"}', '0'),
('zh-tw', 'custom', 'URSRList', '5', '{"SRName":"\\u9700\\u6c42","URName":"\\u7528\\u6236\\u9700\\u6c42"}', '0'),
('en', 'custom', 'URSRList', '1', '{\"SRName\":\"Story\",\"URName\":\"Epic\"}', '0'),
('en', 'custom', 'URSRList', '2', '{\"SRName\":\"Software Requirement\",\"URName\":\"User Requirement\"}', '0');
('en', 'custom', 'URSRList', '2', '{\"SRName\":\"Software Requirement\",\"URName\":\"User Requirement\"}', '0'),
('fr', 'custom', 'URSRList', '1', '{\"SRName\":\"Story\",\"URName\":\"Epic\"}', '0'),
('fr', 'custom', 'URSRList', '2', '{\"SRName\":\"Software Requirement\",\"URName\":\"User Requirement\"}', '0'),
('de', 'custom', 'URSRList', '1', '{\"SRName\":\"Story\",\"URName\":\"Epic\"}', '0'),
('de', 'custom', 'URSRList', '2', '{\"SRName\":\"Software Requirement\",\"URName\":\"User Requirement\"}', '0');
REPLACE INTO `zt_stage` (`name`,`percent`,`type`,`projectType`,`createdBy`,`createdDate`,`editedBy`,`editedDate`,`deleted`) VALUES
('需求','10','request','waterfall','admin','2020-02-08 21:08:30','admin','2020-02-12 13:50:27','0'),
+13 -7
View File
@@ -101,8 +101,6 @@ class router extends baseRouter
global $lang;
if(!is_object($lang)) $lang = new language();
$appName = '';
/* Set productCommon and projectCommon for flow. */
if($moduleName == 'common') $this->setCommonLang();
@@ -111,7 +109,13 @@ class router extends baseRouter
/* Replace main nav lang. */
if($moduleName == 'common' and $this->dbh and !empty($this->config->db->name))
{
$customMenus = $this->dbh->query('SELECT * FROM' . TABLE_LANG . "WHERE `module`='common' AND `section`='mainNav' AND `lang`='{$this->clientLang}' AND `vision`='{$this->config->vision}'")->fetchAll();
$customMenus = array();
try
{
$customMenus = $this->dbh->query('SELECT * FROM' . TABLE_LANG . "WHERE `module`='common' AND `section`='mainNav' AND `lang`='{$this->clientLang}' AND `vision`='{$this->config->vision}'")->fetchAll();
}
catch(PDOException $exception){}
foreach($customMenus as $menu)
{
$menuKey = $menu->key;
@@ -317,7 +321,12 @@ class router extends baseRouter
}
/* Replace common lang. */
$customMenus = $this->dbh->query('SELECT * FROM' . TABLE_LANG . "WHERE `module`='common' AND `lang`='{$this->clientLang}' AND `section`='' AND `vision`='{$config->vision}'")->fetchAll();
$customMenus = array();
try
{
$customMenus = $this->dbh->query('SELECT * FROM' . TABLE_LANG . "WHERE `module`='common' AND `lang`='{$this->clientLang}' AND `section`='' AND `vision`='{$config->vision}'")->fetchAll();
}
catch(PDOException $exception){}
foreach($customMenus as $menu) if(isset($lang->{$menu->key})) $lang->{$menu->key} = $menu->value;
}
}
@@ -356,9 +365,6 @@ class router extends baseRouter
public function loadModuleConfig($moduleName, $appName = '')
{
global $config;
$appName = '';
if($config and (!isset($config->$moduleName) or !is_object($config->$moduleName))) $config->$moduleName = new stdclass();
/* 初始化数组。Init the variables. */
+2 -2
View File
@@ -453,7 +453,7 @@ class actionModel extends model
elseif($actionName == 'unlinkedfromexecution')
{
$name = $this->dao->select('name')->from(TABLE_PROJECT)->where('id')->eq($action->extra)->fetch('name');
if($name) $action->extra = common::hasPriv('project', 'story') ? html::a(helper::createLink('project', 'story', "projectID=$action->extra"), "#$action->extra " . $name) : "#$action->extra " . $name;
if($name) $action->extra = common::hasPriv('execution', 'view') ? html::a(helper::createLink('execution', 'view', "executionID=$action->extra"), "#$action->extra " . $name) : "#$action->extra " . $name;
}
elseif($actionName == 'unlinkedfromproject')
{
@@ -949,7 +949,7 @@ class actionModel extends model
else
{
if($actionType == 'restoredsnapshot' && in_array($action->objectType, array('vm', 'zanode')) && $value == 'defaultSnap') $value = $this->lang->$objectType->snapshot->defaultSnapName;
$desc = str_replace('$' . $key, $value, $desc);
}
}
+1 -1
View File
@@ -106,7 +106,7 @@ $lang->admin->setModule->auditplan = 'QA';
$lang->admin->setModule->meeting = 'Meeting';
$lang->admin->setModule->roadmap = 'Roadmap';
$lang->admin->setModule->track = 'Track';
$lang->admin->setModule->UR = 'URStroy';
$lang->admin->setModule->UR = $lang->URCommon;
$lang->admin->setModule->researchplan = 'Researchplan';
$lang->admin->setModule->gapanalysis = 'Gapanalysis';
$lang->admin->setModule->storylib = 'Story Lib';
+1 -1
View File
@@ -106,7 +106,7 @@ $lang->admin->setModule->auditplan = 'QA';
$lang->admin->setModule->meeting = 'Meeting';
$lang->admin->setModule->roadmap = 'Roadmap';
$lang->admin->setModule->track = 'Track';
$lang->admin->setModule->UR = 'URStroy';
$lang->admin->setModule->UR = $lang->URCommon;
$lang->admin->setModule->researchplan = 'Researchplan';
$lang->admin->setModule->gapanalysis = 'Gapanalysis';
$lang->admin->setModule->storylib = 'Story Lib';
+1 -1
View File
@@ -106,7 +106,7 @@ $lang->admin->setModule->auditplan = 'QA';
$lang->admin->setModule->meeting = 'Meeting';
$lang->admin->setModule->roadmap = 'Roadmap';
$lang->admin->setModule->track = 'Track';
$lang->admin->setModule->UR = 'URStroy';
$lang->admin->setModule->UR = $lang->URCommon;
$lang->admin->setModule->researchplan = 'Researchplan';
$lang->admin->setModule->gapanalysis = 'Gapanalysis';
$lang->admin->setModule->storylib = 'Story Lib';
+1 -1
View File
@@ -106,7 +106,7 @@ $lang->admin->setModule->auditplan = 'QA';
$lang->admin->setModule->meeting = '会议';
$lang->admin->setModule->roadmap = '路线图';
$lang->admin->setModule->track = '矩阵';
$lang->admin->setModule->UR = '用户需求';
$lang->admin->setModule->UR = $lang->URCommon;
$lang->admin->setModule->researchplan = '调研';
$lang->admin->setModule->gapanalysis = '培训';
$lang->admin->setModule->storylib = '需求库';
+1
View File
@@ -666,6 +666,7 @@ class adminModel extends model
->limit('1')
->fetch('date');
if($firstUseDate) $firstUseDate = substr($firstUseDate, 0, 10);
return helper::getDateInterval($firstUseDate);
}
+1 -1
View File
@@ -45,7 +45,7 @@
$viewLink = $this->createLink('execution', 'task', 'executionID=' . $execution->id);
?>
<tr <?php echo $appid?>>
<td class='c-name text-left' title='<?php echo $execution->name;?>'><nobr><?php echo html::a($viewLink, $execution->name, '', "title='$execution->name'");?></nobr></td>
<td class='c-name text-left' title='<?php echo $execution->name;?>'><nobr><?php echo html::a($viewLink, $execution->name, '', "title='$execution->name' class='text-primary'");?></nobr></td>
<td class="c-date"><?php echo $execution->end;?></td>
<?php if($longBlock):?>
<td class="w-70px">
+1 -1
View File
@@ -217,7 +217,7 @@ $config->bug->datatable->fieldList['project']['fixed'] = 'no';
$config->bug->datatable->fieldList['project']['width'] = '120';
$config->bug->datatable->fieldList['project']['required'] = 'no';
$config->bug->datatable->fieldList['project']['control'] = 'hidden';
$config->bug->datatable->fieldList['project']['dataSource'] = array('module' => 'product', 'method' => 'getProjectPairsByProduct', 'params' => '$productID');
$config->bug->datatable->fieldList['project']['dataSource'] = array('module' => 'product', 'method' => 'getProjectPairsByProduct', 'params' => '$productID&');
$config->bug->datatable->fieldList['execution']['title'] = 'execution';
$config->bug->datatable->fieldList['execution']['fixed'] = 'no';
+1
View File
@@ -22,6 +22,7 @@ th.c-confirmed {text-align: center;}
.c-severity {overflow: hidden; white-space: nowrap;}
.c-keywords {overflow: hidden; white-space: nowrap;}
.c-id {text-overflow: ellipsis; white-space: nowrap;}
.c-toTask {overflow: hidden; white-space: nowrap;}
.body-modal #mainMenu>.btn-toolbar {width: auto;}
+1 -1
View File
@@ -125,7 +125,7 @@ if($this->app->tab == 'project') js::set('objectID', $bug->project);
</div>
</td>
</tr>
<tr class='<?php if($product->shadow and isset($project) and !$project->multiple) echo 'hide'?>'>
<tr class='<?php if($product->shadow and isset($project) and $project->multiple) echo 'hide'?>'>
<th><?php echo $lang->bug->productplan;?></th>
<td>
<span id="planIdBox"><?php echo html::select('plan', $plans, $bug->plan, "class='form-control chosen'");?></span>
+1 -1
View File
@@ -161,7 +161,7 @@
<th><?php echo $lang->bug->fromCase;?></th>
<td><?php if($bug->case) echo html::a(helper::createLink('testcase', 'view', "caseID=$bug->case&version=$bug->caseVersion", '', true), "<i class='icon icon-sitemap'></i> {$lang->bug->fromCase}$lang->colon$bug->case", '', isonlybody() ? '' : "data-toggle='modal' data-type='iframe' data-width='80%'");?></td>
</tr>
<tr valign='middle' class='<?php if($product->shadow and isset($project) and !empty($project->multiple)) echo 'hide'?>'>
<tr valign='middle' class='<?php if($product->shadow and isset($project) and empty($project->multiple)) echo 'hide'?>'>
<th><?php echo $lang->bug->productplan;?></th>
<td><?php if(!$bug->plan or !common::printLink('productplan', 'view', "planID=$bug->plan&type=bug", $bug->planName)) echo $bug->planName;?></td>
</tr>
+1 -1
View File
@@ -25,7 +25,7 @@
</tr>
<tr>
<th><?php echo $lang->caselib->desc;?></th>
<td><?php echo html::textarea('desc', '', "rows=10 class='form-control'");?></td>
<td><?php echo html::textarea('desc', '', "rows=10 class='form-control kindeditor'");?></td>
</tr>
<?php $this->printExtendFields('', 'table');?>
<tr>
+1 -1
View File
@@ -90,7 +90,7 @@ $lang->viewDetails = 'View Details';
$lang->actions = 'Aktionen';
$lang->restore = 'Wiederherstellen';
$lang->confirmDraft = 'There are unsaved form of %name%. Do you want to restore them?';
$lang->confirmDraft = 'Unsaved form is found. Do you want to restore it?';
$lang->resume = 'resume';
$lang->comment = 'Notiz';
$lang->history = 'Historie';
+1 -1
View File
@@ -90,7 +90,7 @@ $lang->viewDetails = 'View Details';
$lang->actions = 'Action';
$lang->restore = 'Reset';
$lang->confirmDraft = 'There are unsaved form of %name%. Do you want to restore them?';
$lang->confirmDraft = 'Unsaved form is found. Do you want to restore it?';
$lang->resume = 'resume';
$lang->comment = 'Note';
$lang->history = 'History';
+1 -1
View File
@@ -90,7 +90,7 @@ $lang->viewDetails = 'View Details';
$lang->actions = 'Action';
$lang->restore = 'Réinitialiser';
$lang->confirmDraft = 'There are unsaved form of %name%. Do you want to restore them?';
$lang->confirmDraft = 'Unsaved form is found. Do you want to restore it?';
$lang->resume = 'resume';
$lang->comment = 'Note';
$lang->history = 'Historique';
+4
View File
@@ -109,6 +109,10 @@ $uid = uniqid('');
items: editorTool,
placeholder: $editor.attr('placeholder') || options.placeholder || '',
pasteImage: {postUrl: createLink('file', 'ajaxPasteImg', 'uid=' + kuid), placeholder: $editor.attr('placeholder') || <?php echo json_encode($lang->noticePasteImg);?>},
afterChange: function()
{
$editor.closest('.main-form').trigger('change');
}
});
try
-2
View File
@@ -577,7 +577,6 @@ class customModel extends model
public function getURSRPairs()
{
$lang = $this->app->getClientLang();
$lang = $lang == 'zh-tw' ? 'zh-cn' : $lang;
$langData = $this->dao->select('`key`, `value`, `system`')->from(TABLE_LANG)
->where('lang')->eq($lang)
->andWhere('module')->eq('custom')
@@ -659,7 +658,6 @@ class customModel extends model
{
$this->app->loadLang('custom');
$lang = $this->app->getClientLang();
$lang = $lang == 'zh-tw' ? 'zh-cn' : $lang;
$langData = $this->dao->select('`key`, `value`, `system`')->from(TABLE_LANG)
->where('lang')->eq($lang)
+3 -3
View File
@@ -1,7 +1,7 @@
<?php
$lang->dev->common = 'Entwicklung';
$lang->dev->api = 'API';
$lang->dev->db = 'Datenbank';
$lang->dev->api = 'API Document';
$lang->dev->db = 'Data Dictionary';
$lang->dev->editor = 'Bearbeiter';
$lang->dev->translate = 'Translate';
$lang->dev->dbList = 'Datenbank';
@@ -18,7 +18,7 @@ $lang->dev->paramRange = 'Parameter Range: %s';
$lang->dev->paramDate = 'Date format: YY-mm-dd, e.g 2019-01-01';
$lang->dev->paramColor = 'Color format: #RGB, e.g. #3da7f5';
$lang->dev->paramMailto = "User account. Separate accounts by ','.";
$lang->dev->noteEditor = "The editor is disabled for security reasons. To use this feature, please go to the official website to download and install the plugin of the <a href='https://www.zentao.net/extension-viewExt-150.html' target='_blank'>editor</a>.";
$lang->dev->noteEditor = "The editor is disabled for security reasons. To use this feature, Please turn on.";
$lang->dev->noteTranslate = "The translation is disabled for security reasons. To use this feature, please go to the official website to download and install the plugin of <a href='https://www.zentao.net/extension-viewExt-151.html' target='_blank'>translation</a>.";
$lang->dev->confirmRestore = 'Do you want to reset?';
+3 -3
View File
@@ -1,7 +1,7 @@
<?php
$lang->dev->common = 'Develop';
$lang->dev->api = 'API';
$lang->dev->db = 'Database';
$lang->dev->api = 'API Document';
$lang->dev->db = 'Data Dictionary';
$lang->dev->editor = 'Editor';
$lang->dev->translate = 'Translate';
$lang->dev->dbList = 'Database';
@@ -18,7 +18,7 @@ $lang->dev->paramRange = 'Parameter Range: %s';
$lang->dev->paramDate = 'Date format: YY-mm-dd, e.g 2019-01-01';
$lang->dev->paramColor = 'Color format: #RGB, e.g. #3da7f5';
$lang->dev->paramMailto = "User account. Separate accounts by ','.";
$lang->dev->noteEditor = "The editor is disabled for security reasons. To use this feature, please go to the official website to download and install the plugin of the <a href='https://www.zentao.net/extension-viewExt-150.html' target='_blank'>editor</a>.";
$lang->dev->noteEditor = "The editor is disabled for security reasons. To use this feature, Please turn on.";
$lang->dev->noteTranslate = "The translation is disabled for security reasons. To use this feature, please go to the official website to download and install the plugin of <a href='https://www.zentao.net/extension-viewExt-151.html' target='_blank'>translation</a>.";
$lang->dev->confirmRestore = 'Do you want to reset?';
+3 -3
View File
@@ -1,7 +1,7 @@
<?php
$lang->dev->common = 'Develop';
$lang->dev->api = 'API';
$lang->dev->db = 'Database';
$lang->dev->api = 'API Document';
$lang->dev->db = 'Data Dictionary';
$lang->dev->editor = 'Editor';
$lang->dev->translate = 'Translate';
$lang->dev->dbList = 'Database';
@@ -18,7 +18,7 @@ $lang->dev->paramRange = 'Parameter Range: %s';
$lang->dev->paramDate = 'Date format: YY-mm-dd, e.g 2019-01-01';
$lang->dev->paramColor = 'Color format: #RGB, e.g. #3da7f5';
$lang->dev->paramMailto = "User account. Separate accounts by ','.";
$lang->dev->noteEditor = "The editor is disabled for security reasons. To use this feature, please go to the official website to download and install the plugin of the <a href='https://www.zentao.net/extension-viewExt-150.html' target='_blank'>editor</a>.";
$lang->dev->noteEditor = "The editor is disabled for security reasons. To use this feature, Please turn on.";
$lang->dev->noteTranslate = "The translation is disabled for security reasons. To use this feature, please go to the official website to download and install the plugin of <a href='https://www.zentao.net/extension-viewExt-151.html' target='_blank'>translation</a>.";
$lang->dev->confirmRestore = 'Do you want to reset?';
+2 -2
View File
@@ -1,7 +1,7 @@
<?php
$lang->dev->common = '二次开发';
$lang->dev->api = 'API';
$lang->dev->db = '数据库';
$lang->dev->api = '接口文档';
$lang->dev->db = '数据字典';
$lang->dev->editor = '编辑器';
$lang->dev->translate = '翻译';
$lang->dev->dbList = '数据库';
+8 -1
View File
@@ -418,6 +418,7 @@ class devModel extends model
$originalLangs['SRCommon'] = $this->lang->dev->SR;
$URSRList = $this->loadModel('custom')->getItems("lang={$language}&module=custom&section=URSRList&key={$this->config->custom->URSR}&vision={$this->config->vision}");
if(empty($URSRList)) $URSRList = $this->custom->getItems("lang={$language}&module=custom&section=URSRList&vision={$this->config->vision}");
$URSRList = array_shift($URSRList);
if($URSRList)
{
@@ -505,6 +506,7 @@ class devModel extends model
$customedLangs['URCommon'] = $this->lang->dev->UR == $this->lang->URCommon ? '' : $this->lang->URCommon;
$customedLangs['SRCommon'] = $this->lang->dev->SR == $this->lang->SRCommon ? '' : $this->lang->SRCommon;
$URSRList = $this->custom->getItems("lang={$language}&module=custom&section=URSRList&key={$this->config->custom->URSR}&vision={$this->config->vision}");
if(empty($URSRList)) $URSRList = $this->custom->getItems("lang={$language}&module=custom&section=URSRList&vision={$this->config->vision}");
$URSRList = array_shift($URSRList);
if($URSRList)
{
@@ -1040,7 +1042,12 @@ class devModel extends model
$_POST = array();
$oldValue = $this->dao->select('*')->from(TABLE_LANG)->where('`key`')->eq($this->config->custom->URSR)->andWhere('section')->eq('URSRList')->andWhere('lang')->eq($language)->andWhere('module')->eq('custom')->fetch('value');
$oldValue = json_decode($oldValue);
$URSRList = $this->loadModel('custom')->getItems("lang={$language}&module=custom&section=URSRList&key={$this->config->custom->URSR}&vision={$this->config->vision}");
if(empty($URSRList)) $URSRList = $this->custom->getItems("lang={$language}&module=custom&section=URSRList&vision={$this->config->vision}");
$URSRList = array_shift($URSRList);
$this->config->custom->URSR = $URSRList->key;
$oldValue = json_decode($URSRList->value);
$_POST['SRName'] = !empty($post['common_SRCommon']) ? $post['common_SRCommon'] : zget($oldValue, 'defaultSRName', $oldValue->SRName);
$_POST['URName'] = !empty($post['common_URCommon']) ? $post['common_URCommon'] : zget($oldValue, 'defaultURName', $oldValue->URName);
+1 -1
View File
@@ -47,7 +47,7 @@
</div>
<?php endif;?>
<form class='main-form form-ajax flex-1' method='post'>
<form class='main-form form-ajax flex-1' method='post' id="data-form-<?php echo $type?>">
<div class="main-content">
<div class="title-content flex">
<?php if(str_replace('-', '_', $this->app->getClientLang()) != $language):?>
+8 -1
View File
@@ -160,9 +160,16 @@ class editor extends control
{
$filePath = helper::safe64Decode($filePath);
if(strpos(strtolower($filePath), strtolower($this->app->getBasePath())) !== 0) return print($this->lang->editor->editFileError);
$fileName = empty($_POST['fileName']) ? '' : trim($this->post->fileName);
if(empty($fileName)) return print(js::error($this->lang->editor->emptyFileName));
if($action != 'edit' and $action != 'newPage') $filePath = $this->editor->getSavePath($filePath, $action);
if($action != 'edit' and $action != 'newPage' and file_exists($filePath) and !$this->post->override) return print(js::error($this->lang->editor->repeatFile));
if(!$this->editor->save($filePath)) return;
$result = $this->editor->save($filePath);
if(is_string($result)) return print(js::alert($result));
echo js::reload('parent.parent.extendWin');
return print(js::locate(inlink('edit', "filePath=" . helper::safe64Encode($filePath) . "&action=edit"), 'parent'));
}
+4 -4
View File
@@ -327,14 +327,14 @@ class editorModel extends model
/* Reduce expiration time for check safe file. */
$this->config->safeFileTimeout = 15 * 60;
$statusFile = $this->loadModel('common')->checkSafeFile();
if($statusFile) return print(js::alert(sprintf($this->lang->editor->noticeOkFile, str_replace('\\', '/', $statusFile))));
if($statusFile) return sprintf($this->lang->editor->noticeOkFile, str_replace('\\', '/', $statusFile));
$dirPath = dirname($filePath);
$extFilePath = substr($filePath, 0, strpos($filePath, DS . 'ext' . DS) + 4);
if(!is_dir($dirPath) and is_writable($extFilePath)) mkdir($dirPath, 0777, true);
if(!is_dir($dirPath)) return print(js::alert(sprintf($this->lang->editor->notExists, $extFilePath)));
if(!is_writable($dirPath)) return print(js::alert(sprintf($this->lang->editor->notWritable, $extFilePath)));
if(strpos(strtolower(realpath($dirPath)), strtolower($this->app->getBasePath())) !== 0) return print(js::alert($this->lang->editor->editFileError));
if(!is_dir($dirPath)) return sprintf($this->lang->editor->notExists, $extFilePath);
if(!is_writable($dirPath)) return sprintf($this->lang->editor->notWritable, $extFilePath);
if(strpos(strtolower(realpath($dirPath)), strtolower($this->app->getBasePath())) !== 0) return $this->lang->editor->editFileError;
$fileContent = $this->post->fileContent;
$evils = array('eval', 'exec', 'passthru', 'proc_open', 'shell_exec', 'system', '$$', 'include', 'require', 'assert', 'javascript', 'onclick');
+1 -1
View File
@@ -27,5 +27,5 @@
#cfdChart {margin-top: -20px;}
#triggerModal .modal-dialog {top: 15% !important; overflow-y: auto; max-height: 80%;}
#triggerModal .modal-dialog {top: 15% !important; max-height: 80%;}
#triggerModal .modal-dialog::-webkit-scrollbar-track {background-color: white;}
+2 -2
View File
@@ -654,8 +654,8 @@ $lang->execution->gantt->exportFail = '导出失败。';
$lang->execution->boardColorList = array('#32C5FF', '#006AF1', '#9D28B2', '#FF8F26', '#7FBB00', '#424BAC', '#66c5f8', '#EC2761');
$lang->execution->linkBranchStoryByPlanTips = "执行按计划关联需求时,只导入本执行所关联%s的激活状态的需求。";
$lang->execution->linkNormalStoryByPlanTips = "执行按计划关联需求时,只导入激活状态的需求。";
$lang->execution->linkBranchStoryByPlanTips = "{$lang->execution->common}按计划关联需求时,只导入本{$lang->execution->common}所关联%s的激活状态的需求。";
$lang->execution->linkNormalStoryByPlanTips = "{$lang->execution->common}按计划关联需求时,只导入激活状态的需求。";
$lang->execution->featureBar['dynamic']['all'] = '全部';
$lang->execution->featureBar['dynamic']['today'] = '今天';
+3 -2
View File
@@ -5684,12 +5684,13 @@ class executionModel extends model
*/
public function generateRow($executions, $users, $productID)
{
$rows = array();
$today = helper::today();
$rows = array();
foreach($executions as $id => $execution)
{
$label = $execution->type == 'stage' ? 'label-warning' : 'label-info';
$link = $execution->type == 'kanban' ? helper::createLink('execution', 'kanban', "id=$execution->id") : helper::createLink('execution', 'task', "id=$execution->id");
$execution->name = "<span class='project-type-label label label-outline $label'>{$this->lang->execution->typeList[$execution->type]}</span> " . (empty($execution->children) ? html::a($link, $execution->name) : $execution->name);
$execution->name = "<span class='project-type-label label label-outline $label'>{$this->lang->execution->typeList[$execution->type]}</span> " . (empty($execution->children) ? html::a($link, $execution->name, '_self', 'class="text-primary"') : $execution->name) . (strtotime($today) > strtotime($execution->end) ? '<span class="label label-danger label-badge">' . $this->lang->execution->delayed . '</span>' : '');;
$execution->project = $execution->projectName;
$execution->parent = ($execution->parent and $execution->grade > 1) ? $execution->parent : '';
$execution->asParent = !empty($execution->children);
+3 -2
View File
@@ -271,6 +271,7 @@
<?php foreach($stories as $key => $story):?>
<?php
$totalEstimate += $story->estimate;
$story->from = $this->app->tab;
?>
<tr id="story<?php echo $story->id;?>" data-id='<?php echo $story->id;?>' data-order='<?php echo $story->order ?>' data-estimate='<?php echo $story->estimate?>' data-cases='<?php echo zget($storyCases, $story->id, 0)?>'>
<?php foreach($setting as $key => $value)
@@ -286,7 +287,7 @@
<?php if(!empty($story->children)):?>
<?php $i = 0;?>
<?php foreach($story->children as $key => $child):?>
<?php $child->from = 'execution';?>
<?php $child->from = $this->app->tab;?>
<?php $class = $i == 0 ? ' table-child-top' : '';?>
<?php $class .= ($i + 1 == count($story->children)) ? ' table-child-bottom' : '';?>
<tr class='table-children<?php echo $class;?> parent-<?php echo $story->id;?>' data-id='<?php echo $child->id?>' data-status='<?php echo $child->status?>' data-estimate='<?php echo $child->estimate?>' data-cases='<?php echo zget($storyCases, $story->id, 0);?>'>
@@ -404,7 +405,7 @@
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><i class="icon icon-close"></i></button>
<?php
$linkStoryByPlanTips = $multiBranch ? sprintf($lang->execution->linkBranchStoryByPlanTips, $lang->project->branch) : $lang->execution->linkNormalStoryByPlanTips;
$linkStoryByPlanTips = $execution->multiple ? $linkStoryByPlanTips : str_replace($lang->executionCommon, $lang->projectCommon, $linkStoryByPlanTips);
$linkStoryByPlanTips = $execution->multiple ? $linkStoryByPlanTips : str_replace($lang->execution->common, $lang->projectCommon, $linkStoryByPlanTips);
?>
<h4 class="modal-title"><?php echo $lang->execution->linkStoryByPlan;?></h4><?php echo '(' . $linkStoryByPlanTips . ')';?>
</div>
+1 -1
View File
@@ -39,7 +39,7 @@ class mr extends control
->andWhere('synced')->eq(1)
->orderBy('id')
->count();
if($repoCount == 0) $this->locate($this->repo->createLink('create'));
if($repoCount == 0) $this->locate($this->loadModel('repo')->createLink('create'));
$repoID = $this->loadModel('repo')->saveState($repoID, $objectID);
$repo = $this->repo->getRepoByID($repoID);
+14 -13
View File
@@ -4,26 +4,27 @@
<?php js::set('extra', $extra);?>
<style>
#navTabs {position: sticky; top: 0; background: #fff; z-index: 950;}
#navTabs>li {padding: 0px 10px; display: inline-block}
#navTabs>li>span {display: inline-block;}
#navTabs>li>a {margin: 0!important; padding: 8px 0px; display: inline-block}
#navTabs > li {padding: 0px 10px; display: inline-block}
#navTabs > li > span {display: inline-block;}
#navTabs > li > a {margin: 0!important; padding: 8px 0px; display: inline-block}
#tabContent {margin-top: 5px; z-index: 900; max-width: 220px}
.productTree ul {list-style: none; margin: 0}
.productTree .products>ul {padding-left: 7px;}
.productTree .products>ul>li>div {display: flex; flex-flow: row nowrap; justify-content: flex-start; align-items: center;}
.productTree .products>ul>li label {background: rgba(255,255,255,0.5); line-height: unset; color: #838a9d; border: 1px solid #d8d8d8; border-radius: 2px; padding: 1px 4px;}
.productTree .products>ul > li > div {display: flex; flex-flow: row nowrap; justify-content: flex-start; align-items: center;}
.productTree .products>ul > li label {background: rgba(255,255,255,0.5); line-height: unset; color: #838a9d; border: 1px solid #d8d8d8; border-radius: 2px; padding: 1px 4px;}
.productTree li a i.icon {font-size: 15px !important;}
.productTree li a i.icon:before {min-width: 16px !important;}
.productTree li .label {position: unset; margin-bottom: 0;}
.productTree li>a, div.hide-in-search>a {display: block; padding: 2px 10px 2px 5px; overflow: hidden; line-height: 20px; text-overflow: ellipsis; white-space: nowrap; border-radius: 4px;}
.productTree .tree li>.list-toggle {line-height: 24px;}
.productTree li > a, div.hide-in-search>a {display: block; padding: 2px 10px 2px 5px; overflow: hidden; line-height: 20px; text-overflow: ellipsis; white-space: nowrap; border-radius: 4px;}
.productTree .tree li > .list-toggle {line-height: 24px;}
.productTree .tree li.has-list.open:before {content: unset;}
.tree.noProgram li {padding-left: 0;}
#swapper li>div.hide-in-search>a:focus, #swapper li>div.hide-in-search>a:hover {color: #838a9d; cursor: default;}
#swapper li > div.hide-in-search>a:focus, #swapper li > div.hide-in-search>a:hover {color: #838a9d; cursor: default;}
#swapper li > a {margin-top: 4px; margin-bottom: 4px;}
#swapper li {padding-top: 0; padding-bottom: 0;}
#swapper .tree li>.list-toggle {top: -1px;}
#swapper .tree li > .list-toggle {top: -1px;}
#subHeader .tree ul {display: block;}
div#closed {width: 90px; height: 25px; line-height: 25px; background-color: #ddd; color: #3c495c; text-align: center; margin-left: 15px; border-radius: 2px;}
@@ -56,9 +57,9 @@ foreach($products as $programID => $programProducts)
}
$productsPinYin = common::convert2Pinyin($productNames);
$myProductsHtml = $config->systemMode == 'ALM' ? '<ul class="tree tree-angles" data-ride="tree">' : '';
$normalProductsHtml = $config->systemMode == 'ALM' ? '<ul class="tree tree-angles" data-ride="tree">' : '';
$closedProductsHtml = $config->systemMode == 'ALM' ? '<ul class="tree tree-angles" data-ride="tree">' : '';
$myProductsHtml = $config->systemMode == 'ALM' ? '<ul class="tree tree-angles" data-ride="tree">' : '<ul class="tree noProgram">';
$normalProductsHtml = $config->systemMode == 'ALM' ? '<ul class="tree tree-angles" data-ride="tree">' : '<ul class="tree noProgram">';
$closedProductsHtml = $config->systemMode == 'ALM' ? '<ul class="tree tree-angles" data-ride="tree">' : '<ul class="tree noProgram">';
foreach($products as $programID => $programProducts)
{
@@ -168,7 +169,7 @@ $(function()
$('.nav-tabs li span').hide();
$('.nav-tabs li.active').find('span').show();
$('.nav-tabs>li a').click(function()
$('.nav-tabs > li a').click(function()
{
if($('#swapper input[type="search"]').val() == '')
{
+1 -1
View File
@@ -28,7 +28,7 @@ class productplan extends control
$this->lang->product->branch = sprintf($this->lang->product->branch, $this->lang->product->branchName[$product->type]);
$this->app->loadConfig('execution');
$this->product->setMenu($productID, $branch);
if(!$product->shadow) $this->product->setMenu($productID, $branch);
$this->session->set('currentProductType', $product->type);
$branches = $this->loadModel('branch')->getList($productID, 0, 'all');
+12 -11
View File
@@ -3,26 +3,27 @@
<?php js::set('method', $method);?>
<style>
#navTabs {position: sticky; top: 0; background: #fff; z-index: 950;}
#navTabs>li {padding: 0px 10px; display: inline-block}
#navTabs>li>span {display: inline-block;}
#navTabs>li>a {margin: 0!important; padding: 8px 0px; display: inline-block}
#navTabs > li {padding: 0px 10px; display: inline-block}
#navTabs > li > span {display: inline-block;}
#navTabs > li > a {margin: 0!important; padding: 8px 0px; display: inline-block}
#tabContent {margin-top: 5px; z-index: 900; max-width: 220px}
.projectTree ul {list-style: none; margin: 0}
.projectTree .projects>ul {padding-left: 7px;}
.projectTree .projects>ul>li>div {display: flex; flex-flow: row nowrap; justify-content: flex-start; align-items: center;}
.projectTree .projects>ul>li label {background: rgba(255,255,255,0.5); line-height: unset; color: #838a9d; border: 1px solid #d8d8d8; border-radius: 2px; padding: 1px 4px;}
.projectTree .projects > ul {padding-left: 7px;}
.projectTree .projects > ul > li > div {display: flex; flex-flow: row nowrap; justify-content: flex-start; align-items: center;}
.projectTree .projects > ul > li label {background: rgba(255,255,255,0.5); line-height: unset; color: #838a9d; border: 1px solid #d8d8d8; border-radius: 2px; padding: 1px 4px;}
.projectTree li a i.icon {font-size: 15px !important;}
.projectTree li a i.icon:before {min-width: 16px !important;}
.projectTree li .label {position: unset; margin-bottom: 0;}
.projectTree li>a, div.hide-in-search>a {display: block; padding: 2px 10px 2px 5px; overflow: hidden; line-height: 20px; text-overflow: ellipsis; white-space: nowrap; border-radius: 4px;}
.projectTree .tree li>.list-toggle {line-height: 24px;}
.projectTree li > a, div.hide-in-search>a {display: block; padding: 2px 10px 2px 5px; overflow: hidden; line-height: 20px; text-overflow: ellipsis; white-space: nowrap; border-radius: 4px;}
.projectTree .tree li > .list-toggle {line-height: 24px;}
.projectTree .tree li.has-list.open:before {content: unset;}
.tree.noProgram li {padding-left: 0;}
#swapper li>div.hide-in-search>a:focus, #swapper li>div.hide-in-search>a:hover {color: #838a9d; cursor: default;}
#swapper li > div.hide-in-search>a:focus, #swapper li > div.hide-in-search>a:hover {color: #838a9d; cursor: default;}
#swapper li > a {margin-top: 4px; margin-bottom: 4px;}
#swapper li {padding-top: 0; padding-bottom: 0;}
#swapper .tree li>.list-toggle {top: -1px;}
#swapper .tree li > .list-toggle {top: -1px;}
#dropMenu div#closed {width: 90px; height: 25px; line-height: 25px; background-color: #ddd; color: #3c495c; text-align: center; margin-left: 15px; border-radius: 2px;}
#gray-line {width:230px; height: 1px; margin-left: 10px; margin-bottom:2px; background-color: #ddd;}
@@ -199,7 +200,7 @@ $(function()
$('.nav-tabs li span').hide();
$('.nav-tabs li.active').find('span').show();
$('.nav-tabs>li a').click(function()
$('.nav-tabs > li a').click(function()
{
if($('#swapper input[type="search"]').val() == '')
{
+11 -8
View File
@@ -1267,9 +1267,14 @@ class story extends control
if($this->app->tab == 'project')
{
$module = 'projectstory';
$method = 'view';
$params = "storyID=$storyID";
$module = 'projectstory';
$method = 'view';
$params = "storyID=$storyID";
if(!$this->session->multiple)
{
$module = 'story';
$params .= "&version=0&param={$this->session->project}&storyType=$storyType";
}
}
elseif($this->app->tab == 'execution')
{
@@ -1283,7 +1288,8 @@ class story extends control
$method = 'view';
$params = "storyID=$storyID&version=0&param=0&storyType=$storyType";
}
return print(js::locate($this->createLink($module, $method, $params), 'parent'));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink($module, $method, $params)));
}
$this->commonAction($storyID);
@@ -1631,7 +1637,7 @@ class story extends control
{
$module = 'story';
$method = 'view';
$params = "storyID=$storyID&version=0&param=0&storyType=$storyType";
$params = "storyID=$storyID&version=0&param={$this->session->execution}&storyType=$storyType";
}
}
else
@@ -1800,9 +1806,6 @@ class story extends control
$story = $this->story->getById($storyID);
$product = $this->product->getById($story->product);
/* Set menu. */
$this->product->setMenu($story->product, $story->branch);
/* Get reviewers. */
$reviewers = $product->reviewer;
if(!$reviewers and $product->acl != 'open') $reviewers = $this->loadModel('user')->getProductViewListUsers($product, '', '', '', '');
+10 -7
View File
@@ -1591,6 +1591,7 @@ class storyModel extends model
->setDefault('reviewedDate', $date)
->stripTags($this->config->story->editor->review['id'], $this->config->allowedTags)
->setIF(!$this->post->assignedTo, 'assignedTo', '')
->setIF(!empty($_POST['assignedTo']), 'assignedDate', $now)
->removeIF($this->post->result != 'reject', 'closedReason, duplicateStory, childStories')
->removeIF($this->post->result == 'reject' and $this->post->closedReason != 'duplicate', 'duplicateStory')
->removeIF($this->post->result == 'reject' and $this->post->closedReason != 'subdivided', 'childStories')
@@ -5167,12 +5168,13 @@ class storyModel extends model
{
$showBranch = isset($this->config->product->browse->showBranch) ? $this->config->product->browse->showBranch : 1;
}
if($storyType == 'requirement' and $story->type == 'story') echo '<span class="label label-badge label-light">SR</span> ';
if($story->parent > 0 and isset($story->parentName)) $story->title = "{$story->parentName} / {$story->title}";
if(isset($branches[$story->branch]) and $showBranch and $this->config->vision == 'rnd') echo "<span class='label label-outline label-badge' title={$branches[$story->branch]}>{$branches[$story->branch]}</span> ";
if($story->module and isset($modulePairs[$story->module])) echo "<span class='label label-gray label-badge'>{$modulePairs[$story->module]}</span> ";
if($story->parent > 0) echo '<span class="label label-badge label-light" title="' . $this->lang->story->children . '">' . $this->lang->story->childrenAB . '</span> ';
echo $canView ? html::a($storyLink, $story->title, '', "title='$story->title' style='color: $story->color' data-app='$tab'") : "<span style='color: $story->color'>{$story->title}</span>";
$titleHtml = $story->title;
if($storyType == 'requirement' and $story->type == 'story') $titleHtml = '<span class="label label-badge label-light">SR</span> ';
if($story->parent > 0 and isset($story->parentName)) $titleHtml = "{$story->parentName} / ";
if(isset($branches[$story->branch]) and $showBranch and $this->config->vision == 'rnd') $titleHtml = "<span class='label label-outline label-badge' title={$branches[$story->branch]}>{$branches[$story->branch]}</span> ";
if($story->module and isset($modulePairs[$story->module])) $titleHtml = "<span class='label label-gray label-badge'>{$modulePairs[$story->module]}</span> ";
if($story->parent > 0) $titleHtml = '<span class="label label-badge label-light" title="' . $this->lang->story->children . '">' . $this->lang->story->childrenAB . '</span> ';
echo $canView ? html::a($storyLink, $titleHtml . $story->title, '', "title='$story->title' style='color: $story->color' data-app='$tab'") : "<span style='color: $story->color'>{$titleHtml}{$story->title}</span>";
if(!empty($story->children)) echo '<a class="story-toggle" data-id="' . $story->id . '"><i class="icon icon-angle-right"></i></a>';
break;
case 'plan':
@@ -5276,9 +5278,10 @@ class storyModel extends model
echo $story->version;
break;
case 'actions':
if($tab == 'execution' || ($tab == 'project' && isset($_SESSION['multiple']) && empty($_SESSION['multiple'])))
if($tab == 'execution' or ($tab == 'project' and isset($_SESSION['multiple']) and empty($_SESSION['multiple'])))
{
$menuType = 'execution';
if($storyType == 'requirement') $menuType = 'browse';
}
else
{
+2
View File
@@ -125,6 +125,7 @@ class taskModel extends model
->setIF(is_numeric($this->post->left), 'left', (float)$this->post->left)
->setDefault('openedBy', $this->app->user->account)
->setDefault('openedDate', helper::now())
->setDefault('vision', $this->config->vision)
->cleanINT('execution,story,module')
->stripTags($this->config->task->editor->create['id'], $this->config->allowedTags)
->join('mailto', ',')
@@ -189,6 +190,7 @@ class taskModel extends model
if($bugID > 0)
{
$this->dao->update(TABLE_TASK)->set('fromBug')->eq($bugID)->where('id')->eq($taskID)->exec();
$this->dao->update(TABLE_BUG)->set('toTask')->eq($taskID)->where('id')->eq($bugID)->exec();
$this->loadModel('action')->create('bug', $bugID, 'converttotask', '', $taskID);
}
+2 -1
View File
@@ -355,7 +355,7 @@ class tree extends control
$parentModules = $this->tree->getParents($currentModuleID);
$newModule = (version_compare($execution->openedVersion, '4.1', '>') and $products) ? true : false;
$title = $this->lang->tree->manageExecution;
$title = $execution->multiple ? $this->lang->tree->manageExecution : $this->lang->tree->manageProject;
$position[] = html::a($this->createLink('execution', 'task', "executionID=$rootID"), $execution->name);
$position[] = $this->lang->tree->manageExecution;
@@ -363,6 +363,7 @@ class tree extends control
$this->view->position = $position;
$this->view->rootID = $rootID;
$this->view->productID = $productID;
$this->view->execution = $execution;
$this->view->allProject = $executions;
$this->view->newModule = $newModule;
$this->view->modules = $this->tree->getTaskTreeMenu($rootID, $productID, $rooteModuleID = 0, array('treeModel', 'createTaskManageLink'), 'allModule');
+4 -2
View File
@@ -18,7 +18,8 @@ $lang->tree->browseTask = 'Aufgaben Modul verwalten';
$lang->tree->manage = 'Modul verwalten';
$lang->tree->fix = 'Fix';
$lang->tree->manageProduct = "Verwalte {$lang->productCommon}";
$lang->tree->manageExecution = "Verwalte {$lang->executionCommon}";
$lang->tree->manageProject = "Verwalte {$lang->projectCommon}";
$lang->tree->manageExecution = "Verwalte {$lang->execution->common}";
$lang->tree->manageLine = "Manage Product Line";
$lang->tree->manageBug = 'Verwalte Bugs';
$lang->tree->manageCase = 'Verwalte Fälle';
@@ -34,7 +35,8 @@ $lang->tree->manageCaseChild = 'Verwalte Fälle';
$lang->tree->manageCaselibChild = 'Verwalte Bibliothek';
$lang->tree->manageDashboard = 'Manage Dashboard Module';
$lang->tree->manageDashboardChild = 'Manage Dashboard Child Module';
$lang->tree->manageTaskChild = "Verwalte {$lang->executionCommon}";
$lang->tree->manageProjectChild = "Verwalte {$lang->projectCommon}";
$lang->tree->manageTaskChild = "Verwalte {$lang->execution->common}";
$lang->tree->syncFromProduct = "Copy from Other {$lang->productCommon}s";
$lang->tree->dragAndSort = "Ziehen und Sotieren";
$lang->tree->sort = "Sortieren";
+2
View File
@@ -18,6 +18,7 @@ $lang->tree->browseTask = 'Manage Task Module';
$lang->tree->manage = 'Manage Module';
$lang->tree->fix = 'Fix Module';
$lang->tree->manageProduct = "Manage {$lang->productCommon} Modules";
$lang->tree->manageProject = "Manage {$lang->projectCommon} Modules";
$lang->tree->manageExecution = "Manage {$lang->execution->common} Modules";
$lang->tree->manageLine = "Manage Product Line";
$lang->tree->manageBug = 'Manage Bug';
@@ -34,6 +35,7 @@ $lang->tree->manageCaseChild = 'Manage Child Cases';
$lang->tree->manageCaselibChild = 'Manage Child Libraries';
$lang->tree->manageDashboard = 'Manage Dashboard Module';
$lang->tree->manageDashboardChild = 'Manage Dashboard Child Module';
$lang->tree->manageProjectChild = "Manage Child {$lang->projectCommon} Modules";
$lang->tree->manageTaskChild = "Manage Child {$lang->execution->common} Modules";
$lang->tree->syncFromProduct = "Copy from Other {$lang->productCommon}s";
$lang->tree->dragAndSort = "Drag to order";
+4 -2
View File
@@ -18,7 +18,8 @@ $lang->tree->browseTask = 'Gérer les Modules Tâche';
$lang->tree->manage = 'Gérer les Modules';
$lang->tree->fix = 'Corrigez Module';
$lang->tree->manageProduct = "Gérer les Modules {$lang->productCommon}";
$lang->tree->manageExecution = "Gérer les Modules {$lang->executionCommon}";
$lang->tree->manageProject = "Gérer les Modules {$lang->projectCommon}";
$lang->tree->manageExecution = "Gérer les Modules {$lang->execution->common}";
$lang->tree->manageLine = 'Gérer Ligne Produit';
$lang->tree->manageBug = 'Gérer Bugs';
$lang->tree->manageCase = 'Gérer CasTests';
@@ -34,7 +35,8 @@ $lang->tree->manageCaseChild = 'Gérer Sous-CasTests';
$lang->tree->manageCaselibChild = 'Gérer Sous-Librairies';
$lang->tree->manageDashboard = 'Manage Dashboard Module';
$lang->tree->manageDashboardChild = 'Manage Dashboard Child Module';
$lang->tree->manageTaskChild = "Gérer Sous-Modules {$lang->executionCommon}";
$lang->tree->manageProjectChild = "Gérer Sous-Modules {$lang->projectCommon}";
$lang->tree->manageTaskChild = "Gérer Sous-Modules {$lang->execution->common}";
$lang->tree->syncFromProduct = "Copier d'un autre {$lang->productCommon}";
$lang->tree->dragAndSort = "Faites glisser pour ordonner";
$lang->tree->sort = "Ordonnez";
+2
View File
@@ -18,6 +18,7 @@ $lang->tree->browseTask = '任务模块维护';
$lang->tree->manage = '维护模块';
$lang->tree->fix = '修正数据';
$lang->tree->manageProduct = "维护{$lang->productCommon}视图模块";
$lang->tree->manageProject = "维护{$lang->projectCommon}视图模块";
$lang->tree->manageExecution = "维护{$lang->execution->common}视图模块";
$lang->tree->manageLine = "维护产品线";
$lang->tree->manageBug = '维护测试视图模块';
@@ -34,6 +35,7 @@ $lang->tree->manageCaseChild = '维护用例子模块';
$lang->tree->manageCaselibChild = '维护用例库子模块';
$lang->tree->manageDashboard = '维护仪表盘模块';
$lang->tree->manageDashboardChild = '维护仪表盘子模块';
$lang->tree->manageProjectChild = "维护{$lang->projectCommon}子模块";
$lang->tree->manageTaskChild = "维护{$lang->execution->common}子模块";
$lang->tree->syncFromProduct = '复制模块';
$lang->tree->dragAndSort = "拖放排序";
+3 -2
View File
@@ -998,6 +998,7 @@ class treeModel extends model
if($linkObject)
{
$branch = zget($extra, 'branchID', 0);
/* Get object paths of this execution. */
if(strpos(',story,case,', ",$linkObject,") !== false)
{
@@ -1009,7 +1010,7 @@ class treeModel extends model
->orWhere('t4.project')->eq($executionID)->markRight(1)
->andWhere('t3.deleted')->eq(0)
->andWhere('t2.deleted')->eq(0)
->beginIF(isset($extra['branchID']))->andWhere('t2.branch')->eq(zget($extra, 'branchID', 0))->fi()
->beginIF(isset($extra['branchID']) and $branch !== 'all')->andWhere('t2.branch')->eq($branch)->fi()
->fetchPairs();
}
elseif($linkObject == 'bug' and strpos(',project,execution,', ",{$this->app->tab},") !== false)
@@ -1018,7 +1019,7 @@ class treeModel extends model
->leftJoin(TABLE_MODULE)->alias('t2')->on('t1.module = t2.id')
->where('t1.deleted')->eq(0)
->andWhere('t2.deleted')->eq(0)
->andWhere('t1.branch')->eq(zget($extra, 'branchID', 0))
->beginIF(isset($extra['branchID']) and $branch !== 'all')->andWhere('t1.branch')->eq($branch)->fi()
->andWhere("t1.{$this->app->tab}")->eq($executionID)
->fetchPairs();
}
+1 -1
View File
@@ -44,7 +44,7 @@ li.story-item > .tree-actions .tree-action[data-type=delete] {display: none;}
<form id='childrenForm' method='post' target='hiddenwin' action='<?php echo $this->createLink('tree', 'manageChild', "root={$root->id}&viewType=task");?>'>
<div class='panel'>
<div class='panel-heading'>
<div class='panel-title'><?php echo $lang->tree->manageTaskChild;?></div>
<div class='panel-title'><?php echo $execution->multiple ? $lang->tree->manageTaskChild : $lang->tree->manageProjectChild;?></div>
</div>
<div class='panel-body'>
<table class='table table-form table-auto'>
-12
View File
@@ -405,18 +405,6 @@ $config->delete['17_8'][] = 'extension/max/common/ext/lang/fr/crystal.php';
$config->delete['17_8'][] = 'extension/max/common/ext/lang/vi/crystal.php';
$config->delete['18_0'][] = 'extension/max/custom/ext/view/mode.zentaomax.html.hook.php';
$config->delete['18_0'][] = 'extension/max/my/ext/view/audit.html.php';
$config->delete['18_0'][] = 'extension/biz/common/ext/lang/de/report.php';
$config->delete['18_0'][] = 'extension/biz/common/ext/lang/en/report.php';
$config->delete['18_0'][] = 'extension/biz/common/ext/lang/fr/report.php';
$config->delete['18_0'][] = 'extension/biz/common/ext/lang/vi/report.php';
$config->delete['18_0'][] = 'extension/biz/common/ext/lang/zh-cn/report.php';
$config->delete['18_0'][] = 'extension/biz/common/ext/lang/zh-tw/report.php';
$config->delete['18_0'][] = 'extension/max/common/ext/lang/de/report.php';
$config->delete['18_0'][] = 'extension/max/common/ext/lang/en/report.php';
$config->delete['18_0'][] = 'extension/max/common/ext/lang/fr/report.php';
$config->delete['18_0'][] = 'extension/max/common/ext/lang/vi/report.php';
$config->delete['18_0'][] = 'extension/max/common/ext/lang/zh-cn/report.php';
$config->delete['18_0'][] = 'extension/max/common/ext/lang/zh-tw/report.php';
$config->delete['18_0'][] = 'extension/max/block/ext/config/zentaomax.php';
$config->delete['18_0'][] = 'extension/biz/repo/ext/control/ajaxgetcommitinfo.php';
$config->delete['18_0'][] = 'extension/biz/repo/ext/control/ajaxgetbranchesandtags.php';
+20 -10
View File
@@ -124,7 +124,8 @@ class user extends control
$user = $this->user->getById($userID, 'id');
$account = $user->account;
$users = $this->loadModel('dept')->getDeptUserPairs($this->app->user->dept, 'id');
$deptID = $this->app->user->admin ? 0 : $this->app->user->dept;
$users = $this->loadModel('dept')->getDeptUserPairs($deptID, 'id');
/* Modify story title. */
$this->loadModel('story');
@@ -167,7 +168,8 @@ class user extends control
$user = $this->user->getById($userID, 'id');
$account = $user->account;
$users = $this->loadModel('dept')->getDeptUserPairs($this->app->user->dept, 'id');
$deptID = $this->app->user->admin ? 0 : $this->app->user->dept;
$users = $this->loadModel('dept')->getDeptUserPairs($deptID, 'id');
/* Set the menu. */
$this->view->userList = $this->user->setUserList($users, $userID);
@@ -208,7 +210,8 @@ class user extends control
$user = $this->user->getById($userID, 'id');
$account = $user->account;
$users = $this->loadModel('dept')->getDeptUserPairs($this->app->user->dept, 'id');
$deptID = $this->app->user->admin ? 0 : $this->app->user->dept;
$users = $this->loadModel('dept')->getDeptUserPairs($deptID, 'id');
/* Set menu. */
$this->view->userList = $this->user->setUserList($users, $userID);
@@ -248,7 +251,8 @@ class user extends control
$user = $this->user->getById($userID, 'id');
$account = $user->account;
$users = $this->loadModel('dept')->getDeptUserPairs($this->app->user->dept, 'id');
$deptID = $this->app->user->admin ? 0 : $this->app->user->dept;
$users = $this->loadModel('dept')->getDeptUserPairs($deptID, 'id');
/* Set menu. */
$this->view->userList = $this->user->setUserList($users, $userID);
@@ -299,7 +303,8 @@ class user extends control
$user = $this->user->getById($userID, 'id');
$account = $user->account;
$users = $this->loadModel('dept')->getDeptUserPairs($this->app->user->dept, 'id');
$deptID = $this->app->user->admin ? 0 : $this->app->user->dept;
$users = $this->loadModel('dept')->getDeptUserPairs($deptID, 'id');
/* Append id for secend sort. */
$sort = common::appendOrder($orderBy);
@@ -355,7 +360,8 @@ class user extends control
$user = $this->user->getById($userID, 'id');
$account = $user->account;
$users = $this->loadModel('dept')->getDeptUserPairs($this->app->user->dept, 'id');
$deptID = $this->app->user->admin ? 0 : $this->app->user->dept;
$users = $this->loadModel('dept')->getDeptUserPairs($deptID, 'id');
/* Load pager. */
$this->app->loadClass('pager', $static = true);
@@ -395,7 +401,8 @@ class user extends control
$user = $this->user->getById($userID, 'id');
$account = $user->account;
$users = $this->loadModel('dept')->getDeptUserPairs($this->app->user->dept, 'id');
$deptID = $this->app->user->admin ? 0 : $this->app->user->dept;
$users = $this->loadModel('dept')->getDeptUserPairs($deptID, 'id');
/* Load pager. */
$this->app->loadClass('pager', $static = true);
@@ -435,7 +442,8 @@ class user extends control
$user = $this->user->getById($userID, 'id');
$account = $user->account;
$users = $this->loadModel('dept')->getDeptUserPairs($this->app->user->dept, 'id');
$deptID = $this->app->user->admin ? 0 : $this->app->user->dept;
$users = $this->loadModel('dept')->getDeptUserPairs($deptID, 'id');
/* Load pager. */
$this->app->loadClass('pager', $static = true);
@@ -468,7 +476,8 @@ class user extends control
$user = $this->user->getById($userID, 'id');
$account = $user->account;
$users = $this->loadModel('dept')->getDeptUserPairs($this->app->user->dept, 'id');
$deptID = $this->app->user->admin ? 0 : $this->app->user->dept;
$users = $this->loadModel('dept')->getDeptUserPairs($deptID, 'id');
$this->view->title = "USER #$user->id $user->account/" . $this->lang->user->profile;
$this->view->position[] = $this->lang->user->common;
@@ -1204,7 +1213,8 @@ class user extends control
{
$user = $this->user->getById($userID, 'id');
$account = $user->account;
$users = $this->loadModel('dept')->getDeptUserPairs($this->app->user->dept, 'id');
$deptID = $this->app->user->admin ? 0 : $this->app->user->dept;
$users = $this->loadModel('dept')->getDeptUserPairs($deptID, 'id');
/* set menus. */
$this->view->userList = $this->user->setUserList($users, $userID);
+2 -2
View File
@@ -193,7 +193,7 @@ class zahostModel extends model
*/
public function getImageList($hostID, $browseType = 'all', $param = 0, $orderBy = 'id', $pager = null)
{
$imageList = json_decode(file_get_contents($this->config->zahost->imageListUrl));
$imageList = json_decode(commonModel::http($this->config->zahost->imageListUrl, array(), array()));
$downloadedImageList = $this->dao->select('*')->from(TABLE_IMAGE)
->where('host')->eq($hostID)
@@ -256,7 +256,7 @@ class zahostModel extends model
*/
public function createImage($hostID, $imageName)
{
$imageList = json_decode(file_get_contents($this->config->zahost->imageListUrl));
$imageList = json_decode(commonModel::http($this->config->zahost->imageListUrl, array(), array()));
$imageData = new stdclass;
foreach($imageList as $item) if($item->name == $imageName) $imageData = $item;
+54 -29
View File
@@ -23,14 +23,15 @@
{
if(config.currentModule.indexOf('workflow') !== -1) return;
var skipModules = ['repo', 'mr', 'job'];
var skipModules = ['repo', 'mr', 'job', 'dev', 'custom', 'editor'];
if(skipModules.indexOf(config.currentModule) !== -1) return;
var skipMethods = ['edit', 'import', 'login', 'export', 'finish', 'confirm', 'resolve', 'start', 'pause', 'cancel', 'report', 'close', 'activate', 'restart', 'suspend', 'putoff', 'browse', 'hangup', 'track', 'index', 'reply', 'manage', 'run'];
var skipMethods = ['edit', 'import', 'login', 'export', 'finish', 'confirm', 'resolve', 'start', 'pause', 'cancel', 'report', 'close', 'activate', 'restart', 'suspend', 'putoff', 'browse', 'hangup', 'track', 'index', 'reply', 'manage', 'run', 'show'];
for(var i = 0; i < skipMethods.length; i++)
{
if(config.currentMethod.indexOf(skipMethods[i]) === 0) return;
};
var $messager = '';
setTimeout(function()
{
@@ -39,20 +40,33 @@
{
if($(form).hasClass('no-stash') || $(form).data('ride') == 'table') return;
var target = $(form).attr('target');
if($(form).attr('target') == 'hiddenwin' && config.currentModule.indexOf('program') == -1 && config.currentModule.indexOf('project') == -1 && config.currentModule.indexOf('testcase') == -1) return;
if($(form).attr('target') == 'hiddenwin')
{
var needSkip = true;
var keepModules = ['program', 'product', 'project', 'testcase', 'execution', 'caselib'];
for(var i = 0; i < keepModules.length; i++)
{
if(needSkip && config.currentModule.indexOf(keepModules[i]) === 0) needSkip = false;
};
if(needSkip) return;
}
var formID = config.currentMethod + '-' + config.currentModule + '-' + $(form).attr("id");
var formDataStored = $.zui.store.get(formID);
/* Clear form data for store. */
setTimeout(function() {
$.zui.store.remove(formID);
}, 100)
}, 100);
if(formDataStored && formDataStored.length)
{
var message = lang.confirmDraft.replace('%name%', lang[config.currentModule] ? lang[config.currentModule] : '');
new $.zui.Messager(message, {
type: 'success',
message = lang.confirmDraft.replace('%name%', lang[config.currentModule] ? lang[config.currentModule] : '');
$messager = new $.zui.Messager(message, {
close: true,
placement: 'center',
type: 'info',
placement: 'top',
cssClass: 'mt-md messagger-zt ',
time: 0,
actions: [
{
@@ -70,11 +84,11 @@
{
if((item.name.indexOf(']') != -1) && (item.name.indexOf('[') != -1))
{
var formItem = $('[name^=' + item.name.replace('[]', '').replace('[', '').replace(']', '') + ']');
var formItem = $('#' + item.name.replace('[]', '').replace('[', '').replace(']', ''));
}
else
{
var formItem = $('[name^=' + item.name.replace('[]', '') + ']');
var formItem = $('#' + item.name.replace('[]', ''));
}
}
else if((item.name.indexOf(']') != -1) && (item.name.indexOf('[') != -1))
@@ -83,40 +97,45 @@
}
else
{
var formItem = $('#' + item.name);
var formItem = $('[name^=' + item.name + ']');
if (!(formItem.length && (formItem.attr('type') === 'radio' || formItem.attr('type') === 'checkbox')))
formItem = $('#' + item.name);
}
var tagName = formItem.prop('tagName');
if(tagName === 'SELECT')
{
formItem.val(item.value);
if($(formItem).hasClass('chosen'))
if($(formItem).attr('multiple'))
{
if(!valueMultiple[item.name]) valueMultiple[item.name] = [];
valueMultiple[item.name].push(item.value);
if($(formItem).hasClass('picker-select'))
{
$(formItem).trigger('change');
$(formItem).data('zui.picker').setValue(valueMultiple[item.name]);
}
else if($(formItem).hasClass('chosen'))
{
formItem.val(valueMultiple[item.name]);
$(formItem).trigger('change');
$(formItem).trigger('chosen:updated');
}
}
else if($(formItem).hasClass('chosen'))
{
formItem.val(item.value);
$(formItem).trigger('chosen:updated');
}
else if($(formItem).hasClass('picker-select'))
{
if($(formItem).attr('multiple'))
{
var value = [];
if(!valueMultiple[item.name]) valueMultiple[item.name] = [];
valueMultiple[item.name].push(item.value);
$(formItem).data('zui.picker').setValue(valueMultiple[item.name]);
}
else
{
$(formItem).data('zui.picker').setValue(item.value);
}
$(formItem).data('zui.picker').setValue(item.value);
}
}
else if(tagName === 'TEXTAREA' && $(formItem).hasClass('kindeditor'))
{
KindEditor.remove('#' + item.name);
formItem.val(item.value);
$(formItem).kindeditor({
/* Conetnt change event. */
afterChange: storeFormData(formID, $(form).serializeArray())
});
$(formItem).kindeditor();
}
else
{
@@ -156,6 +175,12 @@
if(res.result === 'success' || res.status === 'success') $.zui.store.remove(formID);
})
}
$('body').one('click', function(e)
{
if($('.messager').length && !$.contains(e.target, $('.messager')))
$messager.destroy();
});
}, 500);
}
handleSaveFormDraft();
@@ -993,7 +1018,7 @@ function toggleFold(form, unfoldIdList, objectID, objectType)
$parentTd = $form.find('td.has-child');
if($parentTd.length == 0) return false;
var toggleClass = ['product', 'requirement'].includes(objectType) ? 'story-toggle' : 'task-toggle';
var toggleClass = ['product', 'requirement', 'story'].indexOf(objectType) !== -1 ? 'story-toggle' : 'task-toggle';
var nameClass = ['product', 'productplan'].indexOf(objectType) !== -1 ? 'c-title' : 'c-name';
$form.find('th.' + nameClass).addClass('clearfix').append("<span id='toggleFold' class='collapsed'><i class='icon icon-angle-double-right'></i></span>");
+2
View File
@@ -8,6 +8,8 @@
* @version $Id: style.css 1454 2009-10-23 01:45:26Z wwccss $
* @link http://www.zentao.net
*/
.mt-md {margin-top: 100px!important;}
/* Finish task #5068*/
.main-table .table{cursor:pointer;}
.table-striped > tbody > tr:nth-child(2n+1) > td, .table-striped > tbody > tr:nth-child(2n+1) > th{background:none;}