diff --git a/config/zentaopms.php b/config/zentaopms.php index 68b934c253..170afc14b9 100644 --- a/config/zentaopms.php +++ b/config/zentaopms.php @@ -227,7 +227,8 @@ $config->openMethods[] = 'doc.createbasicinfo'; $config->openMethods[] = 'project.createguide'; $config->openMethods[] = 'task.editteam'; $config->openMethods[] = 'feedback.mergeproductmodule'; -$config->openMethods[] = 'zanode.nodelist'; +$config->openMethods[] = 'zanode.nodeList'; +$config->openMethods[] = 'action.restoreStages'; $config->openModules = array(); $config->openModules[] = 'install'; @@ -428,6 +429,7 @@ $config->maxPriValue = '256'; $config->importWhiteList = array('user', 'task', 'story', 'bug', 'testcase', 'feedback', 'ticket'); $config->featureGroup = new stdclass(); +$config->featureGroup->my = array('score'); $config->featureGroup->product = array('roadmap', 'track', 'UR'); $config->featureGroup->scrum = array(); $config->featureGroup->waterfall = array(); diff --git a/db/zentaopms284.sql b/db/zentaopms284.sql new file mode 100644 index 0000000000..91fe06b398 --- /dev/null +++ b/db/zentaopms284.sql @@ -0,0 +1,6 @@ +update `zt_task` set `assignedTo` = '' where `mode` = 'multi' and `status` != 'done' and `status` != 'closed'; + +REPLACE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `system`, `vision`) SELECT `lang`, `module`, 'scrumClassify', `key`, `value`, `system`, `vision` FROM `zt_lang` WHERE `module` = 'process' and `section` = 'classify' ORDER BY id ASC; +REPLACE INTO `zt_lang` (`lang`, `module`, `section`, `key`, `value`, `system`, `vision`) SELECT `lang`, `module`, 'agileplusClassify', `key`, `value`, `system`, `vision` FROM `zt_lang` WHERE `module` = 'process' and `section` = 'classify' ORDER BY id ASC; + +UPDATE `zt_project` AS parent INNER JOIN (select `id`,`parent`,`attribute` from `zt_project` where `parent` != 0 and `type` = 'stage') AS child ON parent.`id` = child.`parent` SET parent.`attribute`='mix' where parent.`grade`=1 and parent.`type`='stage' and parent.`attribute` != child.`attribute`; diff --git a/extension/lite/common/ext/lang/de/lite.php b/extension/lite/common/ext/lang/de/lite.php index 911da4653c..ad31ea21d7 100644 --- a/extension/lite/common/ext/lang/de/lite.php +++ b/extension/lite/common/ext/lang/de/lite.php @@ -277,25 +277,6 @@ global $config; if(isset($config->xuanxuan) && strpos($config->visions, ',rnd,') === false) { $lang->xuanxuan = new stdclass(); - $lang->admin->menu->xuanxuan = array('link' => 'Chat|admin|xuanxuan', 'subModule' => 'client,setting'); - $lang->admin->menuOrder[6] = 'xuanxuan'; - - $lang->admin->menu->xuanxuan['subMenu'] = new stdclass(); - $lang->admin->menu->xuanxuan['subMenu']->index = array('link' => 'Home|admin|xuanxuan'); - $lang->admin->menu->xuanxuan['subMenu']->setting = array('link' => 'Parameter|setting|xuanxuan'); - $lang->admin->menu->xuanxuan['subMenu']->update = array('link' => 'Update|client|browse', 'subModule' => 'client'); - - $lang->admin->menu->xuanxuan['menuOrder'][0] = 'index'; - $lang->admin->menu->xuanxuan['menuOrder'][5] = 'setting'; - $lang->admin->menu->xuanxuan['menuOrder'][10] = 'update'; - - if($config->edition != 'open') - { - $lang->admin->menu->xuanxuan['subModule'] = 'client,setting,conference'; - $lang->admin->menu->xuanxuan['subMenu']->conference = array('link' => 'Conference|conference|admin'); - $lang->admin->menu->xuanxuan['menuOrder'][7] = 'conference'; - $lang->navGroup->conference = 'admin'; - } $lang->navGroup->im = 'admin'; $lang->navGroup->setting = 'admin'; diff --git a/extension/lite/common/ext/lang/en/lite.php b/extension/lite/common/ext/lang/en/lite.php index 911da4653c..ad31ea21d7 100644 --- a/extension/lite/common/ext/lang/en/lite.php +++ b/extension/lite/common/ext/lang/en/lite.php @@ -277,25 +277,6 @@ global $config; if(isset($config->xuanxuan) && strpos($config->visions, ',rnd,') === false) { $lang->xuanxuan = new stdclass(); - $lang->admin->menu->xuanxuan = array('link' => 'Chat|admin|xuanxuan', 'subModule' => 'client,setting'); - $lang->admin->menuOrder[6] = 'xuanxuan'; - - $lang->admin->menu->xuanxuan['subMenu'] = new stdclass(); - $lang->admin->menu->xuanxuan['subMenu']->index = array('link' => 'Home|admin|xuanxuan'); - $lang->admin->menu->xuanxuan['subMenu']->setting = array('link' => 'Parameter|setting|xuanxuan'); - $lang->admin->menu->xuanxuan['subMenu']->update = array('link' => 'Update|client|browse', 'subModule' => 'client'); - - $lang->admin->menu->xuanxuan['menuOrder'][0] = 'index'; - $lang->admin->menu->xuanxuan['menuOrder'][5] = 'setting'; - $lang->admin->menu->xuanxuan['menuOrder'][10] = 'update'; - - if($config->edition != 'open') - { - $lang->admin->menu->xuanxuan['subModule'] = 'client,setting,conference'; - $lang->admin->menu->xuanxuan['subMenu']->conference = array('link' => 'Conference|conference|admin'); - $lang->admin->menu->xuanxuan['menuOrder'][7] = 'conference'; - $lang->navGroup->conference = 'admin'; - } $lang->navGroup->im = 'admin'; $lang->navGroup->setting = 'admin'; diff --git a/extension/lite/common/ext/lang/fr/lite.php b/extension/lite/common/ext/lang/fr/lite.php index 911da4653c..ad31ea21d7 100644 --- a/extension/lite/common/ext/lang/fr/lite.php +++ b/extension/lite/common/ext/lang/fr/lite.php @@ -277,25 +277,6 @@ global $config; if(isset($config->xuanxuan) && strpos($config->visions, ',rnd,') === false) { $lang->xuanxuan = new stdclass(); - $lang->admin->menu->xuanxuan = array('link' => 'Chat|admin|xuanxuan', 'subModule' => 'client,setting'); - $lang->admin->menuOrder[6] = 'xuanxuan'; - - $lang->admin->menu->xuanxuan['subMenu'] = new stdclass(); - $lang->admin->menu->xuanxuan['subMenu']->index = array('link' => 'Home|admin|xuanxuan'); - $lang->admin->menu->xuanxuan['subMenu']->setting = array('link' => 'Parameter|setting|xuanxuan'); - $lang->admin->menu->xuanxuan['subMenu']->update = array('link' => 'Update|client|browse', 'subModule' => 'client'); - - $lang->admin->menu->xuanxuan['menuOrder'][0] = 'index'; - $lang->admin->menu->xuanxuan['menuOrder'][5] = 'setting'; - $lang->admin->menu->xuanxuan['menuOrder'][10] = 'update'; - - if($config->edition != 'open') - { - $lang->admin->menu->xuanxuan['subModule'] = 'client,setting,conference'; - $lang->admin->menu->xuanxuan['subMenu']->conference = array('link' => 'Conference|conference|admin'); - $lang->admin->menu->xuanxuan['menuOrder'][7] = 'conference'; - $lang->navGroup->conference = 'admin'; - } $lang->navGroup->im = 'admin'; $lang->navGroup->setting = 'admin'; diff --git a/extension/lite/common/ext/lang/zh-cn/lite.php b/extension/lite/common/ext/lang/zh-cn/lite.php index a8a683a383..bbb3a47c84 100644 --- a/extension/lite/common/ext/lang/zh-cn/lite.php +++ b/extension/lite/common/ext/lang/zh-cn/lite.php @@ -53,7 +53,6 @@ else $lang->task->common = '任务'; $lang->dashboard = isset($lang->dashboard->common) ? $lang->dashboard->common : $lang->dashboard; - /* Ticket. */ if($config->edition != 'open') $lang->feedback->menu->ticket = array('link' => '工单|ticket|browse|browseType=unclosed'); @@ -279,25 +278,6 @@ global $config; if(isset($config->xuanxuan) && strpos($config->visions, ',rnd,') === false) { $lang->xuanxuan = new stdclass(); - $lang->admin->menu->xuanxuan = array('link' => '聊天|admin|xuanxuan', 'subModule' => 'client,setting'); - $lang->admin->menuOrder[6] = 'xuanxuan'; - - $lang->admin->menu->xuanxuan['subMenu'] = new stdclass(); - $lang->admin->menu->xuanxuan['subMenu']->index = array('link' => '首页|admin|xuanxuan'); - $lang->admin->menu->xuanxuan['subMenu']->setting = array('link' => '参数|setting|xuanxuan'); - $lang->admin->menu->xuanxuan['subMenu']->update = array('link' => '更新|client|browse', 'subModule' => 'client'); - - $lang->admin->menu->xuanxuan['menuOrder'][0] = 'index'; - $lang->admin->menu->xuanxuan['menuOrder'][5] = 'setting'; - $lang->admin->menu->xuanxuan['menuOrder'][10] = 'update'; - - if($config->edition != 'open') - { - $lang->admin->menu->xuanxuan['subModule'] = 'client,setting,conference'; - $lang->admin->menu->xuanxuan['subMenu']->conference = array('link' => '音视频|conference|admin'); - $lang->admin->menu->xuanxuan['menuOrder'][7] = 'conference'; - $lang->navGroup->conference = 'admin'; - } $lang->navGroup->im = 'admin'; $lang->navGroup->setting = 'admin'; diff --git a/extension/lite/custom/ext/lang/de/lite.php b/extension/lite/custom/ext/lang/de/lite.php index 7b4a6e67f3..5d0451d9c9 100644 --- a/extension/lite/custom/ext/lang/de/lite.php +++ b/extension/lite/custom/ext/lang/de/lite.php @@ -5,27 +5,13 @@ $lang->custom->notice->readOnlyOfExecution = "If Change Forbidden, any change on $lang->custom->moduleName['execution'] = $lang->custom->execution; -$lang->custom->object = array(); -$lang->custom->object['execution'] = $lang->custom->execution; -$lang->custom->object['story'] = $lang->SRCommon; -$lang->custom->object['task'] = 'Task'; -$lang->custom->object['todo'] = 'Todo'; -$lang->custom->object['user'] = 'User'; -$lang->custom->object['block'] = 'Block'; - -$lang->custom->menuOrder = array(); -$lang->custom->menuOrder[10] = 'execution'; -$lang->custom->menuOrder[15] = 'story'; -$lang->custom->menuOrder[20] = 'task'; -$lang->custom->menuOrder[25] = 'todo'; -$lang->custom->menuOrder[30] = 'user'; -$lang->custom->menuOrder[35] = 'block'; - $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->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 7b4a6e67f3..5d0451d9c9 100644 --- a/extension/lite/custom/ext/lang/en/lite.php +++ b/extension/lite/custom/ext/lang/en/lite.php @@ -5,27 +5,13 @@ $lang->custom->notice->readOnlyOfExecution = "If Change Forbidden, any change on $lang->custom->moduleName['execution'] = $lang->custom->execution; -$lang->custom->object = array(); -$lang->custom->object['execution'] = $lang->custom->execution; -$lang->custom->object['story'] = $lang->SRCommon; -$lang->custom->object['task'] = 'Task'; -$lang->custom->object['todo'] = 'Todo'; -$lang->custom->object['user'] = 'User'; -$lang->custom->object['block'] = 'Block'; - -$lang->custom->menuOrder = array(); -$lang->custom->menuOrder[10] = 'execution'; -$lang->custom->menuOrder[15] = 'story'; -$lang->custom->menuOrder[20] = 'task'; -$lang->custom->menuOrder[25] = 'todo'; -$lang->custom->menuOrder[30] = 'user'; -$lang->custom->menuOrder[35] = 'block'; - $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->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 7b4a6e67f3..5d0451d9c9 100644 --- a/extension/lite/custom/ext/lang/fr/lite.php +++ b/extension/lite/custom/ext/lang/fr/lite.php @@ -5,27 +5,13 @@ $lang->custom->notice->readOnlyOfExecution = "If Change Forbidden, any change on $lang->custom->moduleName['execution'] = $lang->custom->execution; -$lang->custom->object = array(); -$lang->custom->object['execution'] = $lang->custom->execution; -$lang->custom->object['story'] = $lang->SRCommon; -$lang->custom->object['task'] = 'Task'; -$lang->custom->object['todo'] = 'Todo'; -$lang->custom->object['user'] = 'User'; -$lang->custom->object['block'] = 'Block'; - -$lang->custom->menuOrder = array(); -$lang->custom->menuOrder[10] = 'execution'; -$lang->custom->menuOrder[15] = 'story'; -$lang->custom->menuOrder[20] = 'task'; -$lang->custom->menuOrder[25] = 'todo'; -$lang->custom->menuOrder[30] = 'user'; -$lang->custom->menuOrder[35] = 'block'; - $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->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 4380e13b6e..5e687e8001 100644 --- a/extension/lite/custom/ext/lang/zh-cn/lite.php +++ b/extension/lite/custom/ext/lang/zh-cn/lite.php @@ -5,27 +5,13 @@ $lang->custom->notice->readOnlyOfExecution = "禁止修改后,已关闭{$lang- $lang->custom->moduleName['execution'] = $lang->custom->execution; -$lang->custom->object = array(); -$lang->custom->object['execution'] = $lang->custom->execution; -$lang->custom->object['story'] = $lang->SRCommon; -$lang->custom->object['task'] = '任务'; -$lang->custom->object['todo'] = '待办'; -$lang->custom->object['user'] = '用户'; -$lang->custom->object['block'] = '区块'; - -$lang->custom->menuOrder = array(); -$lang->custom->menuOrder[10] = 'execution'; -$lang->custom->menuOrder[15] = 'story'; -$lang->custom->menuOrder[20] = 'task'; -$lang->custom->menuOrder[25] = 'todo'; -$lang->custom->menuOrder[30] = 'user'; -$lang->custom->menuOrder[35] = 'block'; - $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->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/extension/lite/group/ext/lang/resource.php b/extension/lite/group/ext/lang/resource.php index dfd7f33092..3ba031f0f2 100644 --- a/extension/lite/group/ext/lang/resource.php +++ b/extension/lite/group/ext/lang/resource.php @@ -648,8 +648,9 @@ $lang->mail->methodOrder[65] = 'ztCloud'; $lang->resource->custom = new stdclass(); $lang->resource->custom->index = 'index'; $lang->resource->custom->set = 'set'; -$lang->resource->custom->product = 'product'; +$lang->resource->custom->product = 'productName'; $lang->resource->custom->execution = 'execution'; +$lang->resource->custom->required = 'required'; $lang->resource->custom->restore = 'restore'; $lang->resource->custom->flow = 'flow'; $lang->resource->custom->working = 'working'; @@ -666,17 +667,18 @@ $lang->custom->methodOrder[5] = 'index'; $lang->custom->methodOrder[10] = 'set'; $lang->custom->methodOrder[15] = 'product'; $lang->custom->methodOrder[20] = 'execution'; -$lang->custom->methodOrder[25] = 'restore'; -$lang->custom->methodOrder[30] = 'flow'; -$lang->custom->methodOrder[35] = 'working'; -$lang->custom->methodOrder[40] = 'setPublic'; -$lang->custom->methodOrder[45] = 'timezone'; -$lang->custom->methodOrder[50] = 'setStoryConcept'; -$lang->custom->methodOrder[55] = 'editStoryConcept'; -$lang->custom->methodOrder[60] = 'browseStoryConcept'; -$lang->custom->methodOrder[65] = 'setDefaultConcept'; -$lang->custom->methodOrder[70] = 'deleteStoryConcept'; -$lang->custom->methodOrder[75] = 'libreoffice'; +$lang->custom->methodOrder[25] = 'required'; +$lang->custom->methodOrder[30] = 'restore'; +$lang->custom->methodOrder[35] = 'flow'; +$lang->custom->methodOrder[40] = 'working'; +$lang->custom->methodOrder[45] = 'setPublic'; +$lang->custom->methodOrder[50] = 'timezone'; +$lang->custom->methodOrder[55] = 'setStoryConcept'; +$lang->custom->methodOrder[60] = 'editStoryConcept'; +$lang->custom->methodOrder[65] = 'browseStoryConcept'; +$lang->custom->methodOrder[70] = 'setDefaultConcept'; +$lang->custom->methodOrder[75] = 'deleteStoryConcept'; +$lang->custom->methodOrder[80] = 'libreoffice'; $lang->resource->datatable = new stdclass(); $lang->resource->datatable->setGlobal = 'setGlobal'; diff --git a/framework/helper.class.php b/framework/helper.class.php index 38b42bf5b6..a69af8d858 100644 --- a/framework/helper.class.php +++ b/framework/helper.class.php @@ -305,6 +305,49 @@ class helper extends baseHelper { throw EndResponseException::create($content); } + + /** + * Get date interval. + * + * @param string|int $begin + * @param string|int $end + * @param string $format %Y-%m-%d %H:%i:%s + * @static + * @access public + * @return object|string + */ + public static function getDateInterval($begin, $end = '', $format = '') + { + if(empty($end)) $end = time(); + if(is_int($begin)) $begin = date('Y-m-d H:i:s', $begin); + if(is_int($end)) $end = date('Y-m-d H:i:s', $end); + + $begin = date_create($begin); + $end = date_create($end); + $interval = date_diff($begin, $end); + + if($format) + { + $dateInterval = $interval->format($format); + } + else + { + $dateInterval = new stdClass(); + $dateInterval->year = $interval->format('%y'); + $dateInterval->month = $interval->format('%m'); + $dateInterval->day = $interval->format('%d'); + $dateInterval->hour = $interval->format('%H'); + $dateInterval->minute = $interval->format('%i'); + $dateInterval->secound = $interval->format('%s'); + $dateInterval->year = trim($dateInterval->year, '0'); + $dateInterval->month = trim($dateInterval->month, '0'); + $dateInterval->day = trim($dateInterval->day, '0'); + $dateInterval->hour = trim($dateInterval->hour, '0'); + $dateInterval->minute = trim($dateInterval->minute, '0'); + $dateInterval->secound = trim($dateInterval->secound, '0'); + } + return $dateInterval; + } } /** diff --git a/merge.sh b/merge.sh new file mode 100755 index 0000000000..adf6a97447 --- /dev/null +++ b/merge.sh @@ -0,0 +1,9 @@ +vim extension/lite/common/ext/lang/de/lite.php +vim extension/lite/common/ext/lang/en/lite.php +vim extension/lite/common/ext/lang/fr/lite.php +vim extension/lite/common/ext/lang/zh-cn/lite.php +vim module/common/lang/de.php +vim module/common/lang/en.php +vim module/common/lang/fr.php +vim module/common/lang/menu.php +vim module/common/lang/zh-cn.php diff --git a/module/action/control.php b/module/action/control.php index 721b01fd15..92284c76e4 100755 --- a/module/action/control.php +++ b/module/action/control.php @@ -246,6 +246,12 @@ class action extends control if($confirmChange == 'yes') $this->dao->update($table)->set('code')->eq($replaceCode)->where('id')->eq($oldAction->objectID)->exec(); } } + + if($oldAction->objectType == 'execution') + { + $confirmLang = $this->restoreStages($oldAction, $browseType, $confirmChange); + if($confirmLang !== true) return print(js::confirm($confirmLang, $this->createLink('action', 'undelete', "action={$actionID}&browseType={$browseType}&confirmChange=yes"))); + } } $this->action->undelete($actionID); @@ -351,4 +357,84 @@ class action extends control } return $this->send(array('result' => 'success', 'locate' => 'reload')); } + + /** + * Restore stages. + * + * @param object $action + * @param string $browseType + * @param string $confirmChange + * @access public + * @return bool|string + */ + public function restoreStages($action, $browseType, $confirmChange) + { + /* Check parent stage isCreateTask. */ + $execution = $this->dao->select('*')->from(TABLE_EXECUTION)->where('id')->eq($action->objectID)->fetch(); + $hasCreatedTask = $this->loadModel('programplan')->isCreateTask($execution->parent); + if(!$hasCreatedTask) die(js::alert($this->lang->action->hasCreatedTask)); + + /* Check type of siblings. */ + $siblings = $this->dao->select('DISTINCT type')->from(TABLE_EXECUTION)->where('deleted')->eq(0)->andWhere('parent')->eq($execution->parent)->fetchPairs('type'); + if($execution->type == 'stage' and (isset($bsiblings['sprint']) or isset($siblings['kanban']))) die(js::alert($this->lang->action->hasOtherType[$execution->type])); + if(($execution->type == 'sprint' or $execution->type == 'kanban') and isset($siblings['stage'])) die(js::alert($this->lang->action->hasOtherType[$execution->type])); + + /* If parent stage is not exists, you should recover its parent stages, refresh status. */ + $stagePathList = explode(',', trim($execution->path, ',')); + $deletedStageList = $this->dao->select('*')->from(TABLE_EXECUTION)->where('id')->in($stagePathList)->andWhere('deleted')->eq(1)->andWhere('type')->eq('stage')->orderBy('id_asc')->fetchAll('id'); + $deletedParents = $deletedStageList; + array_pop($deletedParents); + + $deletedTitle = ''; + foreach($deletedParents as $deletedParent) $deletedTitle .= "'{$deletedParent->name}',"; + + /* If parent stage's attribute has changed, sub-stage's attribute need change. */ + $deletedTopParent = current($deletedStageList); + $checkTopStage = $this->loadModel('programplan')->checkTopStage($deletedTopParent->id); + $parentAttr = $deletedTopParent->attribute; + if(!$checkTopStage) $parentAttr = $this->dao->select('attribute')->from(TABLE_EXECUTION)->where('id')->eq($deletedTopParent->parent)->fetch('attribute'); + + $needChangeAttr = false; + $startChangedStage = $execution; + foreach($deletedStageList as $deletedStage) + { + if($parentAttr != 'mix' and $parentAttr != $deletedStage->attribute) + { + $startChangedStage = $deletedStage; + $needChangeAttr = true; + break; + } + $parentAttr = $deletedStage->attribute; + } + + /* Confirm. */ + if(!empty($deletedTitle) or $needChangeAttr) + { + $this->app->loadLang('stage'); + + $deletedTitle = trim($deletedTitle, ','); + $confirmLang = sprintf($this->lang->action->hasDeletedParent, $deletedTitle) . $this->lang->action->whetherToRestore; + if($needChangeAttr) $confirmLang = sprintf($this->lang->action->hasChangedAttr, zget($this->lang->stage->typeList, $parentAttr)) . $this->lang->action->whetherToRestore; + if(!empty($deletedTitle) and $needChangeAttr) $confirmLang = sprintf($this->lang->action->hasDeletedParent, $deletedTitle) . sprintf($this->lang->action->hasChangedAttr, zget($this->lang->stage->typeList, $parentAttr)) . $this->lang->action->whetherToRestore; + + if($confirmChange == 'no') + { + return $confirmLang; + } + else + { + if(!empty($deletedTitle)) $this->action->restoreStages($deletedParents); + if($needChangeAttr) + { + $needChangedStages = substr($execution->path, strpos($execution->path, ",{$startChangedStage->id},")); + $needChangedStages = explode(',', trim($needChangedStages, ',')); + $this->dao->update(TABLE_EXECUTION)->set('attribute')->eq($parentAttr)->where('id')->in($needChangedStages)->exec(); + } + } + } + + $this->programplan->computeProgress($startChangedStage->parent); + + return true; + } } diff --git a/module/action/lang/de.php b/module/action/lang/de.php index a33c1a8d7e..a7a7f77f09 100644 --- a/module/action/lang/de.php +++ b/module/action/lang/de.php @@ -58,6 +58,15 @@ $lang->action->noDynamic = 'Kein Verlauf. '; $lang->action->undeletedTips = 'This data did not participate in the merging process during the version upgrade process, so restore is not supported.'; $lang->action->executionNoProject = 'The execution does not belong to a project,please restore the project first'; $lang->action->repoNoServer = 'The repo does not belong to a server,please restore the server first'; +$lang->action->hasCreatedTask = 'Tasks have been created in this parent phase and cannot be restored!'; +$lang->action->hasDeletedParent = 'Restoring this phase requires restoring the deleted parent phase %s at the same time.'; +$lang->action->hasChangedAttr = "After recovery, the phase type will be adjusted to '%s' according to the parent phase type."; +$lang->action->whetherToRestore = 'Confirm to restore?'; + +$lang->action->hasOtherType = array(); +$lang->action->hasOtherType['stage'] = "Only subtypes of {$lang->executionCommon} / Kanban types can be created at this parent stage, so the current stage cannot be restored."; +$lang->action->hasOtherType['sprint'] = "Only subtypes of Stage types can be created at this parent stage, so the current {$lang->executionCommon} cannot be restored."; +$lang->action->hasOtherType['kanban'] = "Only subtypes of Stage types can be created at this parent stage, so the current Kanban cannot be restored."; $lang->action->repeatChange = '%s with the same name and code already exists in the system, After recovery, the name are \"%s\",the code are \"%s\".'; $lang->action->nameRepeatChange = '%s with the same name already exists in the system, After recovery, the name are \"%s\".'; diff --git a/module/action/lang/en.php b/module/action/lang/en.php index 66f846e89c..ff66717f78 100755 --- a/module/action/lang/en.php +++ b/module/action/lang/en.php @@ -58,6 +58,15 @@ $lang->action->noDynamic = 'No dynamics. '; $lang->action->undeletedTips = 'This data did not participate in the merging process during the version upgrade process, so restore is not supported.'; $lang->action->executionNoProject = 'The execution does not belong to a project,please restore the project first'; $lang->action->repoNoServer = 'The repo does not belong to a server,please restore the server first'; +$lang->action->hasCreatedTask = 'Tasks have been created in this parent phase and cannot be restored!'; +$lang->action->hasDeletedParent = 'Restoring this phase requires restoring the deleted parent phase %s at the same time.'; +$lang->action->hasChangedAttr = "After recovery, the phase type will be adjusted to '%s' according to the parent phase type."; +$lang->action->whetherToRestore = 'Confirm to restore?'; + +$lang->action->hasOtherType = array(); +$lang->action->hasOtherType['stage'] = "Only subtypes of {$lang->executionCommon} / Kanban types can be created at this parent stage, so the current stage cannot be restored."; +$lang->action->hasOtherType['sprint'] = "Only subtypes of Stage types can be created at this parent stage, so the current {$lang->executionCommon} cannot be restored."; +$lang->action->hasOtherType['kanban'] = "Only subtypes of Stage types can be created at this parent stage, so the current Kanban cannot be restored."; $lang->action->repeatChange = '%s with the same name and code already exists in the system, After recovery, the name are \"%s\",the code are \"%s\".'; $lang->action->nameRepeatChange = '%s with the same name already exists in the system, After recovery, the name are \"%s\".'; diff --git a/module/action/lang/fr.php b/module/action/lang/fr.php index 8c4de4156c..4418cc164a 100644 --- a/module/action/lang/fr.php +++ b/module/action/lang/fr.php @@ -58,6 +58,15 @@ $lang->action->noDynamic = "Pas d'historique."; $lang->action->undeletedTips = 'This data did not participate in the merging process during the version upgrade process, so restore is not supported.'; $lang->action->executionNoProject = 'The execution does not belong to a project,please restore the project first'; $lang->action->repoNoServer = 'The repo does not belong to a server,please restore the server first'; +$lang->action->hasCreatedTask = 'Tasks have been created in this parent phase and cannot be restored!'; +$lang->action->hasDeletedParent = 'Restoring this phase requires restoring the deleted parent phase %s at the same time.'; +$lang->action->hasChangedAttr = "After recovery, the phase type will be adjusted to '%s' according to the parent phase type."; +$lang->action->whetherToRestore = 'Confirm to restore?'; + +$lang->action->hasOtherType = array(); +$lang->action->hasOtherType['stage'] = "Only subtypes of {$lang->executionCommon} / Kanban types can be created at this parent stage, so the current stage cannot be restored."; +$lang->action->hasOtherType['sprint'] = "Only subtypes of Stage types can be created at this parent stage, so the current {$lang->executionCommon} cannot be restored."; +$lang->action->hasOtherType['kanban'] = "Only subtypes of Stage types can be created at this parent stage, so the current Kanban cannot be restored."; $lang->action->repeatChange = '%s with the same name and code already exists in the system, After recovery, the name are \"%s\",the code are \"%s\".'; $lang->action->nameRepeatChange = '%s with the same name already exists in the system, After recovery, the name are \"%s\".'; diff --git a/module/action/lang/zh-cn.php b/module/action/lang/zh-cn.php index 5b242b1817..7a5cf3a901 100755 --- a/module/action/lang/zh-cn.php +++ b/module/action/lang/zh-cn.php @@ -58,6 +58,15 @@ $lang->action->noDynamic = '暂时没有动态。'; $lang->action->undeletedTips = '该数据在版本升级过程中未参与数据归并流程,不支持还原。'; $lang->action->executionNoProject = '该执行没有所属的项目,请先还原项目再还原执行'; $lang->action->repoNoServer = '该代码库没有所属的服务器,请先还原服务器再还原代码库'; +$lang->action->hasCreatedTask = '该父阶段已创建任务,无法恢复!'; +$lang->action->hasDeletedParent = '恢复该阶段需要同时恢复已删除的父阶段%s,'; +$lang->action->hasChangedAttr = '恢复后阶段类型将根据父阶段类型均调整为“%s”,'; +$lang->action->whetherToRestore = '是否恢复?'; + +$lang->action->hasOtherType = array(); +$lang->action->hasOtherType['stage'] = "当前阶段的父级现在只允许创建{$lang->executionCommon}/看板类型的子级,故无法恢复当前阶段。"; +$lang->action->hasOtherType['sprint'] = "当前{$lang->executionCommon}的父级现在只允许创建阶段类型的子级,故无法恢复当前{$lang->executionCommon}。"; +$lang->action->hasOtherType['kanban'] = "当前看板的父级现在只允许创建阶段类型的子级,故无法恢复当前看板。"; $lang->action->repeatChange = '系统内已有同名、同代号的%s,恢复后名称为\"%s\"、代号为\"%s\"。'; $lang->action->nameRepeatChange = '系统内已有同名的%s,恢复后名称为\"%s\"。'; diff --git a/module/action/model.php b/module/action/model.php index 540aa0c7aa..0dfdf4a832 100755 --- a/module/action/model.php +++ b/module/action/model.php @@ -1887,7 +1887,7 @@ class actionModel extends model if($action->objectType == 'execution') { - $execution = $this->dao->select('id, project, grade, parent, status, deleted')->from(TABLE_EXECUTION)->where('id')->eq($action->objectID)->fetch(); + $execution = $this->dao->select('id, type, project, grade, parent, status, deleted')->from(TABLE_EXECUTION)->where('id')->eq($action->objectID)->fetch(); $this->loadModel('common')->syncExecutionByChild($execution); } } @@ -2221,4 +2221,29 @@ class actionModel extends model $this->loadModel('search')->setSearchParams($this->config->trash->search); } + + /** + * Restore stages. + * + * @param array $stageList + * @access public + * @return void + */ + public function restoreStages($stageList) + { + $deletedActions = $this->dao->select('*')->from(TABLE_ACTION) + ->where('objectID')->in(array_keys($stageList)) + ->andWhere('objectType')->eq('execution') + ->andWhere('action')->eq('deleted') + ->orderBy('id_desc') + ->fetchGroup('objectID'); + + foreach($stageList as $stageID => $stage) + { + $deletedAction = $deletedActions[$stageID][0]; + $this->dao->update(TABLE_EXECUTION)->set('deleted')->eq('0')->where('id')->eq($stageID)->exec(); + $this->dao->update(TABLE_ACTION)->set('extra')->eq(ACTIONMODEL::BE_UNDELETED)->where('id')->eq($deletedAction->id)->exec(); + $this->create($deletedAction->objectType, $deletedAction->objectID, 'undeleted'); + } + } } diff --git a/module/admin/config.php b/module/admin/config.php old mode 100644 new mode 100755 index 8fa6c10599..a90737592c --- a/module/admin/config.php +++ b/module/admin/config.php @@ -6,3 +6,91 @@ $config->admin->log->saveDays = 30; if(!isset($config->safe)) $config->safe = new stdclass(); if(!isset($config->safe->weak)) $config->safe->weak = '123456,password,12345,12345678,qwerty,123456789,1234,1234567,abc123,111111,123123'; + +$config->admin->menuGroup['system'] = array('custom|mode', 'backup', 'cron', 'action|trash', 'admin|xuanxuan', 'setting|xuanxuan', 'admin|license', 'admin|checkweak', 'admin|resetpwdsetting', 'admin|safe', 'custom|timezone', 'search|buildindex', 'admin|tableengine', 'ldap', 'custom|libreoffice', 'conference', 'client'); +$config->admin->menuGroup['user'] = array('dept', 'company', 'user', 'group'); +$config->admin->menuGroup['switch'] = array('admin|setmodule'); +$config->admin->menuGroup['model'] = array('auditcl', 'stage', 'design', 'cmcl', 'reviewcl', 'custom|required', 'custom|set', 'custom|flow', 'custom|code', 'custom|estimate', 'custom|hours', 'subject', 'process', 'activity', 'zoutput', 'classify', 'holiday', 'reviewsetting'); +$config->admin->menuGroup['feature'] = array('custom|set', 'custom|product', 'custom|execution', 'custom|required', 'custom|kanban', 'approvalflow', 'measurement', 'meetingroom', 'custom|browsestoryconcept', 'custom|kanban', 'sqlbuilder', 'report'); +$config->admin->menuGroup['template'] = array('custom|set', 'baseline'); +$config->admin->menuGroup['message'] = array('mail', 'webhook', 'sms', 'message'); +$config->admin->menuGroup['dev'] = array('dev', 'entry'); +$config->admin->menuGroup['extension'] = array('extension'); +$config->admin->menuGroup['convert'] = array('convert'); + +$config->admin->menuModuleGroup['model']['custom|set'] = array('project', 'issue', 'risk', 'opportunity', 'nc'); +$config->admin->menuModuleGroup['model']['custom|required'] = array('project', 'build'); +$config->admin->menuModuleGroup['feature']['custom|set'] = array('todo', 'block', 'story', 'task', 'bug', 'testcase', 'testtask', 'feedback', 'user', 'ticket'); +$config->admin->menuModuleGroup['feature']['custom|required'] = array('bug', 'doc', 'product', 'story', 'productplan', 'release', 'task', '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(); + $config->admin->menuModuleGroup['model']['custom|required'] = array('build'); + $config->admin->menuModuleGroup['feature']['custom|set'] = array('todo', 'block', 'task', 'story', 'user'); + $config->admin->menuModuleGroup['feature']['custom|required'] = array('project', 'task', 'story', 'doc', 'user'); +} + +$config->admin->plugins[203] = new stdClass(); +$config->admin->plugins[203]->name = '人力资源日历'; +$config->admin->plugins[203]->abstract = '禅道人力资源日历插件可以帮助项目管理者查看不同维度下的消耗工时、未完成工作量、并行工作量及负载率,同时组织维度待处理状态下实现了模拟负载的功能,帮助管理者详细了解成员的工作负载情况,更好的进行项目人力资源调度。'; +$config->admin->plugins[203]->viewLink = 'https://www.zentao.net/extension-viewExt-203.html'; + +$config->admin->plugins[198] = new stdClass(); +$config->admin->plugins[198]->name = '需求池插件'; +$config->admin->plugins[198]->abstract = '本插件为禅道需求池管理插件,包括:创建需求池 需求池权限管理 收集需求并向需求池录入需求 记录需求提出人信息 评审需求 拆分用户需求、研发需求 需求跟踪矩阵'; +$config->admin->plugins[198]->viewLink = 'https://www.zentao.net/extension-viewExt-198.html'; + +$config->admin->plugins[27] = new stdClass(); +$config->admin->plugins[27]->name = 'Excel导出/导入'; +$config->admin->plugins[27]->abstract = '安装该插件可以支持Excel导出和任务、需求、Bug、用例导入功能。更新提示:新增任务、需求、Bug的excel导入功能。'; +$config->admin->plugins[27]->viewLink = 'https://www.zentao.net/extension-viewExt-27.html'; + +$config->admin->plugins[26] = new stdClass(); +$config->admin->plugins[26]->name = '甘特图'; +$config->admin->plugins[26]->abstract = '禅道甘特图插件 运用此插件可以查看甘特图,维护任务关系。'; +$config->admin->plugins[26]->viewLink = 'https://www.zentao.net/extension-viewExt-26.html'; + +$config->admin->plugins[30] = new stdClass(); +$config->admin->plugins[30]->name = '日志日历'; +$config->admin->plugins[30]->abstract = '运用此插件可以实现工作日志的添加、编辑、查看、删除、导出等功能,方便用户管理工作日志。'; +$config->admin->plugins[30]->viewLink = 'https://www.zentao.net/extension-viewExt-30.html'; + +$config->admin->plugins[194] = new stdClass(); +$config->admin->plugins[194]->name = '应用巡检报告'; +$config->admin->plugins[194]->abstract = '每日生成公司级禅道应用巡检报告,促进项目管理持续改进。'; +$config->admin->plugins[194]->viewLink = 'https://www.zentao.net/extension-viewExt-194.html'; + +$config->admin->apiRoot = 'https://www.zentao.net'; +$config->admin->cdnRoot = 'https://cdn.easycorp.cn/web'; +$config->admin->classURL = 'https://www.zentao.net/publicclass.html'; +$config->admin->dynamicURL = 'https://www.zentao.net/download.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->apiSite = 'https://api.zentao.net/'; +$config->admin->extAPIURL = $config->admin->apiSite . 'extension-apiGetExtensions-'; +$config->admin->patchAPIURL = $config->admin->apiSite . 'extension-apiGetExtensions-bymodule-MTIxOA==-0-100-1.json'; +$config->admin->downloadAPIURL = $config->admin->apiSite . 'download.json'; +$config->admin->videoAPIURL = $config->admin->apiSite . 'publicclass.json'; +$config->admin->liteMenuList = array('system', 'user', 'feature', 'message', 'extension', 'dev'); + +$config->admin->helpURL['system'] = 'https://www.zentao.net/book/zentaopms/538.html'; +$config->admin->helpURL['user'] = 'https://www.zentao.net/book/zentaopms/538.html'; +$config->admin->helpURL['switch'] = 'https://www.zentao.net/book/zentaopms/538.html'; +$config->admin->helpURL['model'] = 'https://www.zentao.net/book/zentaopms/533.html'; +$config->admin->helpURL['feature'] = 'https://www.zentao.net/book/zentaopms/538.html'; +$config->admin->helpURL['template'] = 'https://www.zentao.net/book/zentaopms/538.html'; +$config->admin->helpURL['message'] = 'https://www.zentao.net/book/zentaopms/email-notification-541.html'; +$config->admin->helpURL['extension'] = 'https://www.zentao.net/book/zentaopms/536.html'; +$config->admin->helpURL['dev'] = 'https://www.zentao.net/book/zentaopms/537.html'; +$config->admin->helpURL['convert'] = 'https://www.zentao.net/book/zentaopms/656.html'; + +$config->admin->navsGroup['feature']['my'] = ',todo,block,'; +$config->admin->navsGroup['feature']['product'] = ',product,story,productplan,release,'; +$config->admin->navsGroup['feature']['project'] = ',project,'; +$config->admin->navsGroup['feature']['execution'] = ',execution,task,'; +$config->admin->navsGroup['feature']['project'] = ',project,story,'; +$config->admin->navsGroup['feature']['qa'] = ',bug,testcase,testsuite,testtask,testreport,caselib,'; +$config->admin->navsGroup['model']['common'] = ',project,build,issue,risk,opportunity,nc,'; +$config->admin->navsGroup['template']['type'] = ',baseline,'; +if($config->vision == 'lite') $config->admin->navsGroup['feature']['my'] .= 'task,'; diff --git a/module/admin/control.php b/module/admin/control.php old mode 100644 new mode 100755 index 0d6bd79bb6..dba531df46 --- a/module/admin/control.php +++ b/module/admin/control.php @@ -34,8 +34,20 @@ class admin extends control $this->loadModel('misc'); - $this->view->title = $this->lang->admin->common; - $this->view->position[] = $this->lang->admin->index; + $hasInternet = $this->admin->checkInternet(); + $clientLang = $this->app->getClientLang(); + $langNotCN = common::checkNotCN(); + $dateUsed = $this->admin->genDateUsed(); + + $this->view->title = $this->lang->admin->common; + $this->view->position[] = $this->lang->admin->index; + $this->view->plugins = $this->admin->getExtensionsByAPI('plugin', $langNotCN ? 5 : 6, $hasInternet); + $this->view->patches = $this->admin->getExtensionsByAPI('patch', 5, $hasInternet); + $this->view->dateUsed = $dateUsed; + $this->view->hasInternet = $hasInternet; + $this->view->dynamics = ($hasInternet and !$langNotCN) ? $this->admin->getDynamicsByAPI(3) : array(); + $this->view->publicClass = ($hasInternet and !$langNotCN) ? $this->admin->getPublicClassByAPI(3) : array(); + $this->view->langNotCN = $langNotCN; $this->display(); } @@ -235,7 +247,7 @@ class admin extends control /** * Set closed features config. - * + * * @access public * @return void */ @@ -248,17 +260,21 @@ class admin extends control { foreach($this->post->module as $module => $options) { + if($module == 'myScore') continue; $checked = reset($options); if(!$checked) $closedFeatures .= "$module,"; } } $closedFeatures = rtrim($closedFeatures, ','); $this->loadModel('setting')->setItem('system.common.closedFeatures', $closedFeatures); + $this->loadModel('setting')->setItem('system.common.global.scoreStatus', $this->post->module['myScore'][0]); + $this->loadModel('setting')->setItem('system.custom.URAndSR', $this->post->module['productUR'][0]); $this->loadModel('custom')->processMeasrecordCron(); $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'top')); } $this->view->title = $this->lang->admin->setModuleIndex; $this->view->closedFeatures = $this->loadModel('setting')->getItem('owner=system&module=common§ion=&key=closedFeatures'); + $this->view->useScore = $this->setting->getItem('owner=system&module=common&global&key=scoreStatus'); $this->view->disabledFeatures = $this->setting->getItem('owner=system&module=common§ion=&key=disabledFeatures'); $this->display(); } diff --git a/module/admin/css/index.css b/module/admin/css/index.css old mode 100644 new mode 100755 index e954c9c911..fd06878df7 --- a/module/admin/css/index.css +++ b/module/admin/css/index.css @@ -1,3 +1,95 @@ +/* atomic class */ +.flex {display: flex;} +.align-center {align-items: center;} +.justify-between {justify-content: space-between;} +.title-color {color: #313C52} +.font-13 {font-size: 13px;} +.border-gray {border: 1px solid #E3E4E9;} +.h-56 {height: 56px;} +.h-40 {height: 40px;} +.pl-16 {padding-left: 16px;} +.px-16 {padding: 0 16px;} +.mb-16 {margin-bottom: 16px;} +.mr-16 {margin-right: 16px;} +.mx-16 {margin: 0 16px;} +.pd-3 {padding: 3px;} +.pb-3 {padding-bottom: 3px;} +.pr-4 {padding-right: 4px;} +.mt-6 {margin-top: 6px;} +.font-18 {font-size: 18px;} +.font-20 {font-size: 20px;} +.font-24 {font-size: 24px;} +.radius-4 {border-radius: 4px;} + #notice {margin: -20px -20px 20px; padding: 20px;} #zentaoLinks {margin-top: 20px;} #zentaoLinks .panel .panel-heading {padding: 6px 10px;} +.main-content.admin {padding: 0;} +.admin {display: flex; background: unset; box-shadow: none;} +.admin h4 {color: #0B0F18;} +.admin > .main {flex: 1 1 70%;} +.admin > .side {flex: 1 1 30%; margin-left: 16px; padding-right: 16px;} +.panel-title {padding: 10px 0px;} +.panel {padding-left: 16px;} +.settings.panel, .plug.panel {margin-bottom: 16px;} +.main > .panel {padding-right: 8px;} + +.settings-list {display: flex; flex-wrap: wrap; padding: 0 4px 16px 4px;} +.settings-list > .setting-box {border: unset; flex: 0 1 20%; padding: 8px;} +.settings-list > .setting-box > button.btn {padding: 5px 10px; height: 100%; width: 100%; display: flex; flex-direction: column; justify-content: space-between; cursor: pointer; white-space: unset; text-align: unset; border: 1px solid rgba(227, 228, 233, 0.6)} +.settings-list > .setting-box > .btn:hover {background: unset;} +.settings-list > .setting-box > .btn[disabled] {cursor: not-allowed; pointer-events: unset;} +.settings-list > .setting-box > .btn[disabled] > a {pointer-events: none;} +.settings-list > .setting-box > .btn > h4 > img {padding-right: 8px; padding-bottom: 3px; width: 32px; height: 27px;} +.settings-list > .setting-box > .btn > .setting-desc {padding-bottom: 16px; color: #5E626D; line-height: 25px; height: 50px;} +.settings-list.lite-setting > .setting-box {flex: 1 1 30%;} + +.plugin-list {display: flex; flex-wrap: wrap; padding: 12px 4px 4px 4px;} +.plugin-list > .plugin-item {flex: 1 1 26%; padding: 16px 10px; border: 1px solid #EDEEF2; border-radius: 4px; margin-right: 10px; margin-bottom: 16px; width: 0px; cursor: pointer;} +.plugin-list > .plugin-item .ext-download {float: right; padding: 6px 0px;} +.plugin-list > .plugin-item > .plug-title {height: 16px; overflow: hidden;} +.plugin-list > .plugin-item .extension-desc {overflow: hidden; height: 16px;} + +.bottom.flex > .panel, .side.panel {margin-bottom: 0;} +.bottom.flex > .official {flex: 1 1 30%; margin-right: 16px; padding: 40px 16px 16px 16px; display: flex; flex-direction: column; position: relative;} +.bottom.flex > .publicClass {flex: 1 1 60%;} + +.official {justify-content: center;} +.official > .panel-title {position: absolute; top: 0px;} +.official-img {background-image: url('/static/images/wechat.jpg'); background-repeat: no-repeat; background-size: contain; flex: 1 1 30%; aspect-ratio: 1 / 1; background-position: center;} +.official-content {flex: 0 0 60%; display: flex; flex-direction: column; justify-content: center; padding-left: 10px;} +.official-content > .content {color: #838A9D; font-size: 12px; line-height: 22px; padding-top: 6px;} +.official-content > .title {color: #313C52; font-size: 13px; line-height: 14px;} + +.classList > .classItem {flex: 1 1 30%; margin: 5px 5px 16px 5px; border: 1px solid rgba(227, 228, 233, 0.6); border-radius: 4px; padding-bottom: 5px; align-items: center;} +.classItem > .imgBack {flex: 1 1 50%;} +.classItem > .imgBack > .classImg {background-repeat: no-repeat; background-size: contain; aspect-ratio: 16 / 9; background-position: center; margin: 0; border-top-left-radius: 4px; border-top-right-radius: 4px;} +.classItem > .classContent {flex: 1 1 50%; padding: 5px; font-size: 14px; color: #0B0F18; text-align: center; overflow: hidden; height: 24px; margin-bottom: 6px; font-weight: 700;} +.more {float: right; padding-right: 12px; font-weight: normal; color: #9EA3B0;} +.panel.publicClass {padding: 0 10px;} +.icon.follow-us {font-size: 20px; padding-left: 10px;} + +.setting-help {width: 45px; color: #9EA3B0; padding-top: 15px;} +[lang^='zh'] .setting-help {padding-top: 0;} +.pointer-none {pointer-events: none;} + +/* css for without internet */ +.main.without-internet {display: flex; flex-wrap: wrap;} +.main.without-internet > .plug.panel {flex: 1 1 60%; margin-bottom: unset; margin-right: 16px;} +.main.without-internet > .bottom > .official.panel {margin-right: unset;} +.main.without-internet > .bottom > .official.panel > .main-panel {flex-direction: row-reverse;} + +/* css in side */ +#mainContent > .side.panel {height: 100%;} +.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; color: #5E626D;} +.time-count {letter-spacing: 1px;} + +.patch-block {padding: 10px 16px 12px; line-height: 20px; border-top: 1px solid #E3E4E9;} +.patch-content {height: 40px; overflow: hidden;} + +.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/css/safe.en.css b/module/admin/css/safe.en.css old mode 100644 new mode 100755 diff --git a/module/admin/css/safe.vi.css b/module/admin/css/safe.vi.css old mode 100644 new mode 100755 diff --git a/module/admin/css/safe.zh-cn.css b/module/admin/css/safe.zh-cn.css old mode 100644 new mode 100755 diff --git a/module/admin/css/safe.zh-tw.css b/module/admin/css/safe.zh-tw.css old mode 100644 new mode 100755 diff --git a/module/admin/css/setmodule.css b/module/admin/css/setmodule.css old mode 100644 new mode 100755 diff --git a/module/admin/js/checkweak.js b/module/admin/js/checkweak.js old mode 100644 new mode 100755 diff --git a/module/admin/js/index.js b/module/admin/js/index.js new file mode 100644 index 0000000000..f97411945c --- /dev/null +++ b/module/admin/js/index.js @@ -0,0 +1,13 @@ +$(function() +{ + $(document).on('click', '.setting-box > button', function() + { + location.href = $(this).attr('data-link'); + }).on('click', '.setting-box a', function(e) + { + e.stopPropagation(); + }).on('click', '.plugin-item', function() + { + window.open($(this).data('link')); + }); +}); diff --git a/module/admin/js/log.js b/module/admin/js/log.js old mode 100644 new mode 100755 diff --git a/module/admin/js/safe.js b/module/admin/js/safe.js old mode 100644 new mode 100755 diff --git a/module/admin/js/setmodule.js b/module/admin/js/setmodule.js old mode 100644 new mode 100755 diff --git a/module/admin/lang/de.php b/module/admin/lang/de.php old mode 100644 new mode 100755 index 7e8b99e72c..115ee795ec --- a/module/admin/lang/de.php +++ b/module/admin/lang/de.php @@ -25,11 +25,24 @@ $lang->admin->resetPWDSetting = 'Reset password Setting'; $lang->admin->tableEngine = 'Table Engine'; $lang->admin->setModuleIndex = 'Set Module'; -$lang->admin->api = 'API'; -$lang->admin->log = 'Log'; -$lang->admin->setting = 'Einstellungen'; -$lang->admin->days = 'Gültige Tage'; -$lang->admin->resetPWDByMail = 'Reset the password via the email'; +$lang->admin->mon = 'month'; +$lang->admin->day = 'day'; +$lang->admin->updateDynamics = 'updateDynamics'; +$lang->admin->updatePatch = 'updatePatch'; +$lang->admin->upgradeRecommend = 'upgradeRecommend'; +$lang->admin->zentaoUsed = ''; + +$lang->admin->api = 'API'; +$lang->admin->log = 'Log'; +$lang->admin->setting = 'Einstellungen'; +$lang->admin->pluginRecommendation = 'Recommended plug-ins'; +$lang->admin->zentaoInfo = 'ZenTao information'; +$lang->admin->officialAccount = 'WeChat Official Account'; +$lang->admin->publicClass = 'Public class'; +$lang->admin->days = 'Gültige Tage'; +$lang->admin->resetPWDByMail = 'Reset the password via the email'; +$lang->admin->followUs = 'Follow Us'; +$lang->admin->followUsContent = 'Check out ZenTao news, events, and support at any time'; $lang->admin->changeEngine = "Change to InnoDB"; $lang->admin->changingTable = 'Replacing data table %s engine...'; @@ -72,12 +85,14 @@ $lang->admin->setModule->optional = 'Optional'; $lang->admin->setModule->opened = 'Opened'; $lang->admin->setModule->closed = 'Closed'; +$lang->admin->setModule->my = 'My'; $lang->admin->setModule->product = 'Product'; $lang->admin->setModule->scrum = 'Scrum Project'; $lang->admin->setModule->waterfall = 'Waterfall Project'; $lang->admin->setModule->assetlib = 'Assetlib'; $lang->admin->setModule->other = 'Other'; +$lang->admin->setModule->score = 'Score'; $lang->admin->setModule->repo = 'Repo'; $lang->admin->setModule->issue = 'Issue'; $lang->admin->setModule->risk = 'Risk'; @@ -142,3 +157,47 @@ $lang->admin->safe->noticeMode = 'The password will be checked when creating $lang->admin->safe->noticeWeakMode = 'The password will be checked when logging into the system, creating and modifying user information, and changing passwords.'; $lang->admin->safe->noticeStrong = 'The longer the password, the more letters, numbers, or special characters it contains, and the less repetitive the password, the more secure it is!'; $lang->admin->safe->noticeGd = 'Your server does not have GD module installed, you cannot use the Captcha function, Please use it after installation.'; + +$lang->admin->menuSetting['system']['name'] = 'System'; +$lang->admin->menuSetting['system']['desc'] = 'System elements configuration, such as backup, chat, security etc.'; +$lang->admin->menuSetting['user']['name'] = 'User'; +$lang->admin->menuSetting['user']['desc'] = 'Manage departments,add members and group configuration permissions.'; +$lang->admin->menuSetting['switch']['name'] = 'Switch'; +$lang->admin->menuSetting['switch']['desc'] = 'Turn on and off some functions of the system.'; +$lang->admin->menuSetting['model']['name'] = 'Model'; +$lang->admin->menuSetting['model']['desc'] = 'Configure different project management models and project common elements.'; +$lang->admin->menuSetting['feature']['name'] = 'Feature'; +$lang->admin->menuSetting['feature']['desc'] = 'Configure the elements of the system according to the function menu.'; +$lang->admin->menuSetting['template']['name'] = 'Template'; +$lang->admin->menuSetting['template']['desc'] = 'Configure the template type and template content of the document.'; +$lang->admin->menuSetting['message']['name'] = 'Message'; +$lang->admin->menuSetting['message']['desc'] = 'Configure notification paths and customize the actions to be notified.'; +$lang->admin->menuSetting['extension']['name'] = 'Extension'; +$lang->admin->menuSetting['extension']['desc'] = 'Browse and install plugins.'; +$lang->admin->menuSetting['dev']['name'] = 'Develop'; +$lang->admin->menuSetting['dev']['desc'] = 'Support for secondary development of the system.'; +$lang->admin->menuSetting['convert']['name'] = 'Data Import'; +$lang->admin->menuSetting['convert']['desc'] = 'Data import from third-party systems.'; + +$lang->admin->updateDynamics = 'Dynamics'; +$lang->admin->updatePatch = 'Patch'; +$lang->admin->upgradeRecommend = 'Recommend Upgrade'; +$lang->admin->zentaoUsed = 'You have used ZenTao'; + +$lang->admin->openTag = 'ZenTao Opensource '; +$lang->admin->bizTag = 'ZenTao Biz '; +$lang->admin->maxTag = 'ZenTao Max '; + +$lang->admin->bizInfoURL = 'https://www.zentao.net/page/enterprise.html'; +$lang->admin->maxInfoURL = 'https://www.zentao.net/page/max.html'; +$lang->admin->productDetail = 'Detail'; +$lang->admin->productFeature['biz'][] = 'Feedback Management'; +$lang->admin->productFeature['biz'][] = 'Task Gantt Charts/Calendar/Effort'; +$lang->admin->productFeature['biz'][] = 'MS Word/Excel Import & Export'; +$lang->admin->productFeature['biz'][] = 'LDAP Support'; +$lang->admin->productFeature['max'][] = 'Project Metrics'; +$lang->admin->productFeature['max'][] = 'Asset Library'; +$lang->admin->productFeature['max'][] = 'QA Plan'; +$lang->admin->productFeature['max'][] = 'Opportunity/Risk/Issues Management'; + +include dirname(__FILE__) . '/menu.php'; diff --git a/module/admin/lang/en.php b/module/admin/lang/en.php old mode 100644 new mode 100755 index ef713be1f4..f377b35bad --- a/module/admin/lang/en.php +++ b/module/admin/lang/en.php @@ -25,19 +25,32 @@ $lang->admin->resetPWDSetting = 'Reset password Setting'; $lang->admin->tableEngine = 'Table Engine'; $lang->admin->setModuleIndex = 'Set Module'; -$lang->admin->api = 'API'; -$lang->admin->log = 'Log'; -$lang->admin->setting = 'Setting'; -$lang->admin->days = 'Valid Day'; -$lang->admin->resetPWDByMail = 'Reset the password via the email'; +$lang->admin->mon = 'month'; +$lang->admin->day = 'day'; +$lang->admin->updateDynamics = 'updateDynamics'; +$lang->admin->updatePatch = 'updatePatch'; +$lang->admin->upgradeRecommend = 'upgradeRecommend'; +$lang->admin->zentaoUsed = ''; -$lang->admin->changeEngine = "Change to InnoDB"; -$lang->admin->changingTable = 'Replacing data table %s engine...'; -$lang->admin->changeSuccess = 'The data table %s engine has been changed to InnoDB.'; -$lang->admin->changeFail = "Failed to replace table %s engine. Reason: %s。"; -$lang->admin->errorInnodb = 'Your MySQL does not support InnoDB data table engine.'; -$lang->admin->changeFinished = "Database engine replacement completed."; -$lang->admin->engineInfo = "The %s table engine is %s."; +$lang->admin->api = 'API'; +$lang->admin->log = 'Log'; +$lang->admin->setting = 'Setting'; +$lang->admin->pluginRecommendation = 'Recommended plug-ins'; +$lang->admin->zentaoInfo = 'ZenTao information'; +$lang->admin->officialAccount = 'WeChat Official Account'; +$lang->admin->publicClass = 'Public class'; +$lang->admin->days = 'Valid Day'; +$lang->admin->resetPWDByMail = 'Reset the password via the email'; +$lang->admin->followUs = 'Follow Us'; +$lang->admin->followUsContent = 'Check out ZenTao news, events, and support at any time'; + +$lang->admin->changeEngine = "Change to InnoDB"; +$lang->admin->changingTable = 'Replacing data table %s engine...'; +$lang->admin->changeSuccess = 'The data table %s engine has been changed to InnoDB.'; +$lang->admin->changeFail = "Failed to replace table %s engine. Reason: %s。"; +$lang->admin->errorInnodb = 'Your MySQL does not support InnoDB data table engine.'; +$lang->admin->changeFinished = "Database engine replacement completed."; +$lang->admin->engineInfo = "The %s table engine is %s."; $lang->admin->engineSummary['hasMyISAM'] = "There are %s tables that are not InnoDB engines"; $lang->admin->engineSummary['allInnoDB'] = "All tables are InnoDB engines"; @@ -72,12 +85,14 @@ $lang->admin->setModule->optional = 'Optional'; $lang->admin->setModule->opened = 'Opened'; $lang->admin->setModule->closed = 'Closed'; +$lang->admin->setModule->my = 'My'; $lang->admin->setModule->product = 'Product'; $lang->admin->setModule->scrum = 'Scrum Project'; $lang->admin->setModule->waterfall = 'Waterfall Project'; $lang->admin->setModule->assetlib = 'Assetlib'; $lang->admin->setModule->other = 'Other'; +$lang->admin->setModule->score = 'Score'; $lang->admin->setModule->repo = 'Repo'; $lang->admin->setModule->issue = 'Issue'; $lang->admin->setModule->risk = 'Risk'; @@ -142,3 +157,47 @@ $lang->admin->safe->noticeMode = 'The password will be checked when creating $lang->admin->safe->noticeWeakMode = 'The password will be checked when logging into the system, creating and modifying user information, and changing passwords.'; $lang->admin->safe->noticeStrong = 'The longer the password, the more letters, numbers, or special characters it contains, and the less repetitive the password, the more secure it is!'; $lang->admin->safe->noticeGd = 'Your server does not have GD module installed, you cannot use the Captcha function, Please use it after installation.'; + +$lang->admin->menuSetting['system']['name'] = 'System'; +$lang->admin->menuSetting['system']['desc'] = 'System elements configuration, such as backup, chat, security etc.'; +$lang->admin->menuSetting['user']['name'] = 'User'; +$lang->admin->menuSetting['user']['desc'] = 'Manage departments,add members and group configuration permissions.'; +$lang->admin->menuSetting['switch']['name'] = 'Switch'; +$lang->admin->menuSetting['switch']['desc'] = 'Turn on and off some functions of the system.'; +$lang->admin->menuSetting['model']['name'] = 'Model'; +$lang->admin->menuSetting['model']['desc'] = 'Configure different project management models and project common elements.'; +$lang->admin->menuSetting['feature']['name'] = 'Feature'; +$lang->admin->menuSetting['feature']['desc'] = 'Configure the elements of the system according to the function menu.'; +$lang->admin->menuSetting['template']['name'] = 'Template'; +$lang->admin->menuSetting['template']['desc'] = 'Configure the template type and template content of the document.'; +$lang->admin->menuSetting['message']['name'] = 'Message'; +$lang->admin->menuSetting['message']['desc'] = 'Configure notification paths and customize the actions to be notified.'; +$lang->admin->menuSetting['extension']['name'] = 'Extension'; +$lang->admin->menuSetting['extension']['desc'] = 'Browse and install plugins.'; +$lang->admin->menuSetting['dev']['name'] = 'Develop'; +$lang->admin->menuSetting['dev']['desc'] = 'Support for secondary development of the system.'; +$lang->admin->menuSetting['convert']['name'] = 'Data Import'; +$lang->admin->menuSetting['convert']['desc'] = 'Data import from third-party systems.'; + +$lang->admin->updateDynamics = 'Dynamics'; +$lang->admin->updatePatch = 'Patch'; +$lang->admin->upgradeRecommend = 'Recommend Upgrade'; +$lang->admin->zentaoUsed = 'You have used ZenTao'; + +$lang->admin->openTag = 'ZenTao Opensource '; +$lang->admin->bizTag = 'ZenTao Biz '; +$lang->admin->maxTag = 'ZenTao Max '; + +$lang->admin->bizInfoURL = 'https://www.zentao.net/page/enterprise.html'; +$lang->admin->maxInfoURL = 'https://www.zentao.net/page/max.html'; +$lang->admin->productDetail = 'Detail'; +$lang->admin->productFeature['biz'][] = 'Feedback Management'; +$lang->admin->productFeature['biz'][] = 'Task Gantt Charts/Calendar/Effort'; +$lang->admin->productFeature['biz'][] = 'MS Word/Excel Import & Export'; +$lang->admin->productFeature['biz'][] = 'LDAP Support'; +$lang->admin->productFeature['max'][] = 'Project Metrics'; +$lang->admin->productFeature['max'][] = 'Asset Library'; +$lang->admin->productFeature['max'][] = 'QA Plan'; +$lang->admin->productFeature['max'][] = 'Opportunity/Risk/Issues Management'; + +include dirname(__FILE__) . '/menu.php'; diff --git a/module/admin/lang/fr.php b/module/admin/lang/fr.php old mode 100644 new mode 100755 index 7b9455f538..416bdc6965 --- a/module/admin/lang/fr.php +++ b/module/admin/lang/fr.php @@ -25,11 +25,24 @@ $lang->admin->resetPWDSetting = 'Reset password Setting'; $lang->admin->tableEngine = 'Table Engine'; $lang->admin->setModuleIndex = 'Set Module'; -$lang->admin->api = 'API'; -$lang->admin->log = 'Log'; -$lang->admin->setting = 'Paramétrage'; -$lang->admin->days = 'Durée de conservation'; -$lang->admin->resetPWDByMail = 'Reset the password via the email'; +$lang->admin->mon = 'month'; +$lang->admin->day = 'day'; +$lang->admin->updateDynamics = 'updateDynamics'; +$lang->admin->updatePatch = 'updatePatch'; +$lang->admin->upgradeRecommend = 'upgradeRecommend'; +$lang->admin->zentaoUsed = ''; + +$lang->admin->api = 'API'; +$lang->admin->log = 'Log'; +$lang->admin->setting = 'Paramétrage'; +$lang->admin->pluginRecommendation = 'Recommended plug-ins'; +$lang->admin->zentaoInfo = 'ZenTao information'; +$lang->admin->officialAccount = 'WeChat Official Account'; +$lang->admin->publicClass = 'Public class'; +$lang->admin->days = 'Durée de conservation'; +$lang->admin->resetPWDByMail = 'Reset the password via the email'; +$lang->admin->followUs = 'Follow Us'; +$lang->admin->followUsContent = 'Check out ZenTao news, events, and support at any time'; $lang->admin->changeEngine = "Change to InnoDB"; $lang->admin->changingTable = 'Replacing data table %s engine...'; @@ -72,12 +85,14 @@ $lang->admin->setModule->optional = 'Optional'; $lang->admin->setModule->opened = 'Opened'; $lang->admin->setModule->closed = 'Closed'; +$lang->admin->setModule->my = 'My'; $lang->admin->setModule->product = 'Product'; $lang->admin->setModule->scrum = 'Scrum Project'; $lang->admin->setModule->waterfall = 'Waterfall Project'; $lang->admin->setModule->assetlib = 'Assetlib'; $lang->admin->setModule->other = 'Other'; +$lang->admin->setModule->score = 'Score'; $lang->admin->setModule->repo = 'Repo'; $lang->admin->setModule->issue = 'Issue'; $lang->admin->setModule->risk = 'Risk'; @@ -142,3 +157,47 @@ $lang->admin->safe->noticeMode = "Le mot de passe sera vérifié lors de la $lang->admin->safe->noticeWeakMode = "Le mot de passe sera vérifié lors de la connexion au système, de la création et de la modification des coordonnées de l'utilisateur, et du changement de mot de passe."; $lang->admin->safe->noticeStrong = "Le mot de passe est d'autant plus sécurisé qu'il est long, qu'il contient plus de lettres, de chiffres ou de caractères spéciaux, et que les lettres du mot de passe sont peu répétitives !"; $lang->admin->safe->noticeGd = 'Your server does not have GD module installed, you cannot use the Captcha function, Please use it after installation.'; + +$lang->admin->menuSetting['system']['name'] = 'System'; +$lang->admin->menuSetting['system']['desc'] = 'System elements configuration, such as backup, chat, security etc.'; +$lang->admin->menuSetting['user']['name'] = 'User'; +$lang->admin->menuSetting['user']['desc'] = 'Manage departments,add members and group configuration permissions.'; +$lang->admin->menuSetting['switch']['name'] = 'Switch'; +$lang->admin->menuSetting['switch']['desc'] = 'Turn on and off some functions of the system.'; +$lang->admin->menuSetting['model']['name'] = 'Model'; +$lang->admin->menuSetting['model']['desc'] = 'Configure different project management models and project common elements.'; +$lang->admin->menuSetting['feature']['name'] = 'Feature'; +$lang->admin->menuSetting['feature']['desc'] = 'Configure the elements of the system according to the function menu.'; +$lang->admin->menuSetting['template']['name'] = 'Template'; +$lang->admin->menuSetting['template']['desc'] = 'Configure the template type and template content of the document.'; +$lang->admin->menuSetting['message']['name'] = 'Message'; +$lang->admin->menuSetting['message']['desc'] = 'Configure notification paths and customize the actions to be notified.'; +$lang->admin->menuSetting['extension']['name'] = 'Extension'; +$lang->admin->menuSetting['extension']['desc'] = 'Browse and install plugins.'; +$lang->admin->menuSetting['dev']['name'] = 'Develop'; +$lang->admin->menuSetting['dev']['desc'] = 'Support for secondary development of the system.'; +$lang->admin->menuSetting['convert']['name'] = 'Data Import'; +$lang->admin->menuSetting['convert']['desc'] = 'Data import from third-party systems.'; + +$lang->admin->updateDynamics = 'Dynamics'; +$lang->admin->updatePatch = 'Patch'; +$lang->admin->upgradeRecommend = 'Recommend Upgrade'; +$lang->admin->zentaoUsed = 'You have used ZenTao'; + +$lang->admin->openTag = 'ZenTao Opensource '; +$lang->admin->bizTag = 'ZenTao Biz '; +$lang->admin->maxTag = 'ZenTao Max '; + +$lang->admin->bizInfoURL = 'https://www.zentao.net/page/enterprise.html'; +$lang->admin->maxInfoURL = 'https://www.zentao.net/page/max.html'; +$lang->admin->productDetail = 'Detail'; +$lang->admin->productFeature['biz'][] = 'Feedback Management'; +$lang->admin->productFeature['biz'][] = 'Task Gantt Charts/Calendar/Effort'; +$lang->admin->productFeature['biz'][] = 'MS Word/Excel Import & Export'; +$lang->admin->productFeature['biz'][] = 'LDAP Support'; +$lang->admin->productFeature['max'][] = 'Project Metrics'; +$lang->admin->productFeature['max'][] = 'Asset Library'; +$lang->admin->productFeature['max'][] = 'QA Plan'; +$lang->admin->productFeature['max'][] = 'Opportunity/Risk/Issues Management'; + +include dirname(__FILE__) . '/menu.php'; diff --git a/module/admin/lang/menu.php b/module/admin/lang/menu.php new file mode 100644 index 0000000000..d3cf02f789 --- /dev/null +++ b/module/admin/lang/menu.php @@ -0,0 +1,215 @@ +admin->menuList = new stdclass(); +$lang->admin->menuList->system['name'] = $lang->admin->menuSetting['system']['name']; +$lang->admin->menuList->system['desc'] = $lang->admin->menuSetting['system']['desc']; +$lang->admin->menuList->system['order'] = 1; + +$lang->admin->menuList->user['name'] = $lang->admin->menuSetting['user']['name']; +$lang->admin->menuList->user['desc'] = $lang->admin->menuSetting['user']['desc']; +$lang->admin->menuList->user['order'] = 2; + +$lang->admin->menuList->switch['name'] = $lang->admin->menuSetting['switch']['name']; +$lang->admin->menuList->switch['desc'] = $lang->admin->menuSetting['switch']['desc']; +$lang->admin->menuList->switch['order'] = 3; + +$lang->admin->menuList->model['name'] = $lang->admin->menuSetting['model']['name']; +$lang->admin->menuList->model['desc'] = $lang->admin->menuSetting['model']['desc']; +$lang->admin->menuList->model['order'] = 4; + +$lang->admin->menuList->feature['name'] = $lang->admin->menuSetting['feature']['name']; +$lang->admin->menuList->feature['desc'] = $lang->admin->menuSetting['feature']['desc']; +$lang->admin->menuList->feature['order'] = 5; + +$lang->admin->menuList->template['name'] = $lang->admin->menuSetting['template']['name']; +$lang->admin->menuList->template['desc'] = $lang->admin->menuSetting['template']['desc']; +$lang->admin->menuList->template['order'] = 6; + +$lang->admin->menuList->message['name'] = $lang->admin->menuSetting['message']['name']; +$lang->admin->menuList->message['desc'] = $lang->admin->menuSetting['message']['desc']; +$lang->admin->menuList->message['order'] = 7; + +$lang->admin->menuList->extension['name'] = $lang->admin->menuSetting['extension']['name']; +$lang->admin->menuList->extension['desc'] = $lang->admin->menuSetting['extension']['desc']; +$lang->admin->menuList->extension['link'] = 'extension|browse'; +$lang->admin->menuList->extension['order'] = 8; + +$lang->admin->menuList->dev['name'] = $lang->admin->menuSetting['dev']['name']; +$lang->admin->menuList->dev['desc'] = $lang->admin->menuSetting['dev']['desc']; +$lang->admin->menuList->dev['order'] = 9; + +$lang->admin->menuList->convert['name'] = $lang->admin->menuSetting['convert']['name']; +$lang->admin->menuList->convert['desc'] = $lang->admin->menuSetting['convert']['desc']; +$lang->admin->menuList->convert['link'] = 'convert|convertjira'; +$lang->admin->menuList->convert['order'] = 10; + +$lang->admin->menuList->system['subMenu']['mode'] = array('link' => "{$lang->custom->mode}|custom|mode|"); +$lang->admin->menuList->system['subMenu']['backup'] = array('link' => "{$lang->backup->common}|backup|index|"); +$lang->admin->menuList->system['subMenu']['trash'] = array('link' => "{$lang->action->trash}|action|trash|"); +$lang->admin->menuList->system['subMenu']['safe'] = array('link' => "{$lang->security}|admin|safe|", 'alias' => 'checkweak,resetpwdsetting', 'links' => array('admin|resetpwdsetting|', 'admin|checkweak|')); +$lang->admin->menuList->system['subMenu']['cron'] = array('link' => "{$lang->admin->cron}|cron|index|", 'subModule' => 'cron'); +$lang->admin->menuList->system['subMenu']['timezone'] = array('link' => "{$lang->timezone}|custom|timezone|"); +$lang->admin->menuList->system['subMenu']['buildindex'] = array('link' => "{$lang->admin->buildIndex}|search|buildindex|"); +$lang->admin->menuList->system['subMenu']['tableengine'] = array('link' => "{$lang->admin->tableEngine}|admin|tableengine|"); + +$lang->admin->menuList->system['menuOrder']['5'] = 'mode'; +$lang->admin->menuList->system['menuOrder']['10'] = 'backup'; +$lang->admin->menuList->system['menuOrder']['15'] = 'trash'; +$lang->admin->menuList->system['menuOrder']['30'] = 'safe'; +$lang->admin->menuList->system['menuOrder']['35'] = 'cron'; +$lang->admin->menuList->system['menuOrder']['40'] = 'timezone'; +$lang->admin->menuList->system['menuOrder']['45'] = 'buildindex'; +$lang->admin->menuList->system['menuOrder']['50'] = 'tableengine'; + +$lang->admin->menuList->system['dividerMenu'] = ',safe,'; + +$lang->admin->menuList->user['subMenu']['dept'] = array('link' => "{$lang->dept->common}|dept|browse|", 'subModule' => 'dept'); +$lang->admin->menuList->user['subMenu']['user'] = array('link' => "{$lang->user->common}|company|browse|", 'subModule' => 'user'); +$lang->admin->menuList->user['subMenu']['group'] = array('link' => "{$lang->priv}|group|browse|", 'subModule' => 'group'); + +$lang->admin->menuList->user['menuOrder']['5'] = 'dept'; +$lang->admin->menuList->user['menuOrder']['10'] = 'user'; +$lang->admin->menuList->user['menuOrder']['15'] = 'group'; + +$lang->admin->menuList->switch['subMenu']['setmodule'] = array('link' => "{$lang->admin->module}|admin|setmodule|"); + +$lang->admin->menuList->switch['menuOrder']['5'] = 'setmodule'; + +$lang->admin->menuList->model['subMenu']['common'] = array('link' => "{$lang->globalSetting}|custom|required|module=project", 'subModule' => 'custom,subject,holiday'); +$lang->admin->menuList->model['subMenu']['scrum'] = array('link' => "{$lang->scrumModel}|auditcl|scrumbrowse|", 'subModule' => 'auditcl'); +$lang->admin->menuList->model['subMenu']['waterfall'] = array('link' => "{$lang->waterfallModel}|stage|settype|", 'subModule' => 'stage'); + +$lang->admin->menuList->model['menuOrder']['5'] = 'common'; +$lang->admin->menuList->model['menuOrder']['10'] = 'scrum'; +$lang->admin->menuList->model['menuOrder']['15'] = 'waterfall'; + +$lang->admin->menuList->model['tabMenu']['common']['project'] = array('link' => "{$lang->project->common}|custom|required|module=project", 'alias' => 'set', 'exclude' => 'custom', 'links' => array('custom|set|')); +$lang->admin->menuList->model['tabMenu']['common']['build'] = array('link' => "{$lang->build->common}|custom|required|module=build", 'alias' => 'set', 'exclude' => 'custom'); +$lang->admin->menuList->model['tabMenu']['common']['flow'] = array('link' => "{$lang->custom->flow}|custom|flow|", 'divider' => true); +$lang->admin->menuList->model['tabMenu']['common']['code'] = array('link' => "{$lang->code}|custom|code|"); +$lang->admin->menuList->model['tabMenu']['common']['hours'] = array('link' => "{$lang->workingHour}|custom|hours|", 'subModule' => 'holiday', 'links' => array('holiday|browse|')); +$lang->admin->menuList->model['tabMenu']['waterfall']['stage'] = array('link' => "{$lang->stage->common}|stage|settype|", 'subModule' => 'stage', 'links' => array('stage|browse|')); +$lang->admin->menuList->model['tabMenu']['menuOrder']['common']['5'] = 'project'; +$lang->admin->menuList->model['tabMenu']['menuOrder']['common']['10'] = 'build'; +$lang->admin->menuList->model['tabMenu']['menuOrder']['common']['35'] = 'flow'; +$lang->admin->menuList->model['tabMenu']['menuOrder']['common']['40'] = 'code'; +$lang->admin->menuList->model['tabMenu']['menuOrder']['common']['45'] = 'hours'; +$lang->admin->menuList->model['tabMenu']['menuOrder']['waterfall']['5'] = 'stage'; + +$lang->admin->menuList->feature['subMenu']['my'] = array('link' => "{$lang->my->common}|custom|set|module=todo&field=priList", 'exclude' => 'set,required'); +$lang->admin->menuList->feature['subMenu']['product'] = array('link' => "{$lang->productCommon}|custom|required|module=product", 'exclude' => 'set,required', 'alias' => 'browsestoryconcept,product'); +$lang->admin->menuList->feature['subMenu']['execution'] = array('link' => "{$lang->execution->common}|custom|execution|"); +$lang->admin->menuList->feature['subMenu']['qa'] = array('link' => "{$lang->qa->common}|custom|required|module=bug", 'exclude' => 'set,required'); +$lang->admin->menuList->feature['subMenu']['kanban'] = array('link' => "{$lang->kanban->common}|custom|kanban|"); +$lang->admin->menuList->feature['subMenu']['doc'] = array('link' => "{$lang->doc->common}|custom|required|module=doc", 'exclude' => 'required'); +$lang->admin->menuList->feature['subMenu']['user'] = array('link' => "{$lang->user->common}|custom|required|module=user", 'links' => array('custom|set|module=user&field=roleList'), 'exclude' => 'set,required'); + +$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'); + +$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,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['tabMenu']['menuOrder']['my']['5'] = 'todo'; +$lang->admin->menuList->feature['tabMenu']['menuOrder']['my']['10'] = 'block'; +$lang->admin->menuList->feature['tabMenu']['menuOrder']['product']['5'] = 'product'; +$lang->admin->menuList->feature['tabMenu']['menuOrder']['product']['10'] = 'story'; +$lang->admin->menuList->feature['tabMenu']['menuOrder']['product']['15'] = 'productplan'; +$lang->admin->menuList->feature['tabMenu']['menuOrder']['product']['20'] = 'release'; +$lang->admin->menuList->feature['tabMenu']['menuOrder']['execution']['5'] = 'execution'; +$lang->admin->menuList->feature['tabMenu']['menuOrder']['execution']['10'] = 'task'; +$lang->admin->menuList->feature['tabMenu']['menuOrder']['qa']['5'] = 'bug'; +$lang->admin->menuList->feature['tabMenu']['menuOrder']['qa']['10'] = 'testcase'; +$lang->admin->menuList->feature['tabMenu']['menuOrder']['qa']['15'] = 'testsuite'; +$lang->admin->menuList->feature['tabMenu']['menuOrder']['qa']['20'] = 'testtask'; +$lang->admin->menuList->feature['tabMenu']['menuOrder']['qa']['25'] = 'testreport'; +$lang->admin->menuList->feature['tabMenu']['menuOrder']['qa']['30'] = 'caselib'; + +$lang->admin->menuList->feature['menuOrder']['5'] = 'my'; +$lang->admin->menuList->feature['menuOrder']['10'] = 'product'; +$lang->admin->menuList->feature['menuOrder']['15'] = 'execution'; +$lang->admin->menuList->feature['menuOrder']['20'] = 'qa'; +$lang->admin->menuList->feature['menuOrder']['25'] = 'kanban'; +$lang->admin->menuList->feature['menuOrder']['30'] = 'doc'; +$lang->admin->menuList->feature['menuOrder']['50'] = 'user'; + +$lang->admin->menuList->feature['dividerMenu'] = ',user,'; + +$lang->admin->menuList->message['subMenu']['mail'] = array('link' => "{$lang->mail->common}|mail|edit|", 'subModule' => 'mail'); +$lang->admin->menuList->message['subMenu']['webhook'] = array('link' => "Webhook|webhook|browse|", 'subModule' => 'webhook'); +$lang->admin->menuList->message['subMenu']['browser'] = array('link' => "{$lang->browser}|message|browser|"); +$lang->admin->menuList->message['subMenu']['setting'] = array('link' => "{$lang->settings}|message|setting|"); + +$lang->admin->menuList->message['menuOrder']['5'] = 'mail'; +$lang->admin->menuList->message['menuOrder']['10'] = 'webhook'; +$lang->admin->menuList->message['menuOrder']['20'] = 'browser'; +$lang->admin->menuList->message['menuOrder']['25'] = 'setting'; + +$lang->admin->menuList->dev['subMenu']['api'] = array('link' => "API|dev|api|module=index"); +$lang->admin->menuList->dev['subMenu']['db'] = array('link' => "{$lang->database}|dev|db|table=" . trim(TABLE_EFFORT, '`')); +$lang->admin->menuList->dev['subMenu']['editor'] = array('link' => "{$lang->editor}|dev|editor|"); +$lang->admin->menuList->dev['subMenu']['entry'] = array('link' => "{$lang->admin->entry}|entry|browse|", 'subModule' => 'entry'); + +$lang->admin->menuList->dev['menuOrder']['5'] = 'api'; +$lang->admin->menuList->dev['menuOrder']['10'] = 'db'; +$lang->admin->menuList->dev['menuOrder']['15'] = 'editor'; +$lang->admin->menuList->dev['menuOrder']['20'] = 'entry'; + +if($config->edition != 'max') unset($lang->admin->menuList->model['subMenu']['scrum'], $lang->admin->menuList->model['menuOrder']['10'], $lang->admin->menuList->template); +if(!helper::hasFeature('waterfall')) +{ + unset($lang->admin->menuList->model['subMenu']['waterfall']); + unset($lang->admin->menuList->model['menuOrder']['15']); +} +if($config->edition == 'max' and !helper::hasFeature('scrum_auditplan')) +{ + if(!helper::hasFeature('scrum_process')) unset($lang->admin->menuList->model['subMenu']['scrum'], $lang->admin->menuList->model['menuOrder']['10']); +} + +if($config->vision == 'lite') +{ + unset($lang->admin->menuList->system['subMenu']['mode']); + unset($lang->admin->menuList->system['subMenu']['buildindex']); + unset($lang->admin->menuList->system['subMenu']['tableengine']); + unset($lang->admin->menuList->system['menuOrder']['5']); + unset($lang->admin->menuList->system['menuOrder']['45']); + unset($lang->admin->menuList->system['menuOrder']['50']); + + unset($lang->admin->menuList->model['subMenu']['scrum']); + unset($lang->admin->menuList->model['subMenu']['waterfall']); + unset($lang->admin->menuList->model['menuOrder']['10']); + unset($lang->admin->menuList->model['menuOrder']['15']); + + 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->projectCommon}|custom|execution|", 'exclude' => 'set,required', 'alias' => 'execution'); + $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']['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['tabMenu']['menuOrder']['my']['15'] = 'task'; + $lang->admin->menuList->feature['tabMenu']['menuOrder']['project']['5'] = 'project'; + $lang->admin->menuList->feature['tabMenu']['menuOrder']['project']['10'] = 'execution'; + $lang->admin->menuList->feature['tabMenu']['menuOrder']['project']['15'] = 'story'; + + $lang->admin->menuList->feature['menuOrder']['15'] = 'project'; +} diff --git a/module/admin/lang/vi.php b/module/admin/lang/vi.php old mode 100644 new mode 100755 index a51563ca2f..feff21edda --- a/module/admin/lang/vi.php +++ b/module/admin/lang/vi.php @@ -22,10 +22,17 @@ $lang->admin->captcha = 'Mã xác thực'; $lang->admin->getCaptcha = 'Gửi Mã xác thực'; $lang->admin->register = 'Register'; -$lang->admin->api = 'API'; -$lang->admin->log = 'Nhật ký'; -$lang->admin->setting = 'Thiết lập'; -$lang->admin->days = 'Ngày hợp lệ'; +$lang->admin->api = 'API'; +$lang->admin->log = 'Nhật ký'; +$lang->admin->setting = 'Thiết lập'; +$lang->admin->pluginRecommendation = 'Recommended plug-ins'; +$lang->admin->zentaoInfo = 'ZenTao information'; +$lang->admin->officialAccount = 'WeChat Official Account'; +$lang->admin->publicClass = 'Public class'; +$lang->admin->days = 'Ngày hợp lệ'; +$lang->admin->resetPWDByMail = 'Reset the password via the email'; +$lang->admin->followUs = 'Follow Us'; +$lang->admin->followUsContent = 'Check out ZenTao news, events, and support at any time'; $lang->admin->info = new stdclass(); $lang->admin->info->version = 'Phiên bản hiện tại là %s. '; @@ -84,4 +91,12 @@ $lang->admin->safe->loginCaptchaList[0] = 'No'; $lang->admin->safe->noticeMode = 'Mật khẩu sẽ được kiểm tra khi người dùng đăng nhập hoặc người dùng thêm hoặc sửa.'; $lang->admin->safe->noticeStrong = ''; -$lang->admin->safe->noticeGd = 'Your server does not have GD module installed, you cannot use the Captcha function, Please use it after installation.'; \ No newline at end of file +$lang->admin->safe->noticeGd = 'Your server does not have GD module installed, you cannot use the Captcha function, Please use it after installation.'; + +$lang->admin->mon = 'month'; +$lang->admin->day = 'day'; +$lang->admin->updateDynamics = 'updateDynamics'; +$lang->admin->updatePatch = 'updatePatch'; +$lang->admin->upgradeRecommend = 'upgradeRecommend'; + +include dirname(__FILE__) . '/menu.php'; diff --git a/module/admin/lang/zh-cn.php b/module/admin/lang/zh-cn.php old mode 100644 new mode 100755 index e824152939..926dede079 --- a/module/admin/lang/zh-cn.php +++ b/module/admin/lang/zh-cn.php @@ -25,19 +25,32 @@ $lang->admin->resetPWDSetting = '重置密码设置'; $lang->admin->tableEngine = '表引擎'; $lang->admin->setModuleIndex = '系统功能配置'; -$lang->admin->api = '接口'; -$lang->admin->log = '日志'; -$lang->admin->setting = '设置'; -$lang->admin->days = '日志保存天数'; -$lang->admin->resetPWDByMail = '通过邮箱重置密码'; +$lang->admin->mon = '月'; +$lang->admin->day = '天'; +$lang->admin->updateDynamics = '更新动态'; +$lang->admin->updatePatch = '补丁更新'; +$lang->admin->upgradeRecommend = '推荐升级'; +$lang->admin->zentaoUsed = '您已使用禅道'; -$lang->admin->changeEngine = "更换到InnoDB"; -$lang->admin->changingTable = '正在更换数据表%s引擎...'; -$lang->admin->changeSuccess = '已经更换数据表%s引擎为InnoDB。'; -$lang->admin->changeFail = "更换数据表%s引擎失败,原因:%s。"; -$lang->admin->errorInnodb = '您当前的数据库不支持使用InnoDB数据表引擎。'; -$lang->admin->changeFinished = "更换数据库引擎完毕。"; -$lang->admin->engineInfo = "表%s的引擎是%s。"; +$lang->admin->api = '接口'; +$lang->admin->log = '日志'; +$lang->admin->setting = '设置'; +$lang->admin->pluginRecommendation = '插件推荐'; +$lang->admin->zentaoInfo = '禅道信息'; +$lang->admin->officialAccount = '官方公众号'; +$lang->admin->publicClass = '公开课'; +$lang->admin->days = '日志保存天数'; +$lang->admin->resetPWDByMail = '通过邮箱重置密码'; +$lang->admin->followUs = '扫码关注公众号'; +$lang->admin->followUsContent = '随时查看禅道动态、活动信息、也可获取帮助支持'; + +$lang->admin->changeEngine = "更换到InnoDB"; +$lang->admin->changingTable = '正在更换数据表%s引擎...'; +$lang->admin->changeSuccess = '已经更换数据表%s引擎为InnoDB。'; +$lang->admin->changeFail = "更换数据表%s引擎失败,原因:%s。"; +$lang->admin->errorInnodb = '您当前的数据库不支持使用InnoDB数据表引擎。'; +$lang->admin->changeFinished = "更换数据库引擎完毕。"; +$lang->admin->engineInfo = "表%s的引擎是%s。"; $lang->admin->engineSummary['hasMyISAM'] = "有%s个表不是InnoDB引擎"; $lang->admin->engineSummary['allInnoDB'] = "所有的表都是InnoDB引擎了"; @@ -72,12 +85,14 @@ $lang->admin->setModule->optional = '可选功能'; $lang->admin->setModule->opened = '已开启'; $lang->admin->setModule->closed = '已关闭'; +$lang->admin->setModule->my = '地盘'; $lang->admin->setModule->product = '产品'; $lang->admin->setModule->scrum = '敏捷项目'; $lang->admin->setModule->waterfall = '瀑布项目'; $lang->admin->setModule->assetlib = '资产库'; $lang->admin->setModule->other = '通用功能'; +$lang->admin->setModule->score = '积分'; $lang->admin->setModule->repo = '代码'; $lang->admin->setModule->issue = '问题'; $lang->admin->setModule->risk = '风险'; @@ -142,3 +157,47 @@ $lang->admin->safe->noticeMode = '系统会在创建和修改用户、修改 $lang->admin->safe->noticeWeakMode = '系统会在登录、创建和修改用户、修改密码的时候检查用户口令。'; $lang->admin->safe->noticeStrong = '密码长度越长,含有大写字母或数字或特殊符号越多,密码字母越不重复,安全度越强!'; $lang->admin->safe->noticeGd = '系统检测到您的服务器未安装GD模块,无法使用验证码功能,请安装后使用。'; + +$lang->admin->menuSetting['system']['name'] = '系统设置'; +$lang->admin->menuSetting['system']['desc'] = '备份、聊天、安全等系统各要素配置。'; +$lang->admin->menuSetting['user']['name'] = '人员管理'; +$lang->admin->menuSetting['user']['desc'] = '维护部门、添加人员、分组配置权限。'; +$lang->admin->menuSetting['switch']['name'] = '功能开关'; +$lang->admin->menuSetting['switch']['desc'] = '打开、关闭系统部分功能。'; +$lang->admin->menuSetting['model']['name'] = '模型配置'; +$lang->admin->menuSetting['model']['desc'] = '不同项目管理模型和项目通用要素配置。'; +$lang->admin->menuSetting['feature']['name'] = '功能配置'; +$lang->admin->menuSetting['feature']['desc'] = '按照功能菜单进行系统的要素配置。'; +$lang->admin->menuSetting['template']['name'] = '文档模板'; +$lang->admin->menuSetting['template']['desc'] = '配置文档的模板类型和模板内容。'; +$lang->admin->menuSetting['message']['name'] = '通知设置'; +$lang->admin->menuSetting['message']['desc'] = '配置通知路径,自定义需要通知的动作。'; +$lang->admin->menuSetting['extension']['name'] = '插件管理'; +$lang->admin->menuSetting['extension']['desc'] = '浏览、安装插件。'; +$lang->admin->menuSetting['dev']['name'] = '二次开发'; +$lang->admin->menuSetting['dev']['desc'] = '支持对系统进行二次开发。'; +$lang->admin->menuSetting['convert']['name'] = '数据导入'; +$lang->admin->menuSetting['convert']['desc'] = '第三方系统的数据导入。'; + +$lang->admin->updateDynamics = '更新动态'; +$lang->admin->updatePatch = '补丁更新'; +$lang->admin->upgradeRecommend = '推荐升级'; +$lang->admin->zentaoUsed = '您已使用禅道'; + +$lang->admin->openTag = '禅道'; +$lang->admin->bizTag = '禅道企业版'; +$lang->admin->maxTag = '禅道旗舰版'; + +$lang->admin->bizInfoURL = 'https://www.zentao.net/page/enterprise.html'; +$lang->admin->maxInfoURL = 'https://www.zentao.net/page/max.html'; +$lang->admin->productDetail = '查看详情'; +$lang->admin->productFeature['biz'][] = '工时管理、甘特图、导入导出'; +$lang->admin->productFeature['biz'][] = '40+内置统计报表、自定义报表功能'; +$lang->admin->productFeature['biz'][] = '强大的自定义工作流、反馈管理功能'; +$lang->admin->productFeature['biz'][] = '价格厚道,专属技术支持服务'; +$lang->admin->productFeature['max'][] = '120+概念,全面覆盖瀑布管理模型'; +$lang->admin->productFeature['max'][] = '项目管理可视化,精准掌控项目进度'; +$lang->admin->productFeature['max'][] = '资产库管理,为项目提供数据支撑'; +$lang->admin->productFeature['max'][] = '严格权限控制,方式灵活安全'; + +include dirname(__FILE__) . '/menu.php'; diff --git a/module/admin/lang/zh-tw.php b/module/admin/lang/zh-tw.php old mode 100644 new mode 100755 diff --git a/module/admin/model.php b/module/admin/model.php old mode 100644 new mode 100755 index 17a6d6a63b..9c8585eebf --- a/module/admin/model.php +++ b/module/admin/model.php @@ -13,6 +13,11 @@ birthday and $user->password == md5($user->birthday)) return true; return false; } + + /** + * Set admin menu. + * + * @access public + * @return void + */ + public function setMenu() + { + $this->checkPrivMenu(); + + $menuKey = $this->getMenuKey(); + if(empty($menuKey)) return; + + $this->setSwitcher($menuKey); + if(isset($this->lang->admin->menuList->$menuKey)) + { + if(isset($this->lang->admin->menuList->$menuKey['subMenu'])) + { + $moduleName = $this->app->rawModule; + $methodName = $this->app->rawMethod; + $firstParam = $this->app->rawParams ? reset($this->app->rawParams) : ''; + + foreach($this->lang->admin->menuList->$menuKey['subMenu'] as $subMenuKey => $subMenu) + { + $subModule = ''; + if($moduleName == 'custom' and strpos(',required,set,', $methodName) !== false) + { + if(isset($this->config->admin->navsGroup[$menuKey][$subMenuKey]) and strpos($this->config->admin->navsGroup[$menuKey][$subMenuKey], ",$firstParam,") !== false) $subModule = 'custom'; + if($firstParam == $subMenuKey) $subModule = 'custom'; + } + + if(!empty($subModule)) $subMenu['subModule'] = $subModule; + if(isset($this->lang->admin->menuList->$menuKey['tabMenu'][$subMenuKey])) + { + if(!empty($subModule)) + { + $this->lang->admin->menuList->$menuKey['tabMenu'][$subMenuKey][$firstParam]['subModule'] = $subModule; + unset($this->lang->admin->menuList->$menuKey['tabMenu'][$subMenuKey][$firstParam]['exclude']); + } + $subMenu['subMenu'] = $this->lang->admin->menuList->$menuKey['tabMenu'][$subMenuKey]; + } + if(isset($this->lang->admin->menuList->$menuKey['tabMenu']['menuOrder'][$subMenuKey])) $subMenu['menuOrder'] = $this->lang->admin->menuList->$menuKey['tabMenu']['menuOrder'][$subMenuKey]; + if(isset($this->lang->admin->menuList->$menuKey['tabMenu']['dividerMenu'][$subMenuKey])) $subMenu['dividerMenu'] = $this->lang->admin->menuList->$menuKey['tabMenu']['dividerMenu'][$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']; + if(isset($this->lang->admin->menuList->$menuKey['dividerMenu'])) $this->lang->admin->dividerMenu = $this->lang->admin->menuList->$menuKey['dividerMenu']; + if(isset($this->lang->admin->menuList->$menuKey['tabMenu'])) $this->lang->admin->tabMenu = $this->lang->admin->menuList->$menuKey['tabMenu']; + } + } + + /** + * Check priv menu. + * + * @access public + * @return void + */ + public function checkPrivMenu() + { + $orders = array(); + foreach($this->lang->admin->menuList as $menuKey => $menu) + { + $menu['disabled'] = true; + if(!isset($menu['link'])) $menu['link'] = ''; + + /* Set links to authorized navigation. */ + if(isset($menu['subMenu'])) + { + /* Reorder secondary navigation. */ + $subMenuList = array(); + $subMenuOrders = $menu['menuOrder']; + ksort($subMenuOrders); + foreach($subMenuOrders as $value) $subMenuList[$value] = $menu['subMenu'][$value]; + + /* Check sub menu priv. */ + foreach($subMenuList as $subMenuKey => $subMenu) + { + $link = array(); + if(isset($menu['tabMenu'][$subMenuKey])) + { + /* Reorder tertiary navigation. */ + $tabMenuList = $menu['tabMenu'][$subMenuKey]; + if(isset($menu['tabMenu']['menuOrder'][$subMenuKey])) + { + $tabMenuOrders = $menu['tabMenu']['menuOrder'][$subMenuKey]; + ksort($tabMenuOrders); + foreach($tabMenuOrders as $value) $tabMenuList[$value] = $menu['tabMenu'][$subMenuKey][$value]; + } + + /* Check tab menu priv. */ + foreach($tabMenuList as $tabMenuKey => $tabMenu) + { + $tabMenuLink = $this->getHasPrivLink($tabMenu); + if(!empty($tabMenuLink)) + { + /* Updated tertiary navigation links. */ + list($module, $method, $params) = $tabMenuLink; + $tabMenuLabel = $tabMenu['link']; + $menu['tabMenu'][$subMenuKey][$tabMenuKey]['link'] = substr($tabMenuLabel, 0, strpos($tabMenuLabel, '|') + 1) . $module . '|' . $method . '|' . $params; + + if(empty($link)) $link = $tabMenuLink; + } + } + } + else + { + if($menuKey == 'message' and $subMenuKey == 'mail') + { + $this->loadModel('mail'); + if(!$this->config->mail->turnon and !$this->session->mailConfig) $subMenu['link'] = $this->lang->mail->common . '|mail|detect|'; + } + + $link = $this->getHasPrivLink($subMenu); + } + + if(!empty($link)) + { + /* Updated secondary navigation link. */ + list($module, $method, $params) = $link; + $subMenuLabel = $subMenu['link']; + $menu['subMenu'][$subMenuKey]['link'] = substr($subMenuLabel, 0, strpos($subMenuLabel, '|') + 1) . $module . '|' . $method . '|' . $params; + + /* Update the level 1 navigation link. */ + if(empty($menu['link'])) $menu['link'] = helper::createLink($module, $method, $params); + $menu['disabled'] = false; + } + } + } + elseif(!empty($menu['link']) and strpos($menu['link'], '|') !== false) + { + list($module, $method) = explode('|', $menu['link']); + $menu['link'] = helper::createLink($module, $method); + if(common::hasPriv($module, $method)) $menu['disabled'] = false; + } + + $order = $menu['order']; + $orders[$order] = $menuKey; + + $this->lang->admin->menuList->$menuKey = $menu; + } + + ksort($orders); + $menuList = new stdclass(); + foreach($orders as $index => $menuKey) + { + $menuList->$menuKey = $this->lang->admin->menuList->$menuKey; + $menuList->$menuKey['order'] = $index; + } + + $this->lang->admin->menuList = $menuList; + } + + /** + * Get the authorized link. + * + * @param array $menu + * @access public + * @return array + */ + public function getHasPrivLink($menu) + { + $link = array(); + if(!empty($menu['link'])) + { + list($label, $module, $method, $params) = explode('|', $menu['link']); + if(common::hasPriv($module, $method)) + { + $link = array($module, $method, $params); + } + elseif(!empty($menu['links'])) + { + foreach($menu['links'] as $menuLink) + { + list($module, $method, $params) = explode('|', $menuLink); + if(common::hasPriv($module, $method)) + { + $link = array($module, $method, $params); + break; + } + } + } + } + + return $link; + } + + /** + * Get menu key + * + * @access public + * @return string + */ + public function getMenuKey() + { + $moduleName = $this->app->rawModule; + $methodName = $this->app->rawMethod; + $firstParam = $this->app->rawParams ? reset($this->app->rawParams) : ''; + $secondParam = $this->app->rawParams ? next($this->app->rawParams) : ''; + + foreach($this->config->admin->menuGroup as $menuKey => $menuGroup) + { + if(in_array($moduleName, $menuGroup)) + { + return $menuKey; + } + elseif(in_array("$moduleName|$methodName", $menuGroup)) + { + if($moduleName == 'custom' and ($methodName == 'required' or $methodName == 'set')) + { + if(in_array($firstParam, $this->config->admin->menuModuleGroup[$menuKey]["custom|$methodName"])) return $menuKey; + } + else + { + return $menuKey; + } + } + } + return null; + } + + /** + * Set switcher. + * + * @param string $currentMenuKey + * @access public + * @return string + */ + public function setSwitcher($currentMenuKey = 'system') + { + if(empty($currentMenuKey)) return null; + + $currentMenu = $this->lang->admin->menuList->$currentMenuKey; + $output = "
"; + $output .= ""; + $output .= "
"; + + $this->lang->switcherMenu = $output; + } + + /** + * Get extensions from zentao.net. + * + * @param string $type plugin|patch + * @param int $limit + * @param bool $hasInternet + * @access public + * @return array + */ + public function getExtensionsByAPI($type = 'plugin', $limit = 6, $hasInternet = true) + { + if($hasInternet) + { + $searchType = $type == 'plugin' ? 'byUpdatedTime,offcial' : 'byModule'; + $param = $type == 'plugin' ? '' : 'MTIxOA=='; + $extensions = $this->loadModel('extension')->getExtensionsByAPI($searchType, $param, 0, $limit); + $plugins = isset($extensions->extensions) ? (array)$extensions->extensions : array(); + foreach($plugins as $id => $plugin) + { + $plugin->viewLink = str_replace(array('info', 'client'), '', $plugin->viewLink); + if($type == 'patch' and !isset($plugin->compatibleRelease)) unset($plugins[$id]); + } + } + else + { + if($this->config->edition == 'open') + { + $plugins = array( + $this->config->admin->plugins[27], + $this->config->admin->plugins[26], + $this->config->admin->plugins[30] + ); + } + else + { + $plugins = array( + $this->config->admin->plugins[198], + $this->config->admin->plugins[194], + $this->config->admin->plugins[203] + ); + } + } + + return $plugins; + } + + /** + * Fetch data from an api. + * + * @param string $url + * @access public + * @return mixed + */ + public function fetchAPI($url) + { + $version = $this->loadModel('upgrade')->getOpenVersion(str_replace('.', '_', $this->config->version)); + $version = str_replace('_', '.', $version); + + $url .= (strpos($url, '?') === false ? '?' : '&') . 'lang=' . str_replace('-', '_', $this->app->getClientLang()) . '&managerVersion=' . self::EXT_MANAGER_VERSION . '&zentaoVersion=' . $version . '&edition=' . $this->config->edition; + $result = json_decode(preg_replace('/[[:cntrl:]]/mu', '', common::http($url))); + + if(!isset($result->status)) return false; + if($result->status != 'success') return false; + if(isset($result->data)) return json_decode($result->data); + } + + /** + * Get public class from zentao.net. + * + * @param int $limit + * @access public + * @return array + */ + public function getPublicClassByAPI($limit = 2) + { + $apiURL = $this->config->admin->videoAPIURL; + $data = $this->fetchAPI($apiURL); + $courses = $data->videos; + + $index = 1; + $publicClass = array(); + foreach($courses as $course) + { + if($index > $limit) break; + + $publicClass[$index] = new stdClass(); + $publicClass[$index]->name = $course->title; + $publicClass[$index]->image = $this->config->admin->cdnRoot . $course->image->list[0]->middleURL; + $publicClass[$index]->viewLink = $this->config->admin->apiRoot . '/publicclass/' . ($course->alias ? "{$course->alias}-" : '') . "{$course->id}.html"; + $index ++; + } + return $publicClass; + } + + /** + * Get dynamics by API. + * + * @param int $limit + * @access public + * @return array + */ + public function getDynamicsByAPI($limit = 2) + { + $apiURL = $this->config->admin->downloadAPIURL; + $data = $this->fetchAPI($apiURL); + $articles = $data->articles; + + $index = 1; + $downloads = array(); + foreach($articles as $article) + { + if($index > $limit) break; + + $tagKey = $this->config->edition . 'Tag'; + if(!isset($this->lang->admin->$tagKey)) break; + if(!preg_match("/{$this->lang->admin->$tagKey}\d/", $article->title)) continue; + + $downloads[$index] = new stdClass(); + $downloads[$index]->id = $article->id; + $downloads[$index]->title = $article->title; + $downloads[$index]->addedDate = $article->addedDate; + $downloads[$index]->link = $this->config->admin->apiRoot . "/download/{$article->alias}-{$article->id}.html"; + $index ++; + } + return $downloads; + } + + /** + * Check internet. + * + * @access public + * @return bool + */ + public function checkInternet() + { + $curl = curl_init(); + curl_setopt($curl, CURLOPT_URL, $this->config->admin->apiSite); + curl_setopt($curl, CURLOPT_TIMEOUT_MS, 1000); + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT_MS, 1000); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); + curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); + $connected = curl_exec($curl); + curl_close($curl); + + return (bool)$connected; + } + + /** + * Get date used object. + * + * @access public + * @return object + */ + public function genDateUsed() + { + $firstUseDate = $this->dao->select('date')->from(TABLE_ACTION) + ->where('date')->gt('0000-00-00') + ->andWhere('actor')->eq($this->app->user->account) + ->orderBy('date_asc') + ->limit('1') + ->fetch('date'); + + return helper::getDateInterval($firstUseDate); + } } diff --git a/module/admin/view/bind.html.php b/module/admin/view/bind.html.php old mode 100644 new mode 100755 diff --git a/module/admin/view/certifyztemail.html.php b/module/admin/view/certifyztemail.html.php old mode 100644 new mode 100755 diff --git a/module/admin/view/certifyztmobile.html.php b/module/admin/view/certifyztmobile.html.php old mode 100644 new mode 100755 diff --git a/module/admin/view/checkweak.html.php b/module/admin/view/checkweak.html.php old mode 100644 new mode 100755 index c667135670..caa0df887a --- a/module/admin/view/checkweak.html.php +++ b/module/admin/view/checkweak.html.php @@ -16,8 +16,8 @@
createLink('admin', 'safe'), $lang->admin->safe->set); - echo html::a($this->createLink('admin', 'checkWeak'), $lang->admin->safe->checkWeak, '', "class='active'"); + if(common::hasPriv('admin', 'safe')) echo html::a($this->createLink('admin', 'safe'), $lang->admin->safe->set); + if(common::hasPriv('admin', 'checkWeak')) echo html::a($this->createLink('admin', 'checkWeak'), $lang->admin->safe->checkWeak, '', "class='active'"); if(common::hasPriv('admin', 'resetPWDSetting')) echo html::a($this->createLink('admin', 'resetPWDSetting'), $lang->admin->resetPWDSetting); ?>
diff --git a/module/admin/view/index.html.php b/module/admin/view/index.html.php old mode 100644 new mode 100755 index c3f501b608..40a03cf45d --- a/module/admin/view/index.html.php +++ b/module/admin/view/index.html.php @@ -11,25 +11,153 @@ */ ?> -
- -
- ' . $lang->admin->notice->ignore, 'hiddenwin', 'class="close" data-dismiss="alert" style="font-size: 12px"');?> -
admin->notice->register, html::a(inlink('register'), $lang->admin->registerNotice->click, '', 'class="alert-link"'));?>
+ +
+
+
+
admin->setting?>
+
+ admin->menuList as $menuKey => $menu):?> + vision == 'lite' and !in_array($menuKey, $config->admin->liteMenuList)) continue;?> +
+ +
+ +
+
+ + +
+
+ admin->pluginRecommendation;?> + admin->extensionURL, "{$lang->more} ", '_blank', 'class="more text-muted flex align-center"');?> +
+
> + + abstract));?> +
+ +

