diff --git a/extension/lite/custom/ext/lang/de/lite.php b/extension/lite/custom/ext/lang/de/lite.php index f3ee432ea4..a11fc0cd5f 100644 --- a/extension/lite/custom/ext/lang/de/lite.php +++ b/extension/lite/custom/ext/lang/de/lite.php @@ -12,6 +12,7 @@ $lang->custom->object['task'] = 'Task'; $lang->custom->object['todo'] = 'Todo'; $lang->custom->object['user'] = 'User'; $lang->custom->object['block'] = 'Block'; +$lang->custom->object['project'] = $lang->projectCommon; $lang->custom->menuOrder = array(); $lang->custom->menuOrder[10] = 'execution'; @@ -22,11 +23,12 @@ $lang->custom->menuOrder[30] = 'user'; $lang->custom->menuOrder[35] = 'block'; $lang->custom->task = new stdClass(); -$lang->custom->task->fields['required'] = 'Required Field'; +$lang->custom->task->fields['required'] = $lang->custom->required; $lang->custom->task->fields['priList'] = 'Priority'; $lang->custom->task->fields['typeList'] = 'Type'; $lang->custom->story = new stdClass(); +$lang->custom->story->fields['required'] = $lang->custom->required; $lang->custom->story->fields['priList'] = 'Priority'; $lang->custom->story->fields['reasonList'] = 'Close Reason'; $lang->custom->story->fields['statusList'] = 'Status'; diff --git a/extension/lite/custom/ext/lang/en/lite.php b/extension/lite/custom/ext/lang/en/lite.php index f3ee432ea4..a11fc0cd5f 100644 --- a/extension/lite/custom/ext/lang/en/lite.php +++ b/extension/lite/custom/ext/lang/en/lite.php @@ -12,6 +12,7 @@ $lang->custom->object['task'] = 'Task'; $lang->custom->object['todo'] = 'Todo'; $lang->custom->object['user'] = 'User'; $lang->custom->object['block'] = 'Block'; +$lang->custom->object['project'] = $lang->projectCommon; $lang->custom->menuOrder = array(); $lang->custom->menuOrder[10] = 'execution'; @@ -22,11 +23,12 @@ $lang->custom->menuOrder[30] = 'user'; $lang->custom->menuOrder[35] = 'block'; $lang->custom->task = new stdClass(); -$lang->custom->task->fields['required'] = 'Required Field'; +$lang->custom->task->fields['required'] = $lang->custom->required; $lang->custom->task->fields['priList'] = 'Priority'; $lang->custom->task->fields['typeList'] = 'Type'; $lang->custom->story = new stdClass(); +$lang->custom->story->fields['required'] = $lang->custom->required; $lang->custom->story->fields['priList'] = 'Priority'; $lang->custom->story->fields['reasonList'] = 'Close Reason'; $lang->custom->story->fields['statusList'] = 'Status'; diff --git a/extension/lite/custom/ext/lang/fr/lite.php b/extension/lite/custom/ext/lang/fr/lite.php index f3ee432ea4..a11fc0cd5f 100644 --- a/extension/lite/custom/ext/lang/fr/lite.php +++ b/extension/lite/custom/ext/lang/fr/lite.php @@ -12,6 +12,7 @@ $lang->custom->object['task'] = 'Task'; $lang->custom->object['todo'] = 'Todo'; $lang->custom->object['user'] = 'User'; $lang->custom->object['block'] = 'Block'; +$lang->custom->object['project'] = $lang->projectCommon; $lang->custom->menuOrder = array(); $lang->custom->menuOrder[10] = 'execution'; @@ -22,11 +23,12 @@ $lang->custom->menuOrder[30] = 'user'; $lang->custom->menuOrder[35] = 'block'; $lang->custom->task = new stdClass(); -$lang->custom->task->fields['required'] = 'Required Field'; +$lang->custom->task->fields['required'] = $lang->custom->required; $lang->custom->task->fields['priList'] = 'Priority'; $lang->custom->task->fields['typeList'] = 'Type'; $lang->custom->story = new stdClass(); +$lang->custom->story->fields['required'] = $lang->custom->required; $lang->custom->story->fields['priList'] = 'Priority'; $lang->custom->story->fields['reasonList'] = 'Close Reason'; $lang->custom->story->fields['statusList'] = 'Status'; diff --git a/extension/lite/custom/ext/lang/zh-cn/lite.php b/extension/lite/custom/ext/lang/zh-cn/lite.php index fc184d77d3..fd96d6bb8e 100644 --- a/extension/lite/custom/ext/lang/zh-cn/lite.php +++ b/extension/lite/custom/ext/lang/zh-cn/lite.php @@ -12,6 +12,7 @@ $lang->custom->object['task'] = '任务'; $lang->custom->object['todo'] = '待办'; $lang->custom->object['user'] = '用户'; $lang->custom->object['block'] = '区块'; +$lang->custom->object['project'] = $lang->projectCommon; $lang->custom->menuOrder = array(); $lang->custom->menuOrder[10] = 'execution'; @@ -22,11 +23,12 @@ $lang->custom->menuOrder[30] = 'user'; $lang->custom->menuOrder[35] = 'block'; $lang->custom->task = new stdClass(); -$lang->custom->task->fields['required'] = '必填项'; +$lang->custom->task->fields['required'] = $lang->custom->required; $lang->custom->task->fields['priList'] = '优先级'; $lang->custom->task->fields['typeList'] = '类型'; $lang->custom->story = new stdClass(); +$lang->custom->story->fields['required'] = $lang->custom->required; $lang->custom->story->fields['priList'] = '优先级'; $lang->custom->story->fields['reasonList'] = '关闭原因'; $lang->custom->story->fields['statusList'] = '状态'; diff --git a/module/admin/config.php b/module/admin/config.php index 0c3cc75852..d4a45b7019 100755 --- a/module/admin/config.php +++ b/module/admin/config.php @@ -23,6 +23,13 @@ $config->admin->menuModuleGroup['model']['custom|required'] = array('project', $config->admin->menuModuleGroup['feature']['custom|set'] = array('todo', 'feedback', 'user', 'block', 'story', 'task', 'bug', 'testcase', 'testtask', 'feedback', 'user'); $config->admin->menuModuleGroup['feature']['custom|required'] = array('bug', 'doc', 'product', 'story', 'productplan', 'release', 'task', 'bug', 'testcase', 'testsuite', 'testtask', 'testreport', 'caselib', 'doc', 'feedback', 'user'); $config->admin->menuModuleGroup['template']['custom|set'] = array('baseline'); +if($config->vision == 'lite') +{ + $config->admin->menuModuleGroup['model']['custom|set'] = array('issue', 'risk', 'opportunity', 'nc'); + $config->admin->menuModuleGroup['model']['custom|required'] = array('build'); + $config->admin->menuModuleGroup['feature']['custom|set'] = array('project', 'todo', 'feedback', 'user', 'block', 'story', 'task', 'bug', 'testcase', 'testtask', 'feedback', 'user'); + $config->admin->menuModuleGroup['feature']['custom|required'] = array('project', 'task', 'story'); +} $config->admin->plugins[203] = new stdClass(); $config->admin->plugins[203]->name = '人力资源日历'; @@ -57,6 +64,8 @@ $config->admin->plugins[194]->viewLink = 'https://www.zentao.net/extension-viewE $config->admin->apiRoot = 'https://www.zentao.net/'; $config->admin->classURL = 'https://www.zentao.net/publicclass.html'; $config->admin->extensionURL = 'https://www.zentao.net/extension-browse.html'; +$config->admin->patchURL = 'https://www.zentao.net/extension-browse-byModule-1218.html'; +$config->admin->downloadURL = 'https://www.zentao.net/download.html'; $config->admin->liteMenuList = array('system', 'user', 'feature', 'message', 'extension', 'dev'); $config->admin->helpURL['system'] = 'https://www.zentao.net/book/zentaopms/538.html'; diff --git a/module/admin/css/index.css b/module/admin/css/index.css index 06ba1c9a99..815c5a3265 100755 --- a/module/admin/css/index.css +++ b/module/admin/css/index.css @@ -78,15 +78,15 @@ .main.without-internet > .bottom > .official.panel > .main-panel {flex-direction: row-reverse;} /* css in side */ -.time-block {background: #EDEEF2; padding:2px 4px; border-radius: 4px; color: #0B0F18; font-size: 15px;} +.time-block {background: #EDEEF2; padding:2px 4px; border-radius: 4px; color: #0B0F18; font-size: 15px; margin: 0 4px;} .dynamic-block {height: 74px; padding: 12px 16px; display: flex; justify-content: space-between; position: relative; line-height: 20px; border-top: 1px solid #E3E4E9;} .dynamic-content {height: 50px; line-height: 25px; overflow: hidden;} .dynamic-time {white-space: nowrap; position: absolute; right: 12px; bottom: 10px; padding-right: 12px; background: white;} -.time-count {letter-spacing: 2px;} +.time-count {letter-spacing: 1px;} -.patch-block {padding: 12px 16px; line-height: 20px; border-top: 1px solid #E3E4E9;} +.patch-block {padding: 10px 16px 12px; line-height: 20px; border-top: 1px solid #E3E4E9;} .patch-content {height: 40px; overflow: hidden;} -.upgrade-block {padding: 16px 16px; line-height: 20px; border-top: 1px solid #E3E4E9;} +.upgrade-block {padding: 6px 16px; line-height: 20px; border-top: 1px solid #E3E4E9;} .upgrade-content {height: 20px; padding-left: 20px; position: relative; margin: 5px 0;} .upgrade-content:before {content: ' '; width: 8px; height: 8px; background: #E3E4E9; border-radius: 50%; position: absolute; left: 0px; top: 5px;} diff --git a/module/admin/lang/menu.php b/module/admin/lang/menu.php index 17cbfcaca8..ad2f640473 100644 --- a/module/admin/lang/menu.php +++ b/module/admin/lang/menu.php @@ -93,13 +93,23 @@ $lang->admin->menuList->feature['subMenu']['user'] = array('link' => "{$l $lang->admin->menuList->feature['tabMenu']['my']['todo'] = array('link' => "{$lang->todo->common}|custom|set|module=todo&field=priList", 'exclude' => 'custom-set'); $lang->admin->menuList->feature['tabMenu']['my']['block'] = array('link' => "{$lang->block->common}|custom|set|module=block&field=closed", 'exclude' => 'custom-set'); -if($config->vision == 'lite') $lang->admin->menuList->feature['tabMenu']['my']['task'] = array('link' => "{$lang->task->common}|custom|required|module=task", 'links' => array('custom|set|module=task&field=priList')); +if($config->vision == 'lite') $lang->admin->menuList->feature['tabMenu']['my']['task'] = array('link' => "{$lang->task->common}|custom|required|module=task", 'links' => array('custom|set|module=task&field=priList'), 'exclude' => 'custom-required,custom-set'); $lang->admin->menuList->feature['tabMenu']['product']['product'] = array('link' => "{$lang->productCommon}|custom|required|module=product", 'links' => array("custom|browsestoryconcept|", 'custom|product|'), 'alias' => 'browsestoryconcept,product', 'exclude' => 'custom-required'); -$lang->admin->menuList->feature['tabMenu']['product']['story'] = array('link' => "{$lang->SRCommon}|custom|required|module=story", 'links' => array("custom|set|module=story&field=categoryList"), 'exclude' => 'custom-required'); +$lang->admin->menuList->feature['tabMenu']['product']['story'] = array('link' => "{$lang->SRCommon}|custom|required|module=story", 'links' => array("custom|set|module=story&field=categoryList"), 'exclude' => 'custom-required,custom-set'); $lang->admin->menuList->feature['tabMenu']['product']['productplan'] = array('link' => "{$lang->productplan->shortCommon}|custom|required|module=productplan", 'exclude' => 'custom-required'); $lang->admin->menuList->feature['tabMenu']['product']['release'] = array('link' => "{$lang->release->common}|custom|required|module=release", 'exclude' => 'custom-required'); +$lang->admin->menuList->feature['tabMenu']['execution']['execution'] = array('link' => "{$lang->execution->common}|custom|execution|"); +$lang->admin->menuList->feature['tabMenu']['execution']['task'] = array('link' => "{$lang->task->common}|custom|required|module=task", 'links' => array('custom|set|module=task&field=priList')); + +$lang->admin->menuList->feature['tabMenu']['qa']['bug'] = array('link' => "{$lang->bug->common}|custom|required|module=bug", 'links' => array("custom|set|module=bug&field=priList"), 'exclude' => 'custom-required,custom-set'); +$lang->admin->menuList->feature['tabMenu']['qa']['testcase'] = array('link' => "{$lang->testcase->common}|custom|required|module=testcase", 'links' => array("custom|set|module=testcase&field=priList"), 'exclude' => 'custom-required,custom-set'); +$lang->admin->menuList->feature['tabMenu']['qa']['testsuite'] = array('link' => "{$lang->testcase->testsuite}|custom|required|module=testsuite", 'exclude' => 'custom-required'); +$lang->admin->menuList->feature['tabMenu']['qa']['testtask'] = array('link' => "{$lang->testtask->common}|custom|required|module=testtask", 'links' => array('custom|set|module=testtask&field=statusList'), 'exclude' => 'custom-required,custom-set'); +$lang->admin->menuList->feature['tabMenu']['qa']['testreport'] = array('link' => "{$lang->testreport->common}|custom|required|module=testreport", 'exclude' => 'custom-required'); +$lang->admin->menuList->feature['tabMenu']['qa']['caselib'] = array('link' => "{$lang->testcase->caselib}|custom|required|module=caselib", 'exclude' => 'custom-required'); + $lang->admin->menuList->feature['menuOrder']['5'] = 'my'; $lang->admin->menuList->feature['menuOrder']['10'] = 'product'; $lang->admin->menuList->feature['menuOrder']['15'] = 'execution'; @@ -158,10 +168,15 @@ if($config->vision == 'lite') unset($lang->admin->menuList->feature['subMenu']['product']); unset($lang->admin->menuList->feature['subMenu']['execution']); unset($lang->admin->menuList->feature['subMenu']['qa']); + unset($lang->admin->menuList->feature['subMenu']['kanban']); unset($lang->admin->menuList->feature['menuOrder']['10']); unset($lang->admin->menuList->feature['menuOrder']['15']); unset($lang->admin->menuList->feature['menuOrder']['20']); + unset($lang->admin->menuList->feature['menuOrder']['25']); - $lang->admin->menuList->feature['subMenu']['project'] = array('link' => "{$lang->project->common}|custom|execution|"); + $lang->admin->menuList->feature['subMenu']['project'] = array('link' => "{$lang->projectCommon}|custom|execution|", 'exclude' => 'set,required', 'alias' => 'execution'); + $lang->admin->menuList->feature['tabMenu']['project']['project'] = array('link' => "{$lang->projectCommon}|custom|required|module=project", 'exclude' => 'custom-required'); + $lang->admin->menuList->feature['tabMenu']['project']['execution'] = array('link' => "{$lang->execution->common}|custom|execution|"); + $lang->admin->menuList->feature['tabMenu']['project']['story'] = array('link' => "{$lang->SRCommon}|custom|required|module=story", 'links' => array("custom|set|module=story&field=priList"), 'exclude' => 'custom-required,custom-set'); $lang->admin->menuList->feature['menuOrder']['15'] = 'project'; } diff --git a/module/admin/model.php b/module/admin/model.php index ebae255e82..d83080b9c0 100755 --- a/module/admin/model.php +++ b/module/admin/model.php @@ -279,21 +279,23 @@ class adminModel extends model $subModule = ''; if($moduleName == 'custom' and strpos(',required,set,', $methodName) !== false) { - if(strpos(',todo,block,', $paramName) !== false and $subMenuKey == 'my') $subModule = 'custom'; - if(strpos(',product,story,productplan,release,', $paramName) !== false and $subMenuKey == 'product') $subModule = 'custom'; + if(strpos(',todo,block,', ",$paramName,") !== false and $subMenuKey == 'my') $subModule = 'custom'; + if(strpos(',product,story,productplan,release,', ",$paramName,") !== false and $subMenuKey == 'product') $subModule = 'custom'; + if(strpos(',task,', ",$paramName,") !== false and $subMenuKey == 'execution') $subModule = 'custom'; + if(strpos(',project,story,', ",$paramName,") !== false and $subMenuKey == 'project') $subModule = 'custom'; + if(strpos(',bug,testcase,testsuite,testtask,testreport,caselib,', ",$paramName,") !== false and $subMenuKey == 'qa') $subModule = 'custom'; if($this->config->vision == 'lite' and $paramName == 'task' and $subMenuKey == 'my') $subModule = 'custom'; } if(!empty($subModule)) $subMenu['subModule'] = $subModule; if(isset($this->lang->admin->menuList->$menuKey['tabMenu'][$subMenuKey])) { - $this->lang->admin->menuList->$menuKey['tabMenu'][$subMenuKey][$paramName]['subModule'] = $subModule; + if(!empty($subModule)) $this->lang->admin->menuList->$menuKey['tabMenu'][$subMenuKey][$paramName]['subModule'] = $subModule; $subMenu['subMenu'] = $this->lang->admin->menuList->$menuKey['tabMenu'][$subMenuKey]; } $this->lang->admin->menu->$subMenuKey = $subMenu; } - } if(isset($this->lang->admin->menuList->$menuKey['menuOrder'])) $this->lang->admin->menuOrder = $this->lang->admin->menuList->$menuKey['menuOrder']; diff --git a/module/admin/view/index.html.php b/module/admin/view/index.html.php index 3b27c0251b..fae7e11f3e 100755 --- a/module/admin/view/index.html.php +++ b/module/admin/view/index.html.php @@ -103,7 +103,7 @@
admin->updateDynamics?>
- admin->extensionURL, "{$lang->more} ", '_blank', 'class="more text-muted flex align-center"');?> + admin->downloadURL, "{$lang->more} ", '_blank', 'class="more text-muted flex align-center"');?>
禅道18.0发布,新增自动化测试方案、使用帮助及全新IDE风格
@@ -121,7 +121,7 @@
admin->updatePatch?>
- admin->extensionURL, "{$lang->more} ", '_blank', 'class="more text-muted flex align-center"');?> + admin->patchURL, "{$lang->more} ", '_blank', 'class="more text-muted flex align-center"');?>
view->patches as $patch):?>
@@ -138,22 +138,22 @@
admin->upgradeRecommend?>
- admin->extensionURL, "{$lang->more} ", '_blank', 'class="more text-muted flex align-center"');?> + admin->downloadURL, "{$lang->more} ", '_blank', 'class="more text-muted flex align-center"');?>
- +
工时管理、甘特图、导入导出
40+内置统计报表、自定义报表功能
强大的自定义工作流、反馈管理功能
- +
工时管理、甘特图、导入导出
40+内置统计报表、自定义报表功能
强大的自定义工作流、反馈管理功能
diff --git a/module/common/view/header.html.php b/module/common/view/header.html.php index 7a728a8858..caa2c93e2c 100755 --- a/module/common/view/header.html.php +++ b/module/common/view/header.html.php @@ -30,7 +30,7 @@ include 'chosen.html.php';
{$app->tab}->menu->$activeMenu) and is_array($lang->{$app->tab}->menu->$activeMenu) and isset($lang->{$app->tab}->menu->{$activeMenu}['subMenu'])):?> tab == 'admin' ? 'admin-tab-menu' : '';?> -
+
diff --git a/module/custom/lang/de.php b/module/custom/lang/de.php index 8368ead6cc..d924816895 100644 --- a/module/custom/lang/de.php +++ b/module/custom/lang/de.php @@ -106,6 +106,9 @@ $lang->custom->object['score'] = 'Score'; $lang->custom->object['mode'] = 'Mode'; $lang->custom->object['productplan'] = 'Plan'; $lang->custom->object['release'] = 'Release'; +$lang->custom->object['testsuite'] = 'Test Suite'; +$lang->custom->object['testreport'] = 'Test Report'; +$lang->custom->object['caselib'] = 'Case Library'; $lang->custom->menuOrder[5] = 'project'; $lang->custom->menuOrder[10] = 'product'; @@ -131,6 +134,7 @@ $lang->custom->block->fields['closed'] = 'Closed Block'; $lang->custom->project = new stdClass(); $lang->custom->project->currencySetting = 'Currency Setting'; $lang->custom->project->defaultCurrency = 'Default Currency'; +$lang->custom->project->fields['required'] = $lang->custom->required; $lang->custom->project->fields['unitList'] = 'Unit List'; $lang->custom->product = new stdClass(); @@ -151,13 +155,14 @@ $lang->custom->story->fields['reviewResultList'] = 'Review Result'; $lang->custom->story->fields['review'] = 'Review Required'; $lang->custom->task = new stdClass(); +$lang->custom->task->fields['required'] = $lang->custom->required; $lang->custom->task->fields['priList'] = 'Priority'; $lang->custom->task->fields['typeList'] = 'Type'; $lang->custom->task->fields['reasonList'] = 'Close Reason'; $lang->custom->task->fields['statusList'] = 'Status'; -$lang->custom->task->fields['hours'] = 'Mannstunden'; $lang->custom->bug = new stdClass(); +$lang->custom->bug->fields['required'] = $lang->custom->required; $lang->custom->bug->fields['priList'] = 'Priority'; $lang->custom->bug->fields['severityList'] = 'Severity'; $lang->custom->bug->fields['osList'] = 'OS'; @@ -168,6 +173,7 @@ $lang->custom->bug->fields['statusList'] = 'Status'; $lang->custom->bug->fields['longlife'] = 'Stalled Days'; $lang->custom->testcase = new stdClass(); +$lang->custom->testcase->fields['required'] = $lang->custom->required; $lang->custom->testcase->fields['priList'] = 'Priority'; $lang->custom->testcase->fields['typeList'] = 'Type'; $lang->custom->testcase->fields['stageList'] = 'Phase'; @@ -176,10 +182,17 @@ $lang->custom->testcase->fields['statusList'] = 'Status'; $lang->custom->testcase->fields['review'] = 'Review Required'; $lang->custom->testtask = new stdClass(); +$lang->custom->testtask->fields['required'] = $lang->custom->required; $lang->custom->testtask->fields['statusList'] = 'Status'; $lang->custom->testtask->fields['typeList'] = 'Type'; $lang->custom->testtask->fields['priList'] = 'Priority'; +$lang->custom->testreport = new stdClass(); +$lang->custom->testreport->fields['required'] = $lang->custom->required; + +$lang->custom->caselib = new stdClass(); +$lang->custom->caselib->fields['required'] = $lang->custom->required; + $lang->custom->todo = new stdClass(); $lang->custom->todo->fields['priList'] = 'Priority'; $lang->custom->todo->fields['typeList'] = 'Type'; diff --git a/module/custom/lang/en.php b/module/custom/lang/en.php index 88e012b3c4..83af4e4c6a 100644 --- a/module/custom/lang/en.php +++ b/module/custom/lang/en.php @@ -106,6 +106,9 @@ $lang->custom->object['score'] = 'Score'; $lang->custom->object['mode'] = 'Mode'; $lang->custom->object['productplan'] = 'Plan'; $lang->custom->object['release'] = 'Release'; +$lang->custom->object['testsuite'] = 'Test Suite'; +$lang->custom->object['testreport'] = 'Test Report'; +$lang->custom->object['caselib'] = 'Case Library'; $lang->custom->menuOrder[5] = 'project'; $lang->custom->menuOrder[10] = 'product'; @@ -131,6 +134,7 @@ $lang->custom->block->fields['closed'] = 'Closed Block'; $lang->custom->project = new stdClass(); $lang->custom->project->currencySetting = 'Currency Setting'; $lang->custom->project->defaultCurrency = 'Default Currency'; +$lang->custom->project->fields['required'] = $lang->custom->required; $lang->custom->project->fields['unitList'] = 'Unit List'; $lang->custom->product = new stdClass(); @@ -151,13 +155,14 @@ $lang->custom->story->fields['reviewResultList'] = 'Review Result'; $lang->custom->story->fields['review'] = 'Need Review'; $lang->custom->task = new stdClass(); +$lang->custom->task->fields['required'] = $lang->custom->required; $lang->custom->task->fields['priList'] = 'Priority'; $lang->custom->task->fields['typeList'] = 'Type'; $lang->custom->task->fields['reasonList'] = 'Close Reason'; $lang->custom->task->fields['statusList'] = 'Status'; -$lang->custom->task->fields['hours'] = 'Effort'; $lang->custom->bug = new stdClass(); +$lang->custom->bug->fields['required'] = $lang->custom->required; $lang->custom->bug->fields['priList'] = 'Priority'; $lang->custom->bug->fields['severityList'] = 'Severity'; $lang->custom->bug->fields['osList'] = 'OS'; @@ -168,6 +173,7 @@ $lang->custom->bug->fields['statusList'] = 'Status'; $lang->custom->bug->fields['longlife'] = 'Stalled Days'; $lang->custom->testcase = new stdClass(); +$lang->custom->testcase->fields['required'] = $lang->custom->required; $lang->custom->testcase->fields['priList'] = 'Priority'; $lang->custom->testcase->fields['typeList'] = 'Type'; $lang->custom->testcase->fields['stageList'] = 'Phase'; @@ -176,10 +182,17 @@ $lang->custom->testcase->fields['statusList'] = 'Status'; $lang->custom->testcase->fields['review'] = 'Need Review'; $lang->custom->testtask = new stdClass(); +$lang->custom->testtask->fields['required'] = $lang->custom->required; $lang->custom->testtask->fields['statusList'] = 'Status'; $lang->custom->testtask->fields['typeList'] = 'Type'; $lang->custom->testtask->fields['priList'] = 'Priority'; +$lang->custom->testreport = new stdClass(); +$lang->custom->testreport->fields['required'] = $lang->custom->required; + +$lang->custom->caselib = new stdClass(); +$lang->custom->caselib->fields['required'] = $lang->custom->required; + $lang->custom->todo = new stdClass(); $lang->custom->todo->fields['priList'] = 'Priority'; $lang->custom->todo->fields['typeList'] = 'Type'; diff --git a/module/custom/lang/fr.php b/module/custom/lang/fr.php index 9f95330f98..1367a158e9 100644 --- a/module/custom/lang/fr.php +++ b/module/custom/lang/fr.php @@ -106,6 +106,9 @@ $lang->custom->object['score'] = 'Score'; $lang->custom->object['mode'] = 'Mode'; $lang->custom->object['productplan'] = 'Plan'; $lang->custom->object['release'] = 'Release'; +$lang->custom->object['testsuite'] = 'Test Suite'; +$lang->custom->object['testreport'] = 'Test Report'; +$lang->custom->object['caselib'] = 'Case Library'; $lang->custom->menuOrder[5] = 'project'; $lang->custom->menuOrder[10] = 'product'; @@ -131,6 +134,7 @@ $lang->custom->block->fields['closed'] = 'Bloc Fermé'; $lang->custom->project = new stdClass(); $lang->custom->project->currencySetting = 'Currency Setting'; $lang->custom->project->defaultCurrency = 'Default Currency'; +$lang->custom->project->fields['required'] = $lang->custom->required; $lang->custom->project->fields['unitList'] = 'Unit List'; $lang->custom->product = new stdClass(); @@ -151,13 +155,14 @@ $lang->custom->story->fields['reviewResultList'] = 'Valider Résultats'; $lang->custom->story->fields['review'] = 'Validation Requise'; $lang->custom->task = new stdClass(); +$lang->custom->task->fields['required'] = $lang->custom->required; $lang->custom->task->fields['priList'] = 'Priorité'; $lang->custom->task->fields['typeList'] = 'Type'; $lang->custom->task->fields['reasonList'] = 'Raison Fermeture'; $lang->custom->task->fields['statusList'] = 'Statut'; -$lang->custom->task->fields['hours'] = 'Effort'; $lang->custom->bug = new stdClass(); +$lang->custom->bug->fields['required'] = $lang->custom->required; $lang->custom->bug->fields['priList'] = 'Priorité'; $lang->custom->bug->fields['severityList'] = 'Sévérité'; $lang->custom->bug->fields['osList'] = 'OS'; @@ -168,6 +173,7 @@ $lang->custom->bug->fields['statusList'] = 'Statut'; $lang->custom->bug->fields['longlife'] = 'Jours Calage'; $lang->custom->testcase = new stdClass(); +$lang->custom->testcase->fields['required'] = $lang->custom->required; $lang->custom->testcase->fields['priList'] = 'Priorité'; $lang->custom->testcase->fields['typeList'] = 'Type'; $lang->custom->testcase->fields['stageList'] = 'Phase'; @@ -176,10 +182,17 @@ $lang->custom->testcase->fields['statusList'] = 'Statut'; $lang->custom->testcase->fields['review'] = 'Validation Requise'; $lang->custom->testtask = new stdClass(); +$lang->custom->testtask->fields['required'] = $lang->custom->required; $lang->custom->testtask->fields['statusList'] = 'Statut'; $lang->custom->testtask->fields['typeList'] = 'Type de test'; $lang->custom->testtask->fields['priList'] = 'Priorité'; +$lang->custom->testreport = new stdClass(); +$lang->custom->testreport->fields['required'] = $lang->custom->required; + +$lang->custom->caselib = new stdClass(); +$lang->custom->caselib->fields['required'] = $lang->custom->required; + $lang->custom->todo = new stdClass(); $lang->custom->todo->fields['priList'] = 'Priorité'; $lang->custom->todo->fields['typeList'] = 'Type'; diff --git a/module/custom/lang/zh-cn.php b/module/custom/lang/zh-cn.php index 53648d2072..d46fd342a9 100644 --- a/module/custom/lang/zh-cn.php +++ b/module/custom/lang/zh-cn.php @@ -106,6 +106,9 @@ $lang->custom->object['score'] = '积分'; $lang->custom->object['mode'] = '模式'; $lang->custom->object['productplan'] = '计划'; $lang->custom->object['release'] = '发布'; +$lang->custom->object['testsuite'] = '套件'; +$lang->custom->object['testreport'] = '测试报告'; +$lang->custom->object['caselib'] = '用例库'; $lang->custom->menuOrder[5] = 'project'; $lang->custom->menuOrder[10] = 'product'; @@ -131,6 +134,7 @@ $lang->custom->block->fields['closed'] = '关闭的区块'; $lang->custom->project = new stdClass(); $lang->custom->project->currencySetting = '货币设置'; $lang->custom->project->defaultCurrency = '默认货币'; +$lang->custom->project->fields['required'] = $lang->custom->required; $lang->custom->project->fields['unitList'] = '预算单位'; $lang->custom->product = new stdClass(); @@ -151,13 +155,14 @@ $lang->custom->story->fields['reviewResultList'] = '评审结果'; $lang->custom->story->fields['review'] = '评审流程'; $lang->custom->task = new stdClass(); +$lang->custom->task->fields['required'] = $lang->custom->required; $lang->custom->task->fields['priList'] = '优先级'; $lang->custom->task->fields['typeList'] = '类型'; $lang->custom->task->fields['reasonList'] = '关闭原因'; $lang->custom->task->fields['statusList'] = '状态'; -$lang->custom->task->fields['hours'] = '工时'; $lang->custom->bug = new stdClass(); +$lang->custom->bug->fields['required'] = $lang->custom->required; $lang->custom->bug->fields['priList'] = '优先级'; $lang->custom->bug->fields['severityList'] = '严重程度'; $lang->custom->bug->fields['osList'] = '操作系统'; @@ -168,6 +173,7 @@ $lang->custom->bug->fields['statusList'] = '状态'; $lang->custom->bug->fields['longlife'] = '久未处理天数'; $lang->custom->testcase = new stdClass(); +$lang->custom->testcase->fields['required'] = $lang->custom->required; $lang->custom->testcase->fields['priList'] = '优先级'; $lang->custom->testcase->fields['typeList'] = '类型'; $lang->custom->testcase->fields['stageList'] = '阶段'; @@ -176,10 +182,17 @@ $lang->custom->testcase->fields['statusList'] = '状态'; $lang->custom->testcase->fields['review'] = '评审流程'; $lang->custom->testtask = new stdClass(); +$lang->custom->testtask->fields['required'] = $lang->custom->required; $lang->custom->testtask->fields['statusList'] = '状态'; $lang->custom->testtask->fields['typeList'] = '测试类型'; $lang->custom->testtask->fields['priList'] = '优先级'; +$lang->custom->testreport = new stdClass(); +$lang->custom->testreport->fields['required'] = $lang->custom->required; + +$lang->custom->caselib = new stdClass(); +$lang->custom->caselib->fields['required'] = $lang->custom->required; + $lang->custom->todo = new stdClass(); $lang->custom->todo->fields['priList'] = '优先级'; $lang->custom->todo->fields['typeList'] = '类型'; diff --git a/module/custom/view/required.html.php b/module/custom/view/required.html.php index 37458bdcbc..12994ae411 100644 --- a/module/custom/view/required.html.php +++ b/module/custom/view/required.html.php @@ -12,7 +12,7 @@ ?> getModuleRoot() . 'common/view/header.html.php';?>
- + vision == 'rnd'))) include 'sidebar.html.php';?>
diff --git a/module/group/lang/resource.php b/module/group/lang/resource.php index 3636592d83..40d2c07675 100644 --- a/module/group/lang/resource.php +++ b/module/group/lang/resource.php @@ -75,6 +75,7 @@ $lang->moduleOrder[225] = 'mr'; $lang->moduleOrder[230] = 'app'; $lang->moduleOrder[235] = 'gogs'; $lang->moduleOrder[240] = 'gitea'; +$lang->moduleOrder[245] = 'holiday'; $lang->resource = new stdclass(); @@ -1931,11 +1932,13 @@ $lang->resource->holiday->create = 'createAction'; $lang->resource->holiday->edit = 'editAction'; $lang->resource->holiday->delete = 'deleteAction'; $lang->resource->holiday->browse = 'browse'; +$lang->resource->holiday->import = 'importAction'; $lang->holiday->methodOrder[0] = 'browse'; $lang->holiday->methodOrder[5] = 'create'; $lang->holiday->methodOrder[10] = 'edit'; $lang->holiday->methodOrder[15] = 'delete'; +$lang->holiday->methodOrder[20] = 'import'; /* Action. */ $lang->resource->action = new stdclass(); diff --git a/module/holiday/config.php b/module/holiday/config.php index f46a285b1e..6c171384f7 100644 --- a/module/holiday/config.php +++ b/module/holiday/config.php @@ -3,3 +3,5 @@ if(!isset($config->holiday)) $config->holiday = new stdclass(); $config->holiday->require = new stdclass(); $config->holiday->require->create = 'name,begin,end'; $config->holiday->require->edit = 'name,begin,end'; + +$config->holiday->apiRoot = 'https://ghproxy.com/https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/%d.json'; diff --git a/module/holiday/control.php b/module/holiday/control.php index 26658d3d81..5b425835cb 100644 --- a/module/holiday/control.php +++ b/module/holiday/control.php @@ -31,9 +31,18 @@ class holiday extends control */ public function browse($year = '') { + if(empty($year)) $year = date('Y'); + $holidays = $this->holiday->getList($year); $yearList = $this->holiday->getYearPairs(); + $yearAndNext = array(date('Y'), date('Y') + 1); + foreach($yearAndNext as $date) + { + if(!in_array($date, $yearList)) $yearList[$date] = $date; + } + krsort($yearList); + $this->view->title = $this->lang->holiday->browse; $this->view->holidays = $holidays; $this->view->yearList = $yearList; @@ -114,4 +123,28 @@ class holiday extends control return print(js::reload('parent')); } } + + /** + * Import holiday. + * + * @param string $year + * @access public + * @return void + */ + public function import($year = '') + { + if(empty($year)) $year = date('Y'); + + $holidays = $this->holiday->getHolidayByAPI($year); + if(helper::isAjaxRequest()) + { + $this->holiday->batchCreate($holidays); + + if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError())); + return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent')); + } + + $this->view->holidays = $holidays; + $this->display(); + } } diff --git a/module/holiday/css/browse.css b/module/holiday/css/browse.css index 9fb6ee448c..9c76821f51 100644 --- a/module/holiday/css/browse.css +++ b/module/holiday/css/browse.css @@ -3,3 +3,6 @@ .with-side .main {padding-left: 145px; float: left;} .side-col {width: 160px;} .panel-sm .panel-body {padding: 10px;} +#mainMenu .input-control {display: flex; width: 200px;} +#mainMenu .input-control .form-name {margin: 8px 10px; white-space: pre;} +.table-import {padding-top: 6px;} diff --git a/module/holiday/js/browse.js b/module/holiday/js/browse.js new file mode 100644 index 0000000000..0cfe06705a --- /dev/null +++ b/module/holiday/js/browse.js @@ -0,0 +1,7 @@ +$(function() +{ + $(document).on('change', '#year', function() + { + window.location.href = createLink('holiday', 'browse', 'year=' + $(this).val()) + '?_single=1'; + }); +}); diff --git a/module/holiday/lang/de.php b/module/holiday/lang/de.php index c922267c1c..f6e9bb99fd 100644 --- a/module/holiday/lang/de.php +++ b/module/holiday/lang/de.php @@ -9,6 +9,7 @@ $lang->holiday->delete = 'Delete'; $lang->holiday->createAction = 'Create Holiday'; $lang->holiday->editAction = 'Edit Holiday'; $lang->holiday->deleteAction = 'Delete Holiday'; +$lang->holiday->importAction = 'Import Holiday'; $lang->holiday->id = 'ID'; $lang->holiday->name = 'Name'; @@ -18,10 +19,12 @@ $lang->holiday->begin = 'Begin'; $lang->holiday->end = 'End'; $lang->holiday->all = 'All'; -$lang->holiday->holiday = 'Holiday'; +$lang->holiday->holiday = 'Holiday'; +$lang->holiday->checkYear = 'Year selection'; $lang->holiday->typeList['holiday'] = 'Holiday'; $lang->holiday->typeList['working'] = 'Working Day'; $lang->holiday->emptyTip = 'No Holiday'; $lang->holiday->confirmDelete = 'Confirm removal of holidays?'; +$lang->holiday->importTip = ''; diff --git a/module/holiday/lang/en.php b/module/holiday/lang/en.php index c922267c1c..f6e9bb99fd 100644 --- a/module/holiday/lang/en.php +++ b/module/holiday/lang/en.php @@ -9,6 +9,7 @@ $lang->holiday->delete = 'Delete'; $lang->holiday->createAction = 'Create Holiday'; $lang->holiday->editAction = 'Edit Holiday'; $lang->holiday->deleteAction = 'Delete Holiday'; +$lang->holiday->importAction = 'Import Holiday'; $lang->holiday->id = 'ID'; $lang->holiday->name = 'Name'; @@ -18,10 +19,12 @@ $lang->holiday->begin = 'Begin'; $lang->holiday->end = 'End'; $lang->holiday->all = 'All'; -$lang->holiday->holiday = 'Holiday'; +$lang->holiday->holiday = 'Holiday'; +$lang->holiday->checkYear = 'Year selection'; $lang->holiday->typeList['holiday'] = 'Holiday'; $lang->holiday->typeList['working'] = 'Working Day'; $lang->holiday->emptyTip = 'No Holiday'; $lang->holiday->confirmDelete = 'Confirm removal of holidays?'; +$lang->holiday->importTip = ''; diff --git a/module/holiday/lang/fr.php b/module/holiday/lang/fr.php index c922267c1c..f6e9bb99fd 100644 --- a/module/holiday/lang/fr.php +++ b/module/holiday/lang/fr.php @@ -9,6 +9,7 @@ $lang->holiday->delete = 'Delete'; $lang->holiday->createAction = 'Create Holiday'; $lang->holiday->editAction = 'Edit Holiday'; $lang->holiday->deleteAction = 'Delete Holiday'; +$lang->holiday->importAction = 'Import Holiday'; $lang->holiday->id = 'ID'; $lang->holiday->name = 'Name'; @@ -18,10 +19,12 @@ $lang->holiday->begin = 'Begin'; $lang->holiday->end = 'End'; $lang->holiday->all = 'All'; -$lang->holiday->holiday = 'Holiday'; +$lang->holiday->holiday = 'Holiday'; +$lang->holiday->checkYear = 'Year selection'; $lang->holiday->typeList['holiday'] = 'Holiday'; $lang->holiday->typeList['working'] = 'Working Day'; $lang->holiday->emptyTip = 'No Holiday'; $lang->holiday->confirmDelete = 'Confirm removal of holidays?'; +$lang->holiday->importTip = ''; diff --git a/module/holiday/lang/zh-cn.php b/module/holiday/lang/zh-cn.php index 5f38ebbcda..7e9fd2499e 100644 --- a/module/holiday/lang/zh-cn.php +++ b/module/holiday/lang/zh-cn.php @@ -6,9 +6,10 @@ $lang->holiday->create = '新建'; $lang->holiday->edit = '编辑'; $lang->holiday->delete = '删除'; -$lang->holiday->createAction = '创建节假日'; -$lang->holiday->editAction = '编辑节假日'; -$lang->holiday->deleteAction = '删除节假日'; +$lang->holiday->createAction = '创建节假日'; +$lang->holiday->editAction = '编辑节假日'; +$lang->holiday->deleteAction = '删除节假日'; +$lang->holiday->importAction = '导入节假日'; $lang->holiday->id = '编号'; $lang->holiday->name = '名称'; @@ -18,10 +19,12 @@ $lang->holiday->begin = '开始日期'; $lang->holiday->end = '结束日期'; $lang->holiday->all = '所有'; -$lang->holiday->holiday = '假期'; +$lang->holiday->holiday = '假期'; +$lang->holiday->checkYear = '年份选择'; $lang->holiday->typeList['holiday'] = '假期'; $lang->holiday->typeList['working'] = '补班'; $lang->holiday->emptyTip = '暂时没有节假日。'; $lang->holiday->confirmDelete = '确认删除节假日?'; +$lang->holiday->importTip = '可以在此 %s国家法定节假日。'; diff --git a/module/holiday/model.php b/module/holiday/model.php index 2b4a05d0f3..3b6e66f1e1 100644 --- a/module/holiday/model.php +++ b/module/holiday/model.php @@ -408,4 +408,80 @@ class holidayModel extends model $this->dao->update(TABLE_TASK)->set('realDuration')->eq($realDuration)->where('id')->eq($task->id)->exec(); } } + + /** + * Get holidays by api. + * + * @param string $year + * @access public + * @return array + */ + public function getHolidayByAPI($year = '') + { + if(empty($year)) $year = date('Y'); + $apiRoot = sprintf($this->config->holiday->apiRoot, $year); + $data = json_decode(common::http($apiRoot)); + $days = isset($data->days) ? (array)$data->days : array(); + + $holidays = array(); + $privDay = 0; + $prevDayOff = true; + $daysIndex = count($days) - 1; + foreach($days as $index => $day) + { + if($index < $daysIndex and (strtotime($day->date) - $privDay > 86400 or $day->isOffDay != $prevDayOff)) + { + $holiday = new stdClass(); + $holiday->type = $day->isOffDay ? 'holiday' : 'working'; + $holiday->name = $day->name . zget($this->lang->holiday->typeList, $holiday->type); + $holiday->begin = $day->date; + $holiday->end = ''; + $holidays[] = $holiday; + } + + if(isset($holiday) or $index == $daysIndex) + { + $holidayNum = count($holidays); + if($holidayNum > 1) + { + if(isset($holiday)) + { + $holidays[$holidayNum - 2]->end = date('Y-m-d', $privDay); + } + else + { + $holidays[$holidayNum - 1]->end = $day->date; + } + } + if(isset($holiday)) unset($holiday); + } + + $privDay = strtotime($day->date); + $prevDayOff = $day->isOffDay; + } + return $holidays; + } + + /** + * Batch create holiday. + * + * @param array $holidays + * @access public + * @return int|bool + */ + public function batchCreate($holidays) + { + foreach($holidays as $holiday) + { + $this->dao->insert(TABLE_HOLIDAY)->data($holiday) + ->autoCheck() + ->batchCheck($this->config->holiday->require->create, 'notempty') + ->check('end', 'ge', $holiday->begin) + ->exec(); + } + if(dao::isError()) return false; + + $lastInsertID = $this->dao->lastInsertID(); + return $lastInsertID; + } } diff --git a/module/holiday/view/browse.html.php b/module/holiday/view/browse.html.php index 637a4ac554..073878af8e 100644 --- a/module/holiday/view/browse.html.php +++ b/module/holiday/view/browse.html.php @@ -13,38 +13,26 @@
-
-
-
-
    - -
  • '> - -
  • - -