name;?>

+

+
+ +
+
+ + + +
+
+
admin->officialAccount?>
+
+
+
+
+ admin->followUs?> + + + +
+
admin->followUsContent?>
+
+
+
+ +
+
+ admin->publicClass;?> + admin->classURL, "{$lang->more} ", '_blank', 'class="more text-muted flex align-center"');?> +
+ +
+ + +
+
+ + +
+
+
admin->zentaoInfo?>
+
+ admin->zentaoUsed;?> + year):?> + year;?>year;?> + + month):?> + month;?>admin->mon;?> + + day;?>admin->day;?> +
+
+
+
+
admin->updateDynamics?>
+ admin->dynamicURL, "{$lang->more} ", '_blank', 'class="more text-muted flex align-center"');?> +
+ +
+
link, $dynamic->title, '_blank');?>
+
addedDate, 0, 10);?>
+
+ +
+
+
+
admin->updatePatch?>
+ admin->patchURL, "{$lang->more} ", '_blank', 'class="more text-muted flex align-center"');?> +
+ +
+
+
name?>
+ +
+
desc?>
+
+ +
+ edition != 'max'):?> +
+
+
admin->upgradeRecommend?>
+
+ edition != 'biz'):?> +
+ +
admin->bizTag?>
+
admin->productDetail?>
+
+ admin->productFeature['biz'] as $feature):?> +
+ +
+ +
+ +
admin->maxTag?>
+
admin->productDetail?>
+
+ admin->productFeature['max'] as $feature):?> +
+ +
+
+
- -
-

- version; - if(trim($config->visions, ',') == 'lite') $versionName = $lang->liteName . $config->liteVersion; - printf($lang->admin->info->version, $versionName); - if($bind) echo sprintf($lang->admin->info->account, '' . $account . ''); - echo $lang->admin->info->links; - ?> -

-
-
diff --git a/module/admin/view/log.html.php b/module/admin/view/log.html.php old mode 100644 new mode 100755 diff --git a/module/admin/view/register.html.php b/module/admin/view/register.html.php old mode 100644 new mode 100755 diff --git a/module/admin/view/resetpwdsetting.html.php b/module/admin/view/resetpwdsetting.html.php old mode 100644 new mode 100755 index 9159f8aa3e..b2959ec9f1 --- a/module/admin/view/resetpwdsetting.html.php +++ b/module/admin/view/resetpwdsetting.html.php @@ -24,21 +24,19 @@
createLink('admin', 'safe'), $lang->admin->safe->set); - if(common::hasPriv('admin', 'checkWeak')) echo html::a($this->createLink('admin', 'checkWeak'), $lang->admin->safe->checkWeak); - echo html::a($this->createLink('admin', 'resetPWDSetting'), $lang->admin->resetPWDSetting, '', "class='active'"); + if(common::hasPriv('admin', 'safe')) echo html::a($this->createLink('admin', 'safe'), $lang->admin->safe->set); + if(common::hasPriv('admin', 'checkWeak')) echo html::a($this->createLink('admin', 'checkWeak'), $lang->admin->safe->checkWeak); + if(common::hasPriv('admin', 'resetPWDSetting')) echo html::a($this->createLink('admin', 'resetPWDSetting'), $lang->admin->resetPWDSetting, '', "class='active'"); ?>
+
+