-
-
-
- + - - - - - + + + + + @@ -60,13 +48,20 @@
holiday->name;?>holiday->holiday;?>holiday->type;?>holiday->desc;?>actions;?>holiday->name;?>holiday->holiday;?>holiday->type;?>holiday->desc;?>actions;?>
- +

holiday->emptyTip;?>

- + + = date('Y')):?> + +
diff --git a/module/holiday/view/create.html.php b/module/holiday/view/create.html.php index a286293d64..9ad43d0195 100644 --- a/module/holiday/view/create.html.php +++ b/module/holiday/view/create.html.php @@ -45,8 +45,8 @@ holiday->desc?> - - + +
diff --git a/module/holiday/view/edit.html.php b/module/holiday/view/edit.html.php index 4dd0c050b2..511598302b 100644 --- a/module/holiday/view/edit.html.php +++ b/module/holiday/view/edit.html.php @@ -45,8 +45,8 @@ holiday->desc?> desc, "class='form-control'")?> - - + +
diff --git a/module/holiday/view/import.html.php b/module/holiday/view/import.html.php new file mode 100644 index 0000000000..4a1c38cca1 --- /dev/null +++ b/module/holiday/view/import.html.php @@ -0,0 +1,60 @@ + + * @package holiday + * @version $Id$ + * @link https://www.zentao.net + */ +?> + + +
+
+ +
+ + + + + + + + + + + + + + + +
holiday->name;?>holiday->holiday;?>
name;?>begin, DT_DATE1) . ' ~ ' . formatTime($holiday->end, DT_DATE1);?>
+ +
+ +
+

+ holiday->emptyTip;?> +

+
+ +
+
+ diff --git a/www/theme/default/style.css b/www/theme/default/style.css index 3e9d518d0f..b2b9ca32cd 100644 --- a/www/theme/default/style.css +++ b/www/theme/default/style.css @@ -68,7 +68,7 @@ th.c-confirmed, th.c-confirm {text-align: center;} .c-object-type {width: 130px;} .c-full-date, .c-mobile, .c-email, .c-text, .c-subject, .c-assigned-box, .c-user-box {width: 150px;} .c-module, .c-date-box {width: 180px;} -.c-ip {width: 200px;} +.c-ip, .c-time-limit {width: 200px;} .c-object {width: 250px;} .c-case-step {width: 300px;} .c-actions-8 {width: 240px;}