admin->resetPWDSetting;?>

+
-
-
- admin->resetPWDSetting;?> -
-
diff --git a/module/admin/view/safe.html.php b/module/admin/view/safe.html.php old mode 100644 new mode 100755 index 08e0478908..071d2cbb1b --- a/module/admin/view/safe.html.php +++ b/module/admin/view/safe.html.php @@ -28,8 +28,8 @@
createLink('admin', 'safe'), $lang->admin->safe->set, '', "class='active'"); - if(common::hasPriv('admin', 'checkWeak')) echo html::a($this->createLink('admin', 'checkWeak'), $lang->admin->safe->checkWeak); + if(common::hasPriv('admin', 'safe')) echo html::a($this->createLink('admin', 'safe'), $lang->admin->safe->set, '', "class='active'"); + if(common::hasPriv('admin', 'checkWeak')) echo html::a($this->createLink('admin', 'checkWeak'), $lang->admin->safe->checkWeak); if(common::hasPriv('admin', 'resetPWDSetting')) echo html::a($this->createLink('admin', 'resetPWDSetting'), $lang->admin->resetPWDSetting); ?>
diff --git a/module/admin/view/setmodule.html.php b/module/admin/view/setmodule.html.php old mode 100644 new mode 100755 index 6e2b53e3e6..de656b2694 --- a/module/admin/view/setmodule.html.php +++ b/module/admin/view/setmodule.html.php @@ -47,7 +47,16 @@ - +
$lang->admin->setModule->{$feature}), $value, "data-code='{$code}'", 'inline');?> diff --git a/module/admin/view/sso.html.php b/module/admin/view/sso.html.php old mode 100644 new mode 100755 diff --git a/module/admin/view/tableengine.html.php b/module/admin/view/tableengine.html.php old mode 100644 new mode 100755 diff --git a/module/admin/view/ztcompany.html.php b/module/admin/view/ztcompany.html.php old mode 100644 new mode 100755 diff --git a/module/backup/lang/zh-cn.php b/module/backup/lang/zh-cn.php index d75db5bfca..e01eed81b3 100644 --- a/module/backup/lang/zh-cn.php +++ b/module/backup/lang/zh-cn.php @@ -1,5 +1,5 @@ backup->common = '系统备份'; +$lang->backup->common = '备份'; $lang->backup->index = '备份首页'; $lang->backup->history = '备份历史'; $lang->backup->delete = '删除备份'; diff --git a/module/block/control.php b/module/block/control.php index 9441c53fcb..b65269bc6c 100755 --- a/module/block/control.php +++ b/module/block/control.php @@ -1101,7 +1101,7 @@ class block extends control /* Get projects. */ $projectID = $this->view->block->module == 'my' ? 0 : (int)$this->session->project; - $executions = $this->loadModel('execution')->getOrderedExecutions($projectID, $status, $count); + $executions = $this->loadModel('execution')->getOrderedExecutions($projectID, $status, $count, 'skipparent'); if(empty($executions)) { $this->view->executions = $executions; diff --git a/module/block/lang/de.php b/module/block/lang/de.php index 068fddbb24..8da269b3dd 100644 --- a/module/block/lang/de.php +++ b/module/block/lang/de.php @@ -10,8 +10,6 @@ * @link http://www.zentao.net */ global $config; -$lang->block = new stdclass(); -$lang->block->common = 'InfoBlock'; $lang->block->id = 'ID'; $lang->block->params = 'Params'; $lang->block->name = 'Name'; @@ -142,6 +140,8 @@ $lang->block->default['waterfall']['project']['6']['block'] = 'projectdynamic'; $lang->block->default['waterfall']['project']['6']['grid'] = 4; $lang->block->default['waterfall']['project']['6']['source'] = 'project'; +$lang->block->default['waterfallplus'] = $lang->block->default['waterfall']; + $lang->block->default['scrum']['project']['1']['title'] = 'Project Overall'; $lang->block->default['scrum']['project']['1']['block'] = 'scrumoverview'; $lang->block->default['scrum']['project']['1']['grid'] = 8; @@ -169,7 +169,8 @@ $lang->block->default['scrum']['project']['4']['grid'] = 4; $lang->block->default['scrum']['project']['5']['title'] = 'Dynamic'; $lang->block->default['scrum']['project']['5']['block'] = 'projectdynamic'; $lang->block->default['scrum']['project']['5']['grid'] = 4; -$lang->block->default['kanban'] = $lang->block->default['scrum']; +$lang->block->default['kanban'] = $lang->block->default['scrum']; +$lang->block->default['agileplus'] = $lang->block->default['scrum']; $lang->block->default['product']['1']['title'] = $lang->productCommon . ' Berichte'; $lang->block->default['product']['1']['block'] = 'statistic'; @@ -375,11 +376,15 @@ $lang->block->modules['scrum']['index']->availableBlocks->sprint = $lang $lang->block->modules['scrum']['index']->availableBlocks->scrumtest = 'Test Version'; $lang->block->modules['scrum']['index']->availableBlocks->projectdynamic = 'Dynamics'; +$lang->block->modules['agileplus']['index'] = $lang->block->modules['scrum']['index']; + $lang->block->modules['waterfall']['index'] = new stdclass(); $lang->block->modules['waterfall']['index']->availableBlocks = new stdclass(); $lang->block->modules['waterfall']['index']->availableBlocks->waterfallgantt = 'Plan Gantt Chart'; $lang->block->modules['waterfall']['index']->availableBlocks->projectdynamic = 'Dynamics'; +$lang->block->modules['waterfallplus']['index'] = $lang->block->modules['waterfall']['index']; + $lang->block->modules['product'] = new stdclass(); $lang->block->modules['product']->availableBlocks = new stdclass(); $lang->block->modules['product']->availableBlocks->statistic = $lang->productCommon . ' Berichte'; diff --git a/module/block/lang/en.php b/module/block/lang/en.php index 5041ff2db0..52ad95e84c 100644 --- a/module/block/lang/en.php +++ b/module/block/lang/en.php @@ -10,8 +10,6 @@ * @link http://www.zentao.net */ global $config; -$lang->block = new stdclass(); -$lang->block->common = 'Block'; $lang->block->id = 'ID'; $lang->block->params = 'Params'; $lang->block->name = 'Name'; @@ -142,6 +140,8 @@ $lang->block->default['waterfall']['project']['6']['block'] = 'projectdynamic'; $lang->block->default['waterfall']['project']['6']['grid'] = 4; $lang->block->default['waterfall']['project']['6']['source'] = 'project'; +$lang->block->default['waterfallplus'] = $lang->block->default['waterfall']; + $lang->block->default['scrum']['project']['1']['title'] = 'Project Overview'; $lang->block->default['scrum']['project']['1']['block'] = 'scrumoverview'; $lang->block->default['scrum']['project']['1']['grid'] = 8; @@ -169,7 +169,8 @@ $lang->block->default['scrum']['project']['4']['grid'] = 4; $lang->block->default['scrum']['project']['5']['title'] = 'Dynamic'; $lang->block->default['scrum']['project']['5']['block'] = 'projectdynamic'; $lang->block->default['scrum']['project']['5']['grid'] = 4; -$lang->block->default['kanban'] = $lang->block->default['scrum']; +$lang->block->default['kanban'] = $lang->block->default['scrum']; +$lang->block->default['agileplus'] = $lang->block->default['scrum']; $lang->block->default['product']['1']['title'] = $lang->productCommon . ' Report'; $lang->block->default['product']['1']['block'] = 'statistic'; @@ -375,11 +376,15 @@ $lang->block->modules['scrum']['index']->availableBlocks->sprint = $lang $lang->block->modules['scrum']['index']->availableBlocks->scrumtest = 'Test Version'; $lang->block->modules['scrum']['index']->availableBlocks->projectdynamic = 'Dynamics'; +$lang->block->modules['agileplus']['index'] = $lang->block->modules['scrum']['index']; + $lang->block->modules['waterfall']['index'] = new stdclass(); $lang->block->modules['waterfall']['index']->availableBlocks = new stdclass(); $lang->block->modules['waterfall']['index']->availableBlocks->waterfallgantt = 'Plan Gantt Chart'; $lang->block->modules['waterfall']['index']->availableBlocks->projectdynamic = 'Dynamics'; +$lang->block->modules['waterfallplus']['index'] = $lang->block->modules['waterfall']['index']; + $lang->block->modules['product'] = new stdclass(); $lang->block->modules['product']->availableBlocks = new stdclass(); $lang->block->modules['product']->availableBlocks->statistic = $lang->productCommon . ' Report'; diff --git a/module/block/lang/fr.php b/module/block/lang/fr.php index ad0415e49c..fa7f693d87 100644 --- a/module/block/lang/fr.php +++ b/module/block/lang/fr.php @@ -10,8 +10,6 @@ * @link http://www.zentao.net */ global $config; -$lang->block = new stdclass(); -$lang->block->common = 'Bloc'; $lang->block->id = 'ID'; $lang->block->params = 'Params'; $lang->block->name = 'Nom'; @@ -142,6 +140,8 @@ $lang->block->default['waterfall']['project']['6']['block'] = 'dynamic'; $lang->block->default['waterfall']['project']['6']['grid'] = 4; $lang->block->default['waterfall']['project']['6']['source'] = ''; +$lang->block->default['waterfallplus'] = $lang->block->default['waterfall']; + $lang->block->default['scrum']['project']['1']['title'] = 'Project Overall'; $lang->block->default['scrum']['project']['1']['block'] = 'scrumoverview'; $lang->block->default['scrum']['project']['1']['grid'] = 8; @@ -169,7 +169,8 @@ $lang->block->default['scrum']['project']['4']['grid'] = 4; $lang->block->default['scrum']['project']['5']['title'] = 'Dynamic'; $lang->block->default['scrum']['project']['5']['block'] = 'projectdynamic'; $lang->block->default['scrum']['project']['5']['grid'] = 4; -$lang->block->default['kanban'] = $lang->block->default['scrum']; +$lang->block->default['kanban'] = $lang->block->default['scrum']; +$lang->block->default['agileplus'] = $lang->block->default['scrum']; $lang->block->default['product']['1']['title'] = ' Rapport de ' . $lang->productCommon; $lang->block->default['product']['1']['block'] = 'statistic'; @@ -375,11 +376,15 @@ $lang->block->modules['scrum']['index']->availableBlocks->sprint = $lang $lang->block->modules['scrum']['index']->availableBlocks->scrumtest = 'Test Version'; $lang->block->modules['scrum']['index']->availableBlocks->projectdynamic = 'Dynamics'; +$lang->block->modules['agileplus']['index'] = $lang->block->modules['scrum']['index']; + $lang->block->modules['waterfall']['index'] = new stdclass(); $lang->block->modules['waterfall']['index']->availableBlocks = new stdclass(); $lang->block->modules['waterfall']['index']->availableBlocks->waterfallgantt = 'Plan Gantt Chart'; $lang->block->modules['waterfall']['index']->availableBlocks->projectdynamic = 'Dynamics'; +$lang->block->modules['waterfallplus']['index'] = $lang->block->modules['waterfall']['index']; + $lang->block->modules['product'] = new stdclass(); $lang->block->modules['product']->availableBlocks = new stdclass(); $lang->block->modules['product']->availableBlocks->statistic = 'Rapport de ' . $lang->productCommon; diff --git a/module/block/lang/vi.php b/module/block/lang/vi.php index f82f02e28e..229e8814e5 100644 --- a/module/block/lang/vi.php +++ b/module/block/lang/vi.php @@ -10,8 +10,6 @@ * @link http://www.zentao.net */ global $config; -$lang->block = new stdclass(); -$lang->block->common = 'Block'; $lang->block->name = 'Tên'; $lang->block->style = 'Kiểu'; $lang->block->grid = 'Vị trí'; diff --git a/module/block/lang/zh-cn.php b/module/block/lang/zh-cn.php index 722868db52..d110b596ca 100644 --- a/module/block/lang/zh-cn.php +++ b/module/block/lang/zh-cn.php @@ -10,8 +10,6 @@ * @link http://www.zentao.net */ global $config; -$lang->block = new stdclass(); -$lang->block->common = '区块'; $lang->block->id = '编号'; $lang->block->params = '参数'; $lang->block->name = '区块名称'; @@ -142,6 +140,8 @@ $lang->block->default['waterfall']['project']['6']['block'] = 'projectdynamic'; $lang->block->default['waterfall']['project']['6']['grid'] = 4; $lang->block->default['waterfall']['project']['6']['source'] = 'project'; +$lang->block->default['waterfallplus'] = $lang->block->default['waterfall']; + $lang->block->default['scrum']['project']['1']['title'] = '项目概况'; $lang->block->default['scrum']['project']['1']['block'] = 'scrumoverview'; $lang->block->default['scrum']['project']['1']['grid'] = 8; @@ -169,7 +169,8 @@ $lang->block->default['scrum']['project']['4']['grid'] = 4; $lang->block->default['scrum']['project']['5']['title'] = '最新动态'; $lang->block->default['scrum']['project']['5']['block'] = 'projectdynamic'; $lang->block->default['scrum']['project']['5']['grid'] = 4; -$lang->block->default['kanban'] = $lang->block->default['scrum']; +$lang->block->default['kanban'] = $lang->block->default['scrum']; +$lang->block->default['agileplus'] = $lang->block->default['scrum']; $lang->block->default['product']['1']['title'] = $lang->productCommon . '统计'; $lang->block->default['product']['1']['block'] = 'statistic'; @@ -375,11 +376,15 @@ $lang->block->modules['scrum']['index']->availableBlocks->sprint = $lang $lang->block->modules['scrum']['index']->availableBlocks->scrumtest = '待测版本'; $lang->block->modules['scrum']['index']->availableBlocks->projectdynamic = '最新动态'; +$lang->block->modules['agileplus']['index'] = $lang->block->modules['scrum']['index']; + $lang->block->modules['waterfall']['index'] = new stdclass(); $lang->block->modules['waterfall']['index']->availableBlocks = new stdclass(); $lang->block->modules['waterfall']['index']->availableBlocks->waterfallgantt = "项目计划"; $lang->block->modules['waterfall']['index']->availableBlocks->projectdynamic = '最新动态'; +$lang->block->modules['waterfallplus']['index'] = $lang->block->modules['waterfall']['index']; + $lang->block->modules['product'] = new stdclass(); $lang->block->modules['product']->availableBlocks = new stdclass(); $lang->block->modules['product']->availableBlocks->statistic = $lang->productCommon . '统计'; diff --git a/module/block/model.php b/module/block/model.php index d5c34f4f36..383315585e 100644 --- a/module/block/model.php +++ b/module/block/model.php @@ -170,7 +170,7 @@ class blockModel extends model ->leftJoin(TABLE_PROJECT)->alias('t2')->on("t1.project = t2.id") ->leftJoin(TABLE_EXECUTION)->alias('t3')->on("t1.execution = t3.id") ->leftJoin(TABLE_TASKTEAM)->alias('t4')->on("t4.task = t1.id and t4.account = '{$this->app->user->account}'") - ->where("(t1.assignedTo = '{$this->app->user->account}' or (t1.mode = 'multi' and t4.`account` = '{$this->app->user->account}') )") + ->where("(t1.assignedTo = '{$this->app->user->account}' or (t1.mode = 'multi' and t4.`account` = '{$this->app->user->account}' and t1.status != 'closed' and t4.status != 'done') )") ->andWhere('(t2.status')->ne('suspended') ->orWhere('t3.status')->ne('suspended') ->markRight(1) diff --git a/module/block/view/executionstatisticblock.html.php b/module/block/view/executionstatisticblock.html.php index e3fdf063db..ff61feb789 100644 --- a/module/block/view/executionstatisticblock.html.php +++ b/module/block/view/executionstatisticblock.html.php @@ -7,17 +7,17 @@ .types-line > li > div:after {content: ''; display: block; background: #FFFFFF; box-shadow: 0 2px 4px 0 rgba(170,170,170,0.50), 0 0 5px 0 rgba(0,0,0,0.1); width: 10px; height: 10px; position: absolute; border-radius: 50%; top: 0; left: 50%; margin-left: -2px;} .types-line > li > div > small {display: block; color: #A6AAB8;} .types-line > li > div > span {display: block; color: #CBD0DB; font-size: 16px;} -.product-info {position: relative; height: 65px;} -.product-info + .product-info {margin-top: 10px;} -.product-info .progress {position: absolute; left: 10px; top: 35px; right: 100px;} -.product-info .progress-info {position: absolute; left: 8px; top: 10px; width: 180px; font-size: 12px;} -.product-info .type-info {color: #A6AAB8; text-align: center; position: absolute; right: 0; top: 6px; width: 100px;} -html[lang="en"] .product-info .type-info {color: #A6AAB8; text-align: center; position: absolute; right: 0; top: 6px; width: 110px;} -.product-info .type-value, -.product-info .type-label {font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;} -.product-info .type-value {font-size: 14px;} -.product-info .type-value > strong {font-size: 20px; color: #3C4353;} -.product-info .actions {position: absolute; left: 10px; top: 14px;} +.execution-info {position: relative; height: 65px;} +.execution-info + .execution-info {margin-top: 10px;} +.execution-info .progress {position: absolute; left: 10px; top: 35px; right: 100px;} +.execution-info .progress-info {position: absolute; left: 8px; top: 10px; width: 180px; font-size: 12px;} +.execution-info .type-info {color: #A6AAB8; text-align: center; position: absolute; right: 0; top: 6px; width: 100px;} +html[lang="en"] .execution-info .type-info {color: #A6AAB8; text-align: center; position: absolute; right: 0; top: 6px; width: 110px;} +.execution-info .type-value, +.execution-info .type-label {font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;} +.execution-info .type-value {font-size: 14px;} +.execution-info .type-value > strong {font-size: 20px; color: #3C4353;} +.execution-info .actions {position: absolute; left: 10px; top: 14px;} .block-statistic .panel-body {padding-top: 0} .block-statistic .tile {margin-bottom: 30px;} .block-statistic .tile-title {font-size: 18px; color: #A6AAB8;} @@ -58,6 +58,7 @@ html[lang="en"] .product-info .type-info {color: #A6AAB8; text-align: center; po .status-count{margin:auto} .status-count tr:first-child td:last-child{color:#000;font-weight:bold} +.block-statistic .execution-progress {vertical-align: middle;} + diff --git a/module/common/view/header.html.php b/module/common/view/header.html.php index 9c26ac3356..caa2c93e2c 100755 --- a/module/common/view/header.html.php +++ b/module/common/view/header.html.php @@ -29,7 +29,8 @@ 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/common/view/kanban.html.php b/module/common/view/kanban.html.php index ff0f8d4fc1..02e883aa1f 100644 --- a/module/common/view/kanban.html.php +++ b/module/common/view/kanban.html.php @@ -21,7 +21,7 @@ #kanbanList .kanban-item.link-block {padding: 0;} #kanbanList .kanban-item.link-block a {padding: 10px; display: block;} #kanbanList .kanban-card {display: flex;} -#kanbanList .kanban-card > .title {white-space: nowrap; overflow: hidden; text-overflow: ellipsis;} +#kanbanList .kanban-card > .title {white-space: nowrap; overflow: hidden;} #kanbanList .kanban-card.has-progress {padding-right: 40px; position: relative;} #kanbanList .kanban-card.has-progress > .progress-pie, #kanbanList .kanban-card.has-progress > .ring {position: absolute; right: 7px; top: 7px; width: 24px; height: 24px;} @@ -48,7 +48,7 @@ #kanbanList .kanban-col[data-type="unclosedProduct"] .kanban-card > .title {white-space: nowrap; line-height: 1;} #kanbanList .kanban-col[data-type="normalRelease"] .kanban-card > .title {display: flex; flex-direction: row; flex-wrap: nowrap; align-items: center;} -#kanbanList .kanban-col[data-type="normalRelease"] .kanban-card > .title > .text {display: block; white-space: nowrap; text-overflow: ellipsis; overflow: hidden;} +#kanbanList .kanban-col[data-type="normalRelease"] .kanban-card > .title > .text {display: block; white-space: nowrap; overflow: hidden;} #kanbanList .kanban-col[data-type="normalRelease"] .kanban-card > .title.has-icon > .text {margin-right: 5px; max-width: calc(100% - 20px);} #kanbanList .no-flex .kanban-col[data-type="normalRelease"] .kanban-card > .title {display: block; height: 38px;} #kanbanList .no-flex .kanban-col[data-type="normalRelease"] .kanban-card > .title > .text {display: inline-block;} diff --git a/module/company/control.php b/module/company/control.php old mode 100644 new mode 100755 index 7ae60d396c..ee554b926c --- a/module/company/control.php +++ b/module/company/control.php @@ -223,15 +223,12 @@ class company extends control /* Get executions' list.*/ $executions = $this->loadModel('execution')->getPairs(0, 'all', 'nocode|multiple'); - $executionsIDList = array_keys($executions); - $executionsList = $this->execution->getByIdList($executionsIDList); - foreach($executionsList as $executionsID => $executionObj) + $executionsList = $this->execution->getByIdList(array_keys($executions)); + foreach($executionsList as $executionID => $execution) { - foreach($projects as $projectsID => $projectsName) - { - if($executionObj->project == $projectsID) $executions[$executionObj->id] = $projectsName . '/' . $executionObj->name; - } + if(isset($projects[$execution->project])) $executions[$execution->id] = $projects[$execution->project] . '/' . $executions[$execution->id]; } + $executions = array($this->lang->execution->common) + $executions; $this->view->executions = $executions; diff --git a/module/convert/view/convertjira.html.php b/module/convert/view/convertjira.html.php index 37a747f2bc..ee55886013 100644 --- a/module/convert/view/convertjira.html.php +++ b/module/convert/view/convertjira.html.php @@ -20,11 +20,6 @@
-
-
-

convert->jira->method;?>

-
-
"> diff --git a/module/custom/config.php b/module/custom/config.php index 6da0127235..5e1fc06856 100644 --- a/module/custom/config.php +++ b/module/custom/config.php @@ -70,3 +70,5 @@ $config->custom->fieldList['testtask'] = 'owner,pri,desc'; $config->custom->fieldList['doc'] = 'keywords,content'; $config->custom->fieldList['user']['create'] = 'dept,role,email,commiter'; $config->custom->fieldList['user']['edit'] = 'dept,role,email,commiter,skype,qq,mobile,phone,address,zipcode,dingding,slack,whatsapp,weixin'; + +$config->custom->notSetMethods = array('required', 'browsestoryconcept', 'product', 'role'); diff --git a/module/custom/control.php b/module/custom/control.php index 111b258ef0..58e1d34591 100644 --- a/module/custom/control.php +++ b/module/custom/control.php @@ -99,12 +99,6 @@ class custom extends control $this->view->forceReview = zget($this->config->$module, 'forceReview', ''); $this->view->forceNotReview = zget($this->config->$module, 'forceNotReview', ''); } - if($module == 'task' and $field == 'hours') - { - $this->app->loadConfig('execution'); - $this->view->weekend = $this->config->execution->weekend; - $this->view->workhours = $this->config->execution->defaultWorkhours; - } if($module == 'bug' and $field == 'longlife') { $this->app->loadConfig('bug'); @@ -190,10 +184,6 @@ class custom extends control $this->testcase->batchReview(array_keys($waitCases), 'pass'); } } - elseif($module == 'task' and $field == 'hours') - { - $this->loadModel('setting')->setItems('system.execution', fixer::input('post')->get()); - } elseif($module == 'bug' and $field == 'longlife') { $this->loadModel('setting')->setItems('system.bug', fixer::input('post')->get()); @@ -382,7 +372,7 @@ class custom extends control $this->view->position[] = $this->lang->custom->required; $this->view->requiredFields = $requiredFields; - $this->view->moduleName = $moduleName; + $this->view->module = $moduleName; $this->display(); } @@ -439,6 +429,7 @@ class custom extends control $this->view->title = $this->lang->custom->browseStoryConcept; $this->view->position[] = $this->lang->custom->browseStoryConcept; $this->view->URSRList = $this->custom->getURSRList(); + $this->view->module = 'product'; $this->display(); } @@ -576,9 +567,10 @@ class custom extends control return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'reload')); } - $this->view->title = $this->lang->custom->product; + $this->view->title = $this->lang->custom->productName; $this->view->position[] = $this->lang->custom->common; $this->view->position[] = $this->view->title; + $this->view->module = 'product'; $this->display(); } @@ -615,7 +607,6 @@ class custom extends control if($_POST) { $this->custom->setConcept(); - $this->loadModel('setting')->setItem('system.custom.URAndSR', $this->post->URAndSR); if($this->config->edition != 'max') $this->loadModel('setting')->setItem('system.custom.hourPoint', $this->post->hourPoint); $this->app->loadLang('common'); @@ -871,4 +862,38 @@ class custom extends control $this->display(); } + + /** + * Set hours and weekend + * + * @access public + * @return void + */ + public function hours($type = 'hours') + { + if($_POST) + { + $data = fixer::input('post')->get(); + $type = $data->type; + + unset($data->type); + if($data->weekend != 1) unset($data->restDay); + + $this->loadModel('setting')->setItems('system.execution', $data); + + $response = new stdclass(); + $response->result = 'success'; + $response->locate = inLink('hours', "type=$type"); + $response->message = $this->lang->saveSuccess; + return $this->send($response); + } + + $this->app->loadConfig('execution'); + $this->view->title = $this->lang->workingHour; + $this->view->type = $type; + $this->view->weekend = $this->config->execution->weekend; + $this->view->workhours = $this->config->execution->defaultWorkhours; + $this->view->restDay = zget($this->config->execution, 'restDay', 0); + $this->display(); + } } diff --git a/module/custom/css/browsestoryconcept.css b/module/custom/css/browsestoryconcept.css index 2f8e5c3424..2a0621cbe2 100644 --- a/module/custom/css/browsestoryconcept.css +++ b/module/custom/css/browsestoryconcept.css @@ -1 +1,7 @@ +.table-form>tbody>tr>th{text-align: center} .c-default {width: 70px;} +.setBtn {margin-top: -5px;} +.px-0 {padding-left: 0; padding-right: 0;} +.pl-20 {padding-left: 20px;} +.pt-5 {padding-top: 5px;} +.box-shadow-none {box-shadow: unset!important;} diff --git a/module/custom/css/common.css b/module/custom/css/common.css index 3c3233d59e..e4d7bf904c 100644 --- a/module/custom/css/common.css +++ b/module/custom/css/common.css @@ -1,2 +1,6 @@ .alert-block {border-top: 1px solid #ddd;} .btn-toolbar.pull-left .divider {margin-left: 0px; border-color: rgba(0,0,0,.2);} +.main-content .main-header {padding: 10px 20px;} +#subNavbar .nav>li>a { padding: 4px 12px;} +#subHeader.admin-tab-menu {margin-bottom: -25px;} +.pl-none {padding-left: 0;} diff --git a/module/custom/js/hours.js b/module/custom/js/hours.js new file mode 100644 index 0000000000..27c93ca508 --- /dev/null +++ b/module/custom/js/hours.js @@ -0,0 +1,16 @@ +$(function() +{ + $("#sidebar .nav [data-toggle='tab']").click(function() + { + $(this).parent().find('a').removeClass('active'); + $(this).addClass('active'); + var type = $(this).hasClass('hours') ? 'hours' : 'weekend'; + $('#type').val(type); + }); + + $('#restDayBox').toggleClass('hidden', $('[name=weekend]:checked').val() != 1) + $('[name=weekend]').change(function() + { + $('#restDayBox').toggleClass('hidden', $(this).val() != 1) + }) +}) diff --git a/module/custom/js/set.js b/module/custom/js/set.js index e6540cd08e..c859aec690 100644 --- a/module/custom/js/set.js +++ b/module/custom/js/set.js @@ -8,12 +8,6 @@ function delItem(clickedButton) $(clickedButton).parent().parent().remove(); } -$(function() -{ - $('#' + module + 'Tab').addClass('btn-active-text'); - $('#' + field + 'Tab').addClass('active'); -}) - $('[name*=unitList]').change(function() { var defaultCurrency = $('#defaultCurrency').val(); diff --git a/module/custom/lang/de.php b/module/custom/lang/de.php index 48e5451d64..c50057573e 100644 --- a/module/custom/lang/de.php +++ b/module/custom/lang/de.php @@ -22,7 +22,7 @@ $lang->custom->score = 'Score'; $lang->custom->timezone = 'Timezone'; $lang->custom->scoreReset = 'Reset Score'; $lang->custom->scoreTitle = 'Point Feature'; -$lang->custom->product = $lang->productCommon; +$lang->custom->productName = $lang->productCommon; $lang->custom->convertFactor = 'Convert factor'; $lang->custom->region = 'Interval'; $lang->custom->tips = 'Tips'; @@ -89,49 +89,22 @@ $lang->custom->closedExecution = 'Closed ' . $lang->executionCommon; $lang->custom->closedKanban = 'Closed ' . $lang->custom->kanban; $lang->custom->closedProduct = 'Closed ' . $lang->productCommon; -$lang->custom->object['project'] = 'Project'; -$lang->custom->object['product'] = $lang->productCommon; -$lang->custom->object['execution'] = $lang->custom->execution; -$lang->custom->object['kanban'] = $lang->custom->kanban; -$lang->custom->object['story'] = 'Story'; -$lang->custom->object['task'] = 'Task'; -$lang->custom->object['bug'] = 'Bug'; -$lang->custom->object['testcase'] = 'Case'; -$lang->custom->object['testtask'] = 'Build'; -$lang->custom->object['todo'] = 'Todo'; -$lang->custom->object['user'] = 'User'; -$lang->custom->object['block'] = 'ClosedBlock'; -$lang->custom->object['flow'] = 'Flow'; -$lang->custom->object['score'] = 'Score'; -$lang->custom->object['mode'] = 'Mode'; - -$lang->custom->menuOrder[5] = 'project'; -$lang->custom->menuOrder[10] = 'product'; -$lang->custom->menuOrder[15] = 'execution'; -$lang->custom->menuOrder[20] = 'kanban'; -$lang->custom->menuOrder[25] = 'story'; -$lang->custom->menuOrder[30] = 'task'; -$lang->custom->menuOrder[35] = 'bug'; -$lang->custom->menuOrder[40] = 'testcase'; -$lang->custom->menuOrder[45] = 'testtask'; -$lang->custom->menuOrder[50] = 'todo'; -$lang->custom->menuOrder[55] = 'user'; -$lang->custom->menuOrder[60] = 'block'; -$lang->custom->menuOrder[65] = 'flow'; -$lang->custom->menuOrder[70] = 'score'; - -$lang->custom->dividerMenu = ',story,todo,block,'; -$lang->custom->separatePage = ',execution,product,kanban,flow,score,'; - $lang->custom->block = new stdclass(); $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(); +$lang->custom->product->fields['required'] = $lang->custom->required; +$lang->custom->product->fields['browsestoryconcept'] = 'Story Concpet'; +$lang->custom->product->fields['product'] = 'Close Setting'; + $lang->custom->story = new stdClass(); +$lang->custom->story->fields['required'] = $lang->custom->required; $lang->custom->story->fields['categoryList'] = 'Category'; $lang->custom->story->fields['priList'] = 'Priority'; $lang->custom->story->fields['sourceList'] = 'Source'; @@ -143,13 +116,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'; @@ -160,6 +134,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'; @@ -168,16 +143,24 @@ $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'; $lang->custom->todo->fields['statusList'] = 'Status'; $lang->custom->user = new stdClass(); +$lang->custom->user->fields['required'] = $lang->custom->required; $lang->custom->user->fields['roleList'] = 'Role'; $lang->custom->user->fields['statusList'] = 'Status'; $lang->custom->user->fields['contactField'] = 'Available Contact'; @@ -232,10 +215,15 @@ $lang->custom->reviewList[0] = 'Off'; $lang->custom->deletedList[1] = 'Show'; $lang->custom->deletedList[0] = 'Hide'; +$lang->custom->setHours = 'Setting Hours'; +$lang->custom->setWeekend = 'Setting Weekend'; +$lang->custom->setHoliday = 'Setting Holiday'; $lang->custom->workingHours = 'hours/day'; -$lang->custom->weekend = 'Weekend'; -$lang->custom->weekendList[2] = '2-Day Off'; +$lang->custom->weekendRole = 'Role'; $lang->custom->weekendList[1] = '1-Day Off'; +$lang->custom->weekendList[2] = '2-Day Off'; +$lang->custom->restDayList[6] = 'Saturday rest'; +$lang->custom->restDayList[0] = 'Sunday rest'; global $config; $lang->custom->sprintConceptList[0] = 'Program Product Iteration'; diff --git a/module/custom/lang/en.php b/module/custom/lang/en.php index b572c5e132..b650794ae8 100644 --- a/module/custom/lang/en.php +++ b/module/custom/lang/en.php @@ -22,7 +22,7 @@ $lang->custom->score = 'Point'; $lang->custom->timezone = 'Timezone'; $lang->custom->scoreReset = 'Reset Points'; $lang->custom->scoreTitle = 'Point Feature'; -$lang->custom->product = $lang->productCommon; +$lang->custom->productName = $lang->productCommon; $lang->custom->convertFactor = 'Convert factor'; $lang->custom->region = 'Interval'; $lang->custom->tips = 'Tips'; @@ -89,49 +89,22 @@ $lang->custom->closedExecution = 'Closed ' . $lang->executionCommon; $lang->custom->closedKanban = 'Closed ' . $lang->custom->kanban; $lang->custom->closedProduct = 'Closed ' . $lang->productCommon; -$lang->custom->object['project'] = 'Project'; -$lang->custom->object['product'] = $lang->productCommon; -$lang->custom->object['execution'] = $lang->custom->execution; -$lang->custom->object['kanban'] = $lang->custom->kanban; -$lang->custom->object['story'] = 'Story'; -$lang->custom->object['task'] = 'Task'; -$lang->custom->object['bug'] = 'Bug'; -$lang->custom->object['testcase'] = 'Case'; -$lang->custom->object['testtask'] = 'Request'; -$lang->custom->object['todo'] = 'Todo'; -$lang->custom->object['user'] = 'User'; -$lang->custom->object['block'] = 'Block'; -$lang->custom->object['flow'] = 'Flow'; -$lang->custom->object['score'] = 'Score'; -$lang->custom->object['mode'] = 'Mode'; - -$lang->custom->menuOrder[5] = 'project'; -$lang->custom->menuOrder[10] = 'product'; -$lang->custom->menuOrder[15] = 'execution'; -$lang->custom->menuOrder[20] = 'kanban'; -$lang->custom->menuOrder[25] = 'story'; -$lang->custom->menuOrder[30] = 'task'; -$lang->custom->menuOrder[35] = 'bug'; -$lang->custom->menuOrder[40] = 'testcase'; -$lang->custom->menuOrder[45] = 'testtask'; -$lang->custom->menuOrder[50] = 'todo'; -$lang->custom->menuOrder[55] = 'user'; -$lang->custom->menuOrder[60] = 'block'; -$lang->custom->menuOrder[65] = 'flow'; -$lang->custom->menuOrder[70] = 'score'; - -$lang->custom->dividerMenu = ',story,todo,block,'; -$lang->custom->separatePage = ',execution,product,kanban,flow,score,'; - $lang->custom->block = new stdclass(); $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(); +$lang->custom->product->fields['required'] = $lang->custom->required; +$lang->custom->product->fields['browsestoryconcept'] = 'Story Concpet'; +$lang->custom->product->fields['product'] = 'Close Setting'; + $lang->custom->story = new stdClass(); +$lang->custom->story->fields['required'] = $lang->custom->required; $lang->custom->story->fields['categoryList'] = 'Category'; $lang->custom->story->fields['priList'] = 'Priority'; $lang->custom->story->fields['sourceList'] = 'Source'; @@ -143,13 +116,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'; @@ -160,6 +134,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'; @@ -168,16 +143,24 @@ $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'; $lang->custom->todo->fields['statusList'] = 'Status'; $lang->custom->user = new stdClass(); +$lang->custom->user->fields['required'] = $lang->custom->required; $lang->custom->user->fields['roleList'] = 'Role'; $lang->custom->user->fields['statusList'] = 'Status'; $lang->custom->user->fields['contactField'] = 'Available Contact'; @@ -232,10 +215,15 @@ $lang->custom->reviewList[0] = 'Off'; $lang->custom->deletedList[1] = 'Show'; $lang->custom->deletedList[0] = 'Hide'; +$lang->custom->setHours = 'Setting Hours'; +$lang->custom->setWeekend = 'Setting Weekend'; +$lang->custom->setHoliday = 'Setting Holiday'; $lang->custom->workingHours = 'Hours/Day'; -$lang->custom->weekend = 'Weekend'; -$lang->custom->weekendList[2] = '2-Day Off'; +$lang->custom->weekendRole = 'Role'; $lang->custom->weekendList[1] = '1-Day Off'; +$lang->custom->weekendList[2] = '2-Day Off'; +$lang->custom->restDayList[6] = 'Saturday rest'; +$lang->custom->restDayList[0] = 'Sunday rest'; global $config; $lang->custom->sprintConceptList[0] = 'Program Product Iteration'; diff --git a/module/custom/lang/fr.php b/module/custom/lang/fr.php index a84f90bd4e..6b6be4b13d 100644 --- a/module/custom/lang/fr.php +++ b/module/custom/lang/fr.php @@ -22,7 +22,7 @@ $lang->custom->score = 'Point'; $lang->custom->timezone = 'Timezone'; $lang->custom->scoreReset = 'Réinit Points'; $lang->custom->scoreTitle = 'Fonctionnalité des Points'; -$lang->custom->product = $lang->productCommon; +$lang->custom->productName = $lang->productCommon; $lang->custom->convertFactor = 'Convert factor'; $lang->custom->region = 'Interval'; $lang->custom->tips = 'Tips'; @@ -89,49 +89,22 @@ $lang->custom->closedExecution = 'Closed ' . $lang->executionCommon; $lang->custom->closedKanban = 'Closed ' . $lang->custom->kanban; $lang->custom->closedProduct = 'Closed ' . $lang->productCommon; -$lang->custom->object['project'] = 'Project'; -$lang->custom->object['product'] = $lang->productCommon; -$lang->custom->object['execution'] = $lang->custom->execution; -$lang->custom->object['kanban'] = $lang->custom->kanban; -$lang->custom->object['story'] = 'Story'; -$lang->custom->object['task'] = 'Tâche'; -$lang->custom->object['bug'] = 'Bug'; -$lang->custom->object['testcase'] = 'CasTest'; -$lang->custom->object['testtask'] = 'Build'; -$lang->custom->object['todo'] = 'Agenda'; -$lang->custom->object['user'] = 'Utilisateur'; -$lang->custom->object['block'] = 'Bloc'; -$lang->custom->object['flow'] = 'Flow'; -$lang->custom->object['score'] = 'Score'; -$lang->custom->object['mode'] = 'Mode'; - -$lang->custom->menuOrder[5] = 'project'; -$lang->custom->menuOrder[10] = 'product'; -$lang->custom->menuOrder[15] = 'execution'; -$lang->custom->menuOrder[20] = 'kanban'; -$lang->custom->menuOrder[25] = 'story'; -$lang->custom->menuOrder[30] = 'task'; -$lang->custom->menuOrder[35] = 'bug'; -$lang->custom->menuOrder[40] = 'testcase'; -$lang->custom->menuOrder[45] = 'testtask'; -$lang->custom->menuOrder[50] = 'todo'; -$lang->custom->menuOrder[55] = 'user'; -$lang->custom->menuOrder[60] = 'block'; -$lang->custom->menuOrder[65] = 'flow'; -$lang->custom->menuOrder[70] = 'score'; - -$lang->custom->dividerMenu = ',story,todo,block,'; -$lang->custom->separatePage = ',execution,product,kanban,flow,score,'; - $lang->custom->block = new stdclass(); $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(); +$lang->custom->product->fields['required'] = $lang->custom->required; +$lang->custom->product->fields['browsestoryconcept'] = 'Story Concpet'; +$lang->custom->product->fields['product'] = 'Close Setting'; + $lang->custom->story = new stdClass(); +$lang->custom->story->fields['required'] = $lang->custom->required; $lang->custom->story->fields['categoryList'] = 'Category'; $lang->custom->story->fields['priList'] = 'Priorité'; $lang->custom->story->fields['sourceList'] = 'Source'; @@ -143,13 +116,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'; @@ -160,6 +134,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'; @@ -168,16 +143,24 @@ $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'; $lang->custom->todo->fields['statusList'] = 'Statut'; $lang->custom->user = new stdClass(); +$lang->custom->user->fields['required'] = $lang->custom->required; $lang->custom->user->fields['roleList'] = 'Rôle'; $lang->custom->user->fields['statusList'] = 'Statut'; $lang->custom->user->fields['contactField'] = 'Contact'; @@ -232,10 +215,15 @@ $lang->custom->reviewList[0] = 'Off'; $lang->custom->deletedList[1] = 'Montrer'; $lang->custom->deletedList[0] = 'Cacher'; +$lang->custom->setHours = 'Setting Hours'; +$lang->custom->setWeekend = 'Setting Weekend'; +$lang->custom->setHoliday = 'Setting Holiday'; $lang->custom->workingHours = 'Heures/Jour'; -$lang->custom->weekend = 'Weekend'; -$lang->custom->weekendList[2] = '2-Jour'; +$lang->custom->weekendRole = 'Role'; $lang->custom->weekendList[1] = '1-Jour'; +$lang->custom->weekendList[2] = '2-Jour'; +$lang->custom->restDayList[6] = 'Saturday rest'; +$lang->custom->restDayList[0] = 'Sunday rest'; global $config; $lang->custom->sprintConceptList[0] = 'Program Product Iteration'; diff --git a/module/custom/lang/zh-cn.php b/module/custom/lang/zh-cn.php index 689e8daeaf..8571ef1a50 100644 --- a/module/custom/lang/zh-cn.php +++ b/module/custom/lang/zh-cn.php @@ -8,7 +8,7 @@ $lang->custom->set = '自定义配置'; $lang->custom->restore = '恢复默认'; $lang->custom->key = '键'; $lang->custom->value = '值'; -$lang->custom->flow = '流程'; +$lang->custom->flow = '流程设置'; $lang->custom->working = '工作方式'; $lang->custom->select = '请选择流程:'; $lang->custom->branch = '多分支'; @@ -22,7 +22,7 @@ $lang->custom->score = '积分'; $lang->custom->timezone = '时区'; $lang->custom->scoreReset = '重置积分'; $lang->custom->scoreTitle = '积分功能'; -$lang->custom->product = $lang->productCommon; +$lang->custom->productName = $lang->productCommon; $lang->custom->convertFactor = '换算系数'; $lang->custom->region = '区间'; $lang->custom->tips = '提示语'; @@ -89,49 +89,22 @@ $lang->custom->closedExecution = '已关闭' . $lang->custom->execution; $lang->custom->closedKanban = '已关闭' . $lang->custom->kanban; $lang->custom->closedProduct = '已关闭' . $lang->productCommon; -$lang->custom->object['project'] = '项目'; -$lang->custom->object['product'] = $lang->productCommon; -$lang->custom->object['execution'] = $lang->custom->execution; -$lang->custom->object['kanban'] = $lang->custom->kanban; -$lang->custom->object['story'] = $lang->SRCommon; -$lang->custom->object['task'] = '任务'; -$lang->custom->object['bug'] = 'Bug'; -$lang->custom->object['testcase'] = '用例'; -$lang->custom->object['testtask'] = '测试单'; -$lang->custom->object['todo'] = '待办'; -$lang->custom->object['user'] = '用户'; -$lang->custom->object['block'] = '区块'; -$lang->custom->object['flow'] = '流程'; -$lang->custom->object['score'] = '积分'; -$lang->custom->object['mode'] = '模式'; - -$lang->custom->menuOrder[5] = 'project'; -$lang->custom->menuOrder[10] = 'product'; -$lang->custom->menuOrder[15] = 'execution'; -$lang->custom->menuOrder[20] = 'kanban'; -$lang->custom->menuOrder[25] = 'story'; -$lang->custom->menuOrder[30] = 'task'; -$lang->custom->menuOrder[35] = 'bug'; -$lang->custom->menuOrder[40] = 'testcase'; -$lang->custom->menuOrder[45] = 'testtask'; -$lang->custom->menuOrder[50] = 'todo'; -$lang->custom->menuOrder[55] = 'user'; -$lang->custom->menuOrder[60] = 'block'; -$lang->custom->menuOrder[65] = 'flow'; -$lang->custom->menuOrder[70] = 'score'; - -$lang->custom->dividerMenu = ',story,todo,block,'; -$lang->custom->separatePage = ',execution,product,kanban,flow,score'; - $lang->custom->block = new stdclass(); $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(); +$lang->custom->product->fields['required'] = $lang->custom->required; +$lang->custom->product->fields['browsestoryconcept'] = '需求概念'; +$lang->custom->product->fields['product'] = '关闭设置'; + $lang->custom->story = new stdClass(); +$lang->custom->story->fields['required'] = $lang->custom->required; $lang->custom->story->fields['categoryList'] = '类型'; $lang->custom->story->fields['priList'] = '优先级'; $lang->custom->story->fields['sourceList'] = '来源'; @@ -143,13 +116,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'] = '操作系统'; @@ -160,6 +134,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'] = '阶段'; @@ -168,16 +143,24 @@ $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'] = '类型'; $lang->custom->todo->fields['statusList'] = '状态'; $lang->custom->user = new stdClass(); +$lang->custom->user->fields['required'] = $lang->custom->required; $lang->custom->user->fields['roleList'] = '职位'; $lang->custom->user->fields['statusList'] = '状态'; $lang->custom->user->fields['contactField'] = '可用联系方式'; @@ -232,10 +215,15 @@ $lang->custom->reviewList[0] = '关闭'; $lang->custom->deletedList[1] = '列出'; $lang->custom->deletedList[0] = '不列出'; +$lang->custom->setHours = '工时设置'; +$lang->custom->setWeekend = '休息日设置'; +$lang->custom->setHoliday = '节假日设置'; $lang->custom->workingHours = '每天可用工时'; -$lang->custom->weekend = '休息日'; -$lang->custom->weekendList[2] = '双休'; +$lang->custom->weekendRole = '规则设置'; $lang->custom->weekendList[1] = '单休'; +$lang->custom->weekendList[2] = '双休'; +$lang->custom->restDayList[6] = '周六休息'; +$lang->custom->restDayList[0] = '周天休息'; global $config; $lang->custom->sprintConceptList[0] = '项目 产品 迭代'; diff --git a/module/custom/model.php b/module/custom/model.php index debea8d153..0f4fed2cf1 100644 --- a/module/custom/model.php +++ b/module/custom/model.php @@ -239,6 +239,7 @@ class customModel extends model $dropMenu = ''; $alias = ''; $exclude = ''; + $divider = false; $link = (is_array($item) and isset($item['link'])) ? $item['link'] : $item; /* The variable of item has not link and is not link then ignore it. */ @@ -293,6 +294,7 @@ class customModel extends model if(isset($item['dropMenu'])) $dropMenu = $item['dropMenu']; if(isset($item['alias'])) $alias = $item['alias']; if(isset($item['exclude'])) $exclude = $item['exclude']; + if(isset($item['divider'])) $divider = $item['divider']; } $hidden = isset($customMenuMap[$name]) && isset($customMenuMap[$name]->hidden) && $customMenuMap[$name]->hidden; @@ -333,6 +335,7 @@ class customModel extends model if($dropMenu) $menuItem->dropMenu = $dropMenu; if($alias) $menuItem->alias = $alias; if($exclude) $menuItem->exclude = $exclude; + if($divider) $menuItem->divider = $divider; if($isTutorialMode) $menuItem->tutorial = true; /* Hidden menu by config in mobile. */ @@ -369,7 +372,7 @@ class customModel extends model else { $isFirst = false; - $menu[$item->order]->divider = false; + if(!isset($menu[$item->order]->divider))$menu[$item->order]->divider = false; } } diff --git a/module/custom/view/browsestoryconcept.html.php b/module/custom/view/browsestoryconcept.html.php index 26f56c0546..45f86fa9e1 100644 --- a/module/custom/view/browsestoryconcept.html.php +++ b/module/custom/view/browsestoryconcept.html.php @@ -9,49 +9,50 @@ * @version $Id: browsestoryconcept.html.php 4129 2020-09-01 01:58:14Z sgm $ */ ?> - - - +getModuleRoot() . 'common/view/header.html.php';?>
-
-
admin->resetPWDByMail;?>
- - - - - - config->URAndSR):?> - - - - - - - - $URSR):?> - - - - - config->URAndSR):?> - - - - - - - -
custom->default;?> custom->URConcept;?> custom->SRConcept;?> actions;?>
custom->URSR) echo 'checked';?>> - custom->URSR ? "disabled=disabled" : '';?> - createLink('custom', 'editStoryConcept', "id=$key", '', true), "", '', "class='btn iframe' data-width=" . ($this->config->URAndSR ? "480px" : "330px") . " title={$lang->edit}");?> - createLink('custom', 'deleteStoryConcept', "id=$key"), "", 'hiddenwin', "class='btn' $disabled title={$lang->delete} data-group='admin'");?> -
+ +
+
+
+ custom->product->fields['browsestoryconcept']?> +
+
+ createLink('custom', 'setstoryconcept', '', '', true), $lang->custom->setStoryConcept, '', "class='btn btn-primary iframe' data-width=" . ($this->config->URAndSR ? "590px" : "405px"));?> +
+
+ + + + + + + config->URAndSR):?> + + + + + + + + $URSR):?> + + + + + config->URAndSR):?> + + + + + + + +
custom->default;?> custom->URConcept;?> custom->SRConcept;?> actions;?>
custom->URSR) echo 'checked';?>> + custom->URSR ? "disabled=disabled" : '';?> + createLink('custom', 'editStoryConcept', "id=$key", '', true), "", '', "class='btn iframe' data-width=" . ($this->config->URAndSR ? "480px" : "330px") . " title={$lang->edit}");?> + createLink('custom', 'deleteStoryConcept', "id=$key"), "", 'hiddenwin', "class='btn' $disabled title={$lang->delete} data-group='admin'");?> +
diff --git a/module/custom/view/score.html.php b/module/custom/view/score.html.php index 009069baaf..8b2fab81e2 100644 --- a/module/custom/view/score.html.php +++ b/module/custom/view/score.html.php @@ -9,7 +9,7 @@ * @link http://www.zentao.net */ ?> - +getModuleRoot() . 'common/view/header.html.php';?>
diff --git a/module/custom/view/set.html.php b/module/custom/view/set.html.php index a12203ac11..36a1d46c66 100644 --- a/module/custom/view/set.html.php +++ b/module/custom/view/set.html.php @@ -10,7 +10,7 @@ * @link http://www.zentao.net */ ?> - +getModuleRoot() . 'common/view/header.html.php';?> @@ -28,14 +28,14 @@ $itemRow = << EOT; ?> + custom->notice->confirmReviewCase)?> -
- +
- custom->object[$module] . $lang->arrow . $lang->custom->$module->fields[$field]?> + custom->$module->fields[$field]?>
@@ -152,21 +141,6 @@ EOT; - - - - - - - - - - - - - - -
custom->workingHours;?>
custom->weekend;?>custom->weekendList, $weekend);?>
diff --git a/module/custom/view/sidebar.html.php b/module/custom/view/sidebar.html.php new file mode 100644 index 0000000000..763619ed35 --- /dev/null +++ b/module/custom/view/sidebar.html.php @@ -0,0 +1,36 @@ +custom->{$module}->fields)):?> + + diff --git a/module/custom/view/working.html.php b/module/custom/view/working.html.php deleted file mode 100644 index 4c8caed0e8..0000000000 --- a/module/custom/view/working.html.php +++ /dev/null @@ -1,35 +0,0 @@ - - * @package custom - * @version $Id$ - * @link http://www.zentao.net - */ -?> - -
- -
-
- custom->working?> -
-
-
- - - - - -
custom->working;?> - global->flow) ? $config->global->flow : 'full';?> - custom->workingList as $key => $value):?> -

- -
- -
- diff --git a/module/datatable/control.php b/module/datatable/control.php index b9be09f43f..f8c2189559 100644 --- a/module/datatable/control.php +++ b/module/datatable/control.php @@ -128,6 +128,7 @@ class datatable extends control if(!$execution->hasProduct and !$execution->multiple) unset($cols['plan']); if(!$execution->hasProduct) unset($cols['branch']); } + if($extra == 'unsetStory' and isset($cols['story'])) unset($cols['story']); $this->view->cols = $cols; $this->view->setting = $setting; diff --git a/module/datatable/view/ajaxcustom.html.php b/module/datatable/view/ajaxcustom.html.php index 1dfaac9f6e..e3a36c661f 100644 --- a/module/datatable/view/ajaxcustom.html.php +++ b/module/datatable/view/ajaxcustom.html.php @@ -62,8 +62,8 @@
$col):?>
' data-key='' data-fixed='' data-width=''> diff --git a/module/dept/lang/de.php b/module/dept/lang/de.php index c729943c3a..5aa9a45c15 100644 --- a/module/dept/lang/de.php +++ b/module/dept/lang/de.php @@ -9,7 +9,6 @@ * @version $Id: en.php 4129 2013-01-18 01:58:14Z wwccss $ * @link http://www.zentao.net */ -$lang->dept->common = 'Abteilung'; $lang->dept->id = 'ID'; $lang->dept->path = 'Path'; $lang->dept->position = 'Position'; diff --git a/module/dept/lang/en.php b/module/dept/lang/en.php index 030947e19b..51d714190c 100644 --- a/module/dept/lang/en.php +++ b/module/dept/lang/en.php @@ -9,7 +9,6 @@ * @version $Id: en.php 4129 2013-01-18 01:58:14Z wwccss $ * @link http://www.zentao.net */ -$lang->dept->common = 'Department'; $lang->dept->id = 'ID'; $lang->dept->path = 'Path'; $lang->dept->position = 'Position'; diff --git a/module/dept/lang/fr.php b/module/dept/lang/fr.php index a37f31d364..4b75de3faf 100644 --- a/module/dept/lang/fr.php +++ b/module/dept/lang/fr.php @@ -9,7 +9,6 @@ * @version $Id: en.php 4129 2013-01-18 01:58:14Z wwccss $ * @link http://www.zentao.net */ -$lang->dept->common = 'Compartiments'; $lang->dept->id = 'ID'; $lang->dept->path = 'Path'; $lang->dept->position = 'Position'; diff --git a/module/dept/lang/zh-cn.php b/module/dept/lang/zh-cn.php index 5ae59fdaee..ea92254f6e 100644 --- a/module/dept/lang/zh-cn.php +++ b/module/dept/lang/zh-cn.php @@ -9,7 +9,6 @@ * @version $Id: zh-cn.php 4129 2013-01-18 01:58:14Z wwccss $ * @link http://www.zentao.net */ -$lang->dept->common = '部门结构'; $lang->dept->id = '编号'; $lang->dept->path = '路径'; $lang->dept->position = '职位'; diff --git a/module/dept/view/browse.html.php b/module/dept/view/browse.html.php index 345eff97a5..93861a70cb 100644 --- a/module/dept/view/browse.html.php +++ b/module/dept/view/browse.html.php @@ -12,11 +12,6 @@ ?> dept->repeatDepart);?> -
diff --git a/module/dev/view/api.html.php b/module/dev/view/api.html.php index de48267908..3bdb9b80a8 100644 --- a/module/dev/view/api.html.php +++ b/module/dev/view/api.html.php @@ -10,7 +10,7 @@ disableFeature and in_array($module, $config->disableFeature)) continue; - $active = ($module == $selectedModule) ? 'active' : ''; + $active = ($module == $selectedModule) ? 'text-primary' : ''; $moduleName = zget($lang->dev->tableList, $module, $module); ?> @@ -22,7 +22,7 @@
dev->tableList, $module, $module); ?> diff --git a/module/dev/view/db.html.php b/module/dev/view/db.html.php index 2b6869b38a..7380771867 100644 --- a/module/dev/view/db.html.php +++ b/module/dev/view/db.html.php @@ -9,7 +9,7 @@
$table):?> dev->tableList, $subTable, ''); ?> @@ -21,7 +21,7 @@
$table):?> dev->tableList, $subTable, ''); ?> diff --git a/module/doc/config.php b/module/doc/config.php index dd5ec6214c..1d3d7bf145 100644 --- a/module/doc/config.php +++ b/module/doc/config.php @@ -9,8 +9,8 @@ $config->doc->edit = new stdclass(); $config->doc->createlib->requiredFields = 'name'; $config->doc->editlib->requiredFields = 'name'; -$config->doc->create->requiredFields = 'lib,title'; -$config->doc->edit->requiredFields = 'title'; +$config->doc->create->requiredFields = 'lib,title'; +$config->doc->edit->requiredFields = 'title'; $config->doc->customObjectLibs = 'files,customFiles'; $config->doc->notArticleType = ''; diff --git a/module/doc/control.php b/module/doc/control.php index 4b6e8bfd5e..62a201ffee 100755 --- a/module/doc/control.php +++ b/module/doc/control.php @@ -158,6 +158,12 @@ class doc extends control { if($execution->multiple) { + if($execution->type == 'stage' and $execution->grade > 1) + { + $parentExecutions = $this->dao->select('id,name')->from(TABLE_EXECUTION)->where('id')->in(trim($execution->path, ','))->andWhere('type')->in('stage,kanban,sprint')->orderBy('grade')->fetchPairs(); + $execution->name = implode('/', $parentExecutions); + } + $executionPrefix = isset($projects[$execution->project]) ? $projects[$execution->project] . '/' : ''; $executions[$executionID] = $executionPrefix . $execution->name; } @@ -240,7 +246,16 @@ class doc extends control if(!empty($lib->execution)) { $execution = $this->execution->getByID($lib->execution); - if($execution->type == 'stage') $this->lang->doc->execution = str_replace($this->lang->executionCommon, $this->lang->project->stage, $this->lang->doc->execution); + if($execution->type == 'stage') + { + if($execution->grade > 1) + { + $parentExecutions = $this->dao->select('id,name')->from(TABLE_EXECUTION)->where('id')->in(trim($execution->path, ','))->andWhere('type')->in('stage,kanban,sprint')->orderBy('grade')->fetchPairs(); + $execution->name = implode('/', $parentExecutions); + } + + $this->lang->doc->execution = str_replace($this->lang->executionCommon, $this->lang->project->stage, $this->lang->doc->execution); + } $this->view->execution = $execution; } diff --git a/module/doc/js/createbasicinfo.js b/module/doc/js/createbasicinfo.js index 978b76ccdd..45a770f6d8 100644 --- a/module/doc/js/createbasicinfo.js +++ b/module/doc/js/createbasicinfo.js @@ -8,6 +8,12 @@ $(function() $('#saveBtn').click(function() { + var requiredArr = ['lib', 'title', 'keywords']; + for(var i = 0; i < 3; i++) + { + if(requiredFields.indexOf(',' + requiredArr[i] + ',') != -1 && !$('#' + requiredArr[i]).val().trim()) return alert(eval(requiredArr[i] + 'NotEmpty')); + } + var params = $('#dataform').serializeArray(); sessionStorage.setItem('docBasicInfo', JSON.stringify(params)); diff --git a/module/doc/model.php b/module/doc/model.php index 014e17e4d0..c0e038bf34 100644 --- a/module/doc/model.php +++ b/module/doc/model.php @@ -116,13 +116,14 @@ class docModel extends model { if(strpos($extra, 'withObject') !== false) { - if($lib->product != 0) $lib->name = zget($products, $lib->product, '') . ' / ' . $lib->name; - if($lib->project != 0) $lib->name = zget($projects, $lib->project, '') . ' / ' . $lib->name; if($lib->execution != 0) { $lib->name = zget($executions, $lib->execution, '') . ' / ' . $lib->name; if(!empty($waterfalls[$lib->execution])) $lib->name = $waterfalls[$lib->execution] . ' / ' . $lib->name; + $lib->name = trim($lib->name, '/'); } + if($lib->product != 0) $lib->name = zget($products, $lib->product, '') . ' / ' . $lib->name; + if($lib->project != 0) $lib->name = zget($projects, $lib->project, '') . ' / ' . $lib->name; } $libPairs[$lib->id] = $lib->name; @@ -1580,6 +1581,11 @@ class docModel extends model $orderedExecutions = array(); foreach($executions as $id => $execution) { + if($execution->type == 'stage' and $execution->grade != 1) + { + $parentExecutions = $this->dao->select('id,name')->from(TABLE_EXECUTION)->where('id')->in(trim($execution->path, ','))->andWhere('type')->in('stage,kanban,sprint')->orderBy('grade')->fetchPairs(); + $execution->name = implode('/', $parentExecutions); + } $execution->name = zget($projectPairs, $execution->project) . ' / ' . $execution->name; if($execution->status != 'done' and $execution->status != 'closed' and $execution->PM == $this->app->user->account) diff --git a/module/doc/view/createbasicinfo.html.php b/module/doc/view/createbasicinfo.html.php index c862c46ffc..d63a34c128 100644 --- a/module/doc/view/createbasicinfo.html.php +++ b/module/doc/view/createbasicinfo.html.php @@ -13,6 +13,10 @@ doc->placeholder);?> +doc->create->requiredFields . ',');?> +error->notempty, $lang->doc->lib));?> +error->notempty, $lang->doc->title));?> +error->notempty, $lang->doc->keywords));?>
@@ -40,7 +44,8 @@ doc->keywords;?> - doc->keywordsTips}'");?> + doc->create->requiredFields},", ',keywords,') !== false ? 'required' : '';?> + doc->keywordsTips}'");?> doc->type;?> diff --git a/module/doc/view/createtexttype.html.php b/module/doc/view/createtexttype.html.php index 06df09278a..6a97b23c1a 100644 --- a/module/doc/view/createtexttype.html.php +++ b/module/doc/view/createtexttype.html.php @@ -15,6 +15,9 @@ doc->placeholder);?> +doc->create->requiredFields . ',');?> +error->notempty, $lang->doc->lib));?> +error->notempty, $lang->doc->keywords));?> + + +lifetime == 'ops' or in_array($execution->attribute, array('request', 'review'))):?> +