diff --git a/module/common/lang/menu.php b/module/common/lang/menu.php index d5a9edadfd..2f7e394f50 100644 --- a/module/common/lang/menu.php +++ b/module/common/lang/menu.php @@ -215,7 +215,7 @@ $lang->scrum->menu->devops = array('link' => "{$lang->repo->common}|repo|br $lang->scrum->menu->build = array('link' => "{$lang->build->common}|project|build|project=%s", 'subModule' => 'projectbuild'); $lang->scrum->menu->release = array('link' => "{$lang->release->common}|projectrelease|browse|project=%s", 'subModule' => 'projectrelease'); $lang->scrum->menu->dynamic = array('link' => "$lang->dynamic|project|dynamic|project=%s"); -$lang->scrum->menu->settings = array('link' => "$lang->settings|project|view|project=%s", 'subModule' => 'tree,stakeholder', 'alias' => 'edit,manageproducts,group,managemembers,manageview,managepriv,whitelist,addwhitelist,team,managerepo'); +$lang->scrum->menu->settings = array('link' => "$lang->settings|project|view|project=%s", 'subModule' => 'tree,stakeholder', 'alias' => 'edit,manageproducts,group,managemembers,manageview,managepriv,whitelist,addwhitelist,team,managerepo', 'exclude' => 'tree-browsetask'); $lang->scrum->menu->storyGroup['dropMenu'] = new stdclass(); $lang->scrum->menu->storyGroup['dropMenu']->story = array('link' => "{$lang->SRCommon}|projectstory|story|projectID=%s&productID=%s", 'subModule' => 'projectstory,tree'); @@ -253,7 +253,7 @@ $lang->scrum->menu->settings['subMenu']->members = array('link' => "{$lang-> $lang->scrum->menu->settings['subMenu']->whitelist = array('link' => "{$lang->whitelist}|project|whitelist|project=%s", 'subModule' => 'personnel'); $lang->scrum->menu->settings['subMenu']->stakeholder = array('link' => "{$lang->stakeholder->common}|stakeholder|browse|project=%s", 'subModule' => 'stakeholder'); $lang->scrum->menu->settings['subMenu']->group = array('link' => "{$lang->priv}|project|group|project=%s", 'alias' => 'group,manageview,managepriv'); -$lang->scrum->menu->settings['subMenu']->module = array('link' => "{$lang->module}|tree|browse|product=%s&view=story", 'subModule' => 'tree'); +$lang->scrum->menu->settings['subMenu']->module = array('link' => "{$lang->module}|tree|browse|product=%s&view=story"); $lang->scrum->menu->settings['subMenu']->managerepo = array('link' => "{$lang->repo->codeRepo}|project|managerepo|project=%s"); /* Waterfall menu. */ @@ -343,7 +343,7 @@ $lang->execution->menu->view = array('link' => "$lang->view|execution|grouptas if($config->edition != 'open') $lang->execution->menu->view = array('link' => "$lang->view|execution|gantt|executionID=%s", 'alias' => 'grouptask,tree,taskeffort,gantt,calendar,relation,maintainrelation'); $lang->execution->menu->storyGroup = array('link' => "{$lang->common->story}|execution|story|executionID=%s",'class' => 'dropdown dropdown-hover', 'subModule' => 'story', 'alias' => 'batchcreate,storykanban'); -$lang->execution->menu->story = array('link' => "$lang->SRCommon|execution|story|executionID=%s", 'subModule' => 'story', 'alias' => 'storykanban'); +$lang->execution->menu->story = array('link' => "$lang->SRCommon|execution|story|executionID=%s", 'subModule' => 'story', 'alias' => 'storykanban,linkstory'); $lang->execution->menu->qa = array('link' => "{$lang->qa->common}|execution|bug|executionID=%s", 'subModule' => 'bug,testcase,testtask,testreport', 'alias' => 'qa,bug,testcase,testtask,testreport'); $lang->execution->menu->devops = array('link' => "{$lang->repo->common}|repo|browse|repoID=0&branchID=&objectID=%s", 'subModule' => 'repo'); $lang->execution->menu->doc = array('link' => "{$lang->doc->common}|doc|tableContents|type=execution&objectID=%s", 'subModule' => 'doc'); diff --git a/module/execution/control.php b/module/execution/control.php index 7e5db92d26..36171420e7 100644 --- a/module/execution/control.php +++ b/module/execution/control.php @@ -180,7 +180,7 @@ class execution extends control /* Save to session. */ $uri = $this->app->getURI(true); - $this->app->session->set('taskList', $uri, 'execution'); + $this->app->session->set('taskList', $uri . "#app={$this->app->tab}", 'execution'); /* Process the order by field. */ if(!$orderBy) $orderBy = $this->cookie->executionTaskOrder ? $this->cookie->executionTaskOrder : 'status,id_desc'; @@ -685,12 +685,12 @@ class execution extends control unset($this->config->bug->search['fields']['resolvedDate']); unset($this->config->bug->search['fields']['closedDate']); unset($this->config->bug->search['fields']['branch']); + if(empty($execution->multiple) && empty($execution->hasProduct)) unset($this->config->bug->search['fields']['plan']); if(empty($project->hasProduct)) { unset($this->config->bug->search['fields']['product']); if($project->model !== 'scrum') unset($this->config->bug->search['fields']['plan']); } - unset($this->config->bug->search['params']['resolvedBy']); unset($this->config->bug->search['params']['closedBy']); unset($this->config->bug->search['params']['status']); @@ -1844,7 +1844,7 @@ class execution extends control $this->view->code = $code; $this->view->team = $team; $this->view->teams = array(0 => '') + $this->execution->getCanCopyObjects((int)$projectID); - $this->view->allProjects = array(0 => '') + $this->project->getPairsByModel('all', 0, 'noclosed|multiple'); + $this->view->allProjects = array(0 => '') + $this->project->getPairsByModel('all', 0, 'noclosed,multiple'); $this->view->copyProjects = $copyProjects; $this->view->copyExecutions = array('' => '') + $this->execution->getList($copyProjectID); $this->view->executionID = $executionID; diff --git a/module/execution/lang/de.php b/module/execution/lang/de.php index 29c7ef95cb..ee29d08f90 100644 --- a/module/execution/lang/de.php +++ b/module/execution/lang/de.php @@ -345,6 +345,7 @@ $lang->execution->wbs = "Aufgaben aufteilen"; $lang->execution->batchWBS = "Mehrere aufteilen"; $lang->execution->howToUpdateBurn = "Hilfe "; $lang->execution->whyNoStories = "Keine Story kann verknüpft werden. Bitte prüfen Sie ob ein Story mit {$lang->executionCommon} verknüpft ist {$lang->productCommon} und stellen Sie sicher das diese geprüft ist."; +$lang->execution->projectNoStories = "No story can be linked. Please check whether there is any story in project and make sure it has been reviewed."; $lang->execution->productStories = "{$lang->executionCommon} verknüpfte Story ist ein Subset von {$lang->productCommon}, welche nur nach überprüfung verknüpft werden kann. Bitte Story verknüpfen。"; $lang->execution->haveDraft = "There are %s draft stories can't be linked."; $lang->execution->doneExecutions = 'Erledigt'; diff --git a/module/execution/lang/en.php b/module/execution/lang/en.php index 5c7d8daf50..276311554f 100644 --- a/module/execution/lang/en.php +++ b/module/execution/lang/en.php @@ -345,6 +345,7 @@ $lang->execution->wbs = "Create Task"; $lang->execution->batchWBS = "Batch Create Tasks"; $lang->execution->howToUpdateBurn = "Help "; $lang->execution->whyNoStories = "No story can be linked. Please check whether there is any story in {$lang->executionCommon} which is linked to {$lang->productCommon} and make sure it has been reviewed."; +$lang->execution->projectNoStories = "No story can be linked. Please check whether there is any story in project and make sure it has been reviewed."; $lang->execution->productStories = "Stories linked to {$lang->executionCommon} are the subeset of stories linked to {$lang->productCommon}. Stories can only be linked after they pass the review. Link Stories now."; $lang->execution->haveDraft = "%s stories in draft, so they can't be linked."; $lang->execution->doneExecutions = 'Finished'; diff --git a/module/execution/lang/fr.php b/module/execution/lang/fr.php index 3da5b42ffa..40c1dd6f2f 100644 --- a/module/execution/lang/fr.php +++ b/module/execution/lang/fr.php @@ -345,6 +345,7 @@ $lang->execution->wbs = "Créer Tâche"; $lang->execution->batchWBS = "Créer Tâche en lot"; $lang->execution->howToUpdateBurn = "Mise à jour "; $lang->execution->whyNoStories = "Aucune story ne peut être associée. Vérifiez s'il existe des stories dans {$lang->executionCommon} qui sont associées à {$lang->productCommon} et vérifiez qu'elles ont bien été validées."; +$lang->execution->projectNoStories = "No story can be linked. Please check whether there is any story in project and make sure it has been reviewed."; $lang->execution->productStories = "Les stories associées au {$lang->executionCommon} sont une portion des stories associées au {$lang->productCommon}. Les stories ne peuvent être associées à un {$lang->executionCommon} qu'après avoir été validées. Associer Stories maintenant."; $lang->execution->haveDraft = "%s stories sont encore en conception, elles ne peuvent pas être associées au {$lang->executionCommon} actuellement."; $lang->execution->doneExecutions = 'Terminé'; diff --git a/module/execution/lang/vi.php b/module/execution/lang/vi.php index 9d3885c16a..bd77c671f5 100644 --- a/module/execution/lang/vi.php +++ b/module/execution/lang/vi.php @@ -281,6 +281,7 @@ $lang->execution->wbs = "Tạo nhiệm vụ"; $lang->execution->batchWBS = "Tạo nhiệm vụ hàng loạt"; $lang->execution->howToUpdateBurn = "Giúp"; $lang->execution->whyNoStories = "Không có câu chuyện có thể liên kết. Vui lòng kiểm tra có câu chuyện trong {$lang->executionCommon} cái liên kết tới {$lang->productCommon} và chắc chắn nó đã được duyệt."; +$lang->execution->projectNoStories = "No story can be linked. Please check whether there is any story in project and make sure it has been reviewed."; $lang->execution->productStories = "Câu chuyện liên kết tới {$lang->executionCommon} là tập hợp con của câu chuyện liên kết tới {$lang->productCommon}. Các câu chuyện chỉ có thể liên kết sau khi chúng đã được duyệt. Liên kết câu chuyện now."; $lang->execution->haveDraft = "%s câu chuyện đang nháp, bởi vậy chúng không thể liên kết."; $lang->execution->doneExecutions = 'Kết thúc'; diff --git a/module/execution/lang/zh-cn.php b/module/execution/lang/zh-cn.php index 77f79dff1f..a11a6923d4 100644 --- a/module/execution/lang/zh-cn.php +++ b/module/execution/lang/zh-cn.php @@ -345,6 +345,7 @@ $lang->execution->wbs = "分解任务"; $lang->execution->batchWBS = "批量分解"; $lang->execution->howToUpdateBurn = "帮助 "; $lang->execution->whyNoStories = "看起来没有{$lang->SRCommon}可以关联。请检查下{$lang->executionCommon}关联的{$lang->productCommon}中有没有{$lang->SRCommon},而且要确保它们已经审核通过。"; +$lang->execution->projectNoStories = "看起来没有{$lang->SRCommon}可以关联。请检查下项目中有没有{$lang->SRCommon},而且要确保它们已经审核通过。"; $lang->execution->productStories = "{$lang->executionCommon}关联的{$lang->SRCommon}是{$lang->productCommon}{$lang->SRCommon}的子集,并且只有评审通过的{$lang->SRCommon}才能关联。请关联{$lang->SRCommon}。"; $lang->execution->haveDraft = "有%s条草稿状态的{$lang->SRCommon}无法关联到该执行"; $lang->execution->doneExecutions = '已结束'; diff --git a/module/execution/view/build.html.php b/module/execution/view/build.html.php index e1c014cd0d..c1610c1616 100644 --- a/module/execution/view/build.html.php +++ b/module/execution/view/build.html.php @@ -51,7 +51,6 @@ build->id;?> build->product;?> build->name;?> - build->product;?> build->scmPath;?> build->filePath;?> build->date;?> @@ -69,7 +68,6 @@ branchName) echo "{$build->branchName}"?> createLink('build', 'view', "build=$build->id"), $build->name);?> - productName;?> scmPath, 'http') === 0 ? html::a($build->scmPath) : $build->scmPath;?> filePath, 'http') === 0 ? html::a($build->filePath) : $build->filePath;?> date?> diff --git a/module/execution/view/kanban.html.php b/module/execution/view/kanban.html.php index c51bd5fcdd..7c036b443d 100644 --- a/module/execution/view/kanban.html.php +++ b/module/execution/view/kanban.html.php @@ -74,7 +74,7 @@ $canBatchCreateBug = ($productID and common::hasPriv('bug', 'batchCreate') and $canImportBug = ($productID and common::hasPriv('execution', 'importBug')); $canCreateStory = ($productID and common::hasPriv('story', 'create')); $canBatchCreateStory = ($productID and common::hasPriv('story', 'batchCreate')); -$canLinkStory = ($productID and common::hasPriv('execution', 'linkStory')); +$canLinkStory = ($productID and common::hasPriv('execution', 'linkStory') and !empty($execution->hasProduct)); $canLinkStoryByPlan = ($productID and common::hasPriv('execution', 'importplanstories') and !empty($project->hasProduct)); $hasStoryButton = ($canCreateStory or $canBatchCreateStory or $canLinkStory or $canLinkStoryByPlan); $hasTaskButton = ($canCreateTask or $canBatchCreateTask or $canImportBug); diff --git a/module/execution/view/linkstory.html.php b/module/execution/view/linkstory.html.php index dccd6cc427..05e7db5875 100644 --- a/module/execution/view/linkstory.html.php +++ b/module/execution/view/linkstory.html.php @@ -105,7 +105,8 @@
-

{$app->rawModule}->whyNoStories;?>

+ rawModule == 'execution' and !$project->hasProduct) ? 'projectNoStories' : 'whyNoStories';?> +

{$app->rawModule}->{$emptyTips};?>

diff --git a/module/execution/view/story.html.php b/module/execution/view/story.html.php index 88c6ecc9d7..e6883a207a 100644 --- a/module/execution/view/story.html.php +++ b/module/execution/view/story.html.php @@ -81,7 +81,7 @@ if($productID) common::printIcon('story', 'report', "productID=$productID&branchID=&storyType=$storyType&browseType=$type&moduleID=$param&chartType=pie&projectID=$execution->id", '', 'button', 'bar-chart muted'); common::printLink('story', 'export', "productID=$productID&orderBy=id_desc&executionID=$execution->id&browseType=$type&storyType=$storyType", " " . $lang->story->export, '', "class='btn btn-link export iframe'"); - $canLinkStory = $execution->hasProduct or $execution->multiple; + $canLinkStory = $execution->multiple; if(common::canModify('execution', $execution)) { $this->lang->story->create = $this->lang->execution->createStory; diff --git a/module/execution/view/taskkanban.html.php b/module/execution/view/taskkanban.html.php index 5cb87219fe..a4c48dbb19 100644 --- a/module/execution/view/taskkanban.html.php +++ b/module/execution/view/taskkanban.html.php @@ -90,8 +90,8 @@ $canImportBug = ($productID and common::hasPriv('execution', 'importBug')); $canCreateStory = ($productID and common::hasPriv('story', 'create')); $canBatchCreateStory = ($productID and common::hasPriv('story', 'batchCreate')); - $canLinkStory = ($productID and common::hasPriv('execution', 'linkStory')); - $canLinkStoryByPlan = ($productID and common::hasPriv('execution', 'importplanstories') and !$hiddenPlan); + $canLinkStory = ($productID and common::hasPriv('execution', 'linkStory') and !empty($execution->hasProduct)); + $canLinkStoryByPlan = ($productID and common::hasPriv('execution', 'importplanstories') and !$hiddenPlan and !empty($execution->hasProduct)); $hasStoryButton = ($canCreateStory or $canBatchCreateStory or $canLinkStory or $canLinkStoryByPlan); $hasTaskButton = ($canCreateTask or $canBatchCreateTask or $canImportBug); $hasBugButton = ($canCreateBug or $canBatchCreateBug); diff --git a/module/kanban/control.php b/module/kanban/control.php index 4479d6883d..1070aef18e 100644 --- a/module/kanban/control.php +++ b/module/kanban/control.php @@ -1378,7 +1378,7 @@ class kanban extends control $this->app->loadClass('pager', $static = true); $pager = new pager($recTotal, $recPerPage, $pageID); - $this->view->projects = array($this->lang->kanban->allProjects) + $this->project->getPairsByProgram(); + $this->view->projects = array($this->lang->kanban->allProjects) + $this->project->getPairsByProgram('', 'all', false, '', '', '', 'multiple'); $this->view->selectedProjectID = $selectedProjectID; $this->view->lanePairs = $this->kanban->getLanePairsByGroup($groupID); $this->view->executions2Imported = $this->execution->getStatData($selectedProjectID, 'undone', 0, 0, false, '', 'id_asc', $pager); diff --git a/module/misc/lang/de.php b/module/misc/lang/de.php index e892681bf2..70525fda4d 100644 --- a/module/misc/lang/de.php +++ b/module/misc/lang/de.php @@ -47,8 +47,8 @@ $lang->misc->zentao->cowin['feedback'] = "Feedback"; $lang->misc->zentao->cowin['recommend'] = "More"; $lang->misc->zentao->service['zentaotrain'] = 'ZenTao Training'; -$lang->misc->zentao->service['idc'] = 'Zentao Cloud'; -$lang->misc->zentao->service['custom'] = 'Zentao Custom'; +$lang->misc->zentao->service['idc'] = 'ZenTao Cloud'; +$lang->misc->zentao->service['custom'] = 'ZenTao Custom'; global $config; $lang->misc->zentao->others['chanzhi'] = " Zsite"; @@ -100,7 +100,7 @@ $lang->misc->feature->close = 'Close'; $lang->misc->feature->downloadFile = 'Download introduction'; $lang->misc->feature->tutorialDesc = '

ZenTao 15.0 has new functions, and you know how to use it through the "Tutorial".

Click your [Avatar-Theme-Young Blue] to set it.

'; $lang->misc->feature->themeDesc = '

ZenTao 15.0+ a new "Youth Blue" theme, the pages are more beautiful and the experience is more friendly.

Click your [Avatar-Theme-Young Blue] to set it.

'; -$lang->misc->feature->visionsDesc = "

The concept of interface has been added since 16.5. Users can deal with R & D affairs in [R&D] and daily office affairs in [Lite].

You can view the current interface on the avatar, and click the name of the interface to view and switch other interfaces.

"; +$lang->misc->feature->visionsDesc = "

The concept of interface has been added since 16.5. Users can deal with R&D affairs in [Full Feature Interface] and daily office affairs in [Operation Management Interface].

You can view the current interface on the avatar, and click the name of the interface to view and switch other interfaces.

"; $lang->misc->feature->visionsImage = 'theme/default/images/main/visions_en.png'; $lang->misc->releaseDate['17.8'] = '2022-11-02'; @@ -225,7 +225,7 @@ $lang->misc->feature->all['15.0.3'][] = array('title' => 'Fix Bug', 'desc' $lang->misc->feature->all['15.0.2'][] = array('title' => 'Fix Bug', 'desc' => ''); $lang->misc->feature->all['15.0.1'][] = array('title' => 'Fix Bug', 'desc' => ''); $lang->misc->feature->all['15.0'][] = array('title' => 'Fix Bug', 'desc' => ''); -$lang->misc->feature->all['15.0.rc3'][] = array('title' => 'Adjust details,Fix bug', 'desc' => ''); +$lang->misc->feature->all['15.0.rc3'][] = array('title' => 'Adjust details, fix bug.', 'desc' => ''); $lang->misc->feature->all['15.0.rc2'][] = array('title' => 'Fix Bug.', 'desc' => ''); $lang->misc->feature->all['15.0.rc1'][] = array('title' => 'Upgrade to 15,reframe menu, add program.', 'desc' => ''); $lang->misc->feature->all['12.5.3'][] = array('title' => 'Adjust annual data.', 'desc' => ''); diff --git a/module/misc/lang/en.php b/module/misc/lang/en.php index b63f934519..fb0e92e185 100644 --- a/module/misc/lang/en.php +++ b/module/misc/lang/en.php @@ -100,7 +100,7 @@ $lang->misc->feature->close = 'Close'; $lang->misc->feature->downloadFile = 'Download introduction'; $lang->misc->feature->tutorialDesc = '

ZenTao 15.0 has new functions, and you know how to use it through the "Tutorial".

Click your [Avatar-Theme-Young Blue] to set it.

'; $lang->misc->feature->themeDesc = '

ZenTao 15.0+ a new "Youth Blue" theme, the pages are more beautiful and the experience is more friendly.

Click your [Avatar-Theme-Young Blue] to set it.

'; -$lang->misc->feature->visionsDesc = "

The concept of interface has been added since 16.5. Users can deal with R & D affairs in [R&D] and daily office affairs in [Lite].

You can view the current interface on the avatar, and click the name of the interface to view and switch other interfaces.

"; +$lang->misc->feature->visionsDesc = "

The concept of interface has been added since 16.5. Users can deal with R&D affairs in [Full Feature Interface] and daily office affairs in [Operation Management Interface].

You can view the current interface on the avatar, and click the name of the interface to view and switch other interfaces.

"; $lang->misc->feature->visionsImage = 'theme/default/images/main/visions_en.png'; $lang->misc->releaseDate['17.8'] = '2022-11-02'; @@ -223,9 +223,9 @@ $lang->misc->feature->all['15.2'][] = array('title' => 'Optimize the new v $lang->misc->feature->all['15.0.3'][] = array('title' => 'Fix Bug', 'desc' => ''); $lang->misc->feature->all['15.0.2'][] = array('title' => 'Fix Bug', 'desc' => ''); -$lang->misc->feature->all['15.0.1'][] = array('title' => 'Fix bug', 'desc' => ''); -$lang->misc->feature->all['15.0'][] = array('title' => 'Fix bug', 'desc' => ''); -$lang->misc->feature->all['15.0.rc3'][] = array('title' => 'Adjust details,Fix bug', 'desc' => ''); +$lang->misc->feature->all['15.0.1'][] = array('title' => 'Fix Bug', 'desc' => ''); +$lang->misc->feature->all['15.0'][] = array('title' => 'Fix Bug', 'desc' => ''); +$lang->misc->feature->all['15.0.rc3'][] = array('title' => 'Adjust details, fix bug.', 'desc' => ''); $lang->misc->feature->all['15.0.rc2'][] = array('title' => 'Fix Bug.', 'desc' => ''); $lang->misc->feature->all['15.0.rc1'][] = array('title' => 'Upgrade to 15,reframe menu, add program.', 'desc' => ''); $lang->misc->feature->all['12.5.3'][] = array('title' => 'Adjust annual data.', 'desc' => ''); diff --git a/module/misc/lang/fr.php b/module/misc/lang/fr.php index 0bc2366d43..7b47d01dc1 100644 --- a/module/misc/lang/fr.php +++ b/module/misc/lang/fr.php @@ -47,8 +47,8 @@ $lang->misc->zentao->cowin['feedback'] = "Feedback"; $lang->misc->zentao->cowin['recommend'] = "Plus..."; $lang->misc->zentao->service['zentaotrain'] = 'ZenTao Training'; -$lang->misc->zentao->service['idc'] = 'Zentao Cloud'; -$lang->misc->zentao->service['custom'] = 'Zentao Custom'; +$lang->misc->zentao->service['idc'] = 'ZenTao Cloud'; +$lang->misc->zentao->service['custom'] = 'ZenTao Custom'; global $config; $lang->misc->zentao->others['chanzhi'] = " Zsite"; @@ -100,7 +100,7 @@ $lang->misc->feature->close = 'Close'; $lang->misc->feature->downloadFile = 'Download introduction'; $lang->misc->feature->tutorialDesc = '

ZenTao 15.0 has new functions, and you know how to use it through the "Tutorial".

Click your [Avatar-Theme-Young Blue] to set it.

'; $lang->misc->feature->themeDesc = '

ZenTao 15.0+ a new "Youth Blue" theme, the pages are more beautiful and the experience is more friendly.

Click your [Avatar-Theme-Young Blue] to set it.

'; -$lang->misc->feature->visionsDesc = "

The concept of interface has been added since 16.5. Users can deal with R & D affairs in [R&D] and daily office affairs in [Lite].

You can view the current interface on the avatar, and click the name of the interface to view and switch other interfaces.

"; +$lang->misc->feature->visionsDesc = "

The concept of interface has been added since 16.5. Users can deal with R&D affairs in [Full Feature Interface] and daily office affairs in [Operation Management Interface].

You can view the current interface on the avatar, and click the name of the interface to view and switch other interfaces.

"; $lang->misc->feature->visionsImage = 'theme/default/images/main/visions_en.png'; $lang->misc->releaseDate['17.8'] = '2022-11-02'; diff --git a/module/misc/lang/zh-cn.php b/module/misc/lang/zh-cn.php index d5b2ef9cc6..f9dcacc66a 100644 --- a/module/misc/lang/zh-cn.php +++ b/module/misc/lang/zh-cn.php @@ -100,7 +100,7 @@ $lang->misc->feature->close = '关闭'; $lang->misc->feature->downloadFile = '下载新版本功能介绍文档'; $lang->misc->feature->tutorialDesc = "

禅道15系列新增了多项功能,您可以通过“新手引导教程”快速了解禅道的基本使用方法。

通过鼠标经过 [头像-新手引导],点击新手引导,即可进入新手引导教程。

"; $lang->misc->feature->themeDesc = "

禅道15系列上线了全新的“青春蓝”主题,页面呈现更加美观,体验更加友好。

通过鼠标经过 [头像-主题-青春蓝],点击青春蓝,即可设置成功。

"; -$lang->misc->feature->visionsDesc = "

从16.5开始增加了界面概念,用户可以在[研发综合界面]中处理研发事务、在[迅捷界面]处理日常办公事务。

在头像右侧即可查看当前所处界面,点击当前界面名称可查看和切换其他的界面。

"; +$lang->misc->feature->visionsDesc = "

从16.5开始增加了界面概念,用户可以在[研发综合界面]中处理研发事务、在[运营管理界面]处理日常办公事务。

在头像右侧即可查看当前所处界面,点击当前界面名称可查看和切换其他的界面。

"; $lang->misc->feature->visionsImage = 'theme/default/images/main/visions.png'; $lang->misc->releaseDate['17.8'] = '2022-11-02'; diff --git a/module/my/model.php b/module/my/model.php index 926ec8e9a9..3a432a791d 100644 --- a/module/my/model.php +++ b/module/my/model.php @@ -1301,6 +1301,7 @@ class myModel extends model $review->time = $action->date; $review->result = strtolower($action->extra); $review->status = $objectType == 'attend' ? $object->reviewStatus : $object->status; + if(strpos($review->result, ',') !== false) list($review->result) = explode(',', $review->result); if($review->type == 'review') $review->type = 'project'; if($review->type == 'case') $review->type = 'testcase'; diff --git a/module/my/view/task.html.php b/module/my/view/task.html.php index 64caf5f5e8..950103d321 100644 --- a/module/my/view/task.html.php +++ b/module/my/view/task.html.php @@ -104,15 +104,16 @@ ' title='name?>'> team)) echo '' . $this->lang->task->multipleAB . ' ';?> executionMultiple) ? 'project' : 'execution'; if($task->parent > 0) { - echo '' . $this->lang->task->childrenAB . ' ' . html::a($this->createLink('task', 'view', "taskID=$task->id", '', '', $task->project), $task->parentName . ' / '. $task->name, '', "title='{$task->parentName} / {$task->name}'"); + echo '' . $this->lang->task->childrenAB . ' ' . html::a($this->createLink('task', 'view', "taskID=$task->id", '', '', $task->project), $task->parentName . ' / '. $task->name, '', "title='{$task->parentName} / {$task->name}' data-app='$dataApp'"); } else { $onlybody = $task->executionType == 'kanban' ? true : ''; $class = $task->executionType == 'kanban' ? 'iframe' : ''; - echo html::a($this->createLink('task', 'view', "taskID=$task->id", '', $onlybody, $task->project), $task->name, null, "class='$class' data-width='80%' style='color: $task->color'"); + echo html::a($this->createLink('task', 'view', "taskID=$task->id", '', $onlybody, $task->project), $task->name, null, "class='$class' data-width='80%' style='color: $task->color' data-app='$dataApp'"); } ?> children)) echo '';?> @@ -189,8 +190,9 @@ id);?> + executionMultiple) ? 'project' : 'execution';?> parent > 0) echo '' . $this->lang->task->childrenAB . ' ';?> - createLink('task', 'view', "taskID=$child->id", '', '', $child->project), $child->name, null, "style='color: $child->color'");?> + createLink('task', 'view', "taskID=$child->id", '', '', $child->project), $child->name, null, "style='color: $child->color' data-app='$dataApp'");?> pri;?>' title='task->priList, $child->pri);?>'>task->priList, $child->pri);?> diff --git a/module/program/model.php b/module/program/model.php index 393556a4ef..9ee3ab4e0e 100644 --- a/module/program/model.php +++ b/module/program/model.php @@ -67,10 +67,11 @@ class programModel extends model * @param string $status all|noclosed * @param string|array $append * @param string|int $shadow all | 0 | 1 + * @param bool $withProgram * @access public * @return array */ - public function getProductPairs($programID = 0, $mode = 'assign', $status = 'all', $append = '', $shadow = 0) + public function getProductPairs($programID = 0, $mode = 'assign', $status = 'all', $append = '', $shadow = 0, $withProgram = false) { /* Get the top programID. */ if($programID) @@ -84,72 +85,40 @@ class programModel extends model if(!empty($append) and is_array($append)) $append = implode(',', $append); $views = empty($append) ? $this->app->user->view->products : $this->app->user->view->products . ",$append"; - return $this->dao->select('*')->from(TABLE_PRODUCT) + $dao = $this->dao->select('id, name, program')->from(TABLE_PRODUCT) ->where('deleted')->eq(0) ->andWhere('vision')->eq($this->config->vision) ->beginIF($shadow !== 'all')->andWhere('shadow')->eq((int)$shadow)->fi() ->beginIF($mode == 'assign')->andWhere('program')->eq($programID)->fi() ->beginIF(strpos($status, 'noclosed') !== false)->andWhere('status')->ne('closed')->fi() - ->beginIF(!$this->app->user->admin)->andWhere('id')->in($views)->fi() - ->fetchPairs('id', 'name'); - } + ->beginIF(!$this->app->user->admin)->andWhere('id')->in($views)->fi(); - /** - * Get product pairs which name with program. - * - * @param int $programID - * @param string $mode - * @param string $status - * @param string $append - * @param int $shadow - * @access public - * @return array - */ - public function getProductPairsWithProgram($programID = 0, $mode = 'assign', $status = 'all', $append = '', $shadow = 0) - { - /* Get the top programID. */ - if($programID) - { - $program = $this->getByID($programID); - $path = array_filter(explode(',', $program->path)); - $programID = current($path); - } + if(!$withProgram) return $dao->fetchPairs('id', 'name'); - /* When mode equals assign and programID equals 0, you can query the standalone product. */ - if(!empty($append) and is_array($append)) $append = implode(',', $append); - $views = empty($append) ? $this->app->user->view->products : $this->app->user->view->products . ",$append"; - - $products = $this->dao->select("t1.id, t1.program, CONCAT(IF(t2.name IS NOT NULL, t2.name, ''), '/', t1.name) AS name")->from(TABLE_PRODUCT)->alias('t1') - ->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.program = t2.id') - ->where('t1.deleted')->eq('0') - ->andWhere('t1.vision')->eq($this->config->vision) - ->beginIF($shadow !== 'all')->andWhere('t1.shadow')->eq((int)$shadow)->fi() - ->beginIF($mode == 'assign')->andWhere('t1.program')->eq($programID)->fi() - ->beginIF(strpos($status, 'noclosed') !== false)->andWhere('t1.status')->ne('closed')->fi() - ->beginIF(!$this->app->user->admin)->andWhere('t1.id')->in($views)->fi() - ->orderBy('t1.program, t1.order_asc') - ->fetchGroup('program'); + $products = $dao->orderBy('program,order')->fetchGroup('program'); + $productPrograms = $this->dao->select('id, name')->from(TABLE_PROJECT)->where('type')->eq('program')->andWhere('deleted')->eq('0')->fetchPairs(); /* Put products of current program first.*/ if($mode != 'assign' && $programID) { $currentProgramProducts = $products[$programID]; - unset($products[$programID]); - array_unshift($products, $currentProgramProducts); } $productPairs = array(); foreach($products as $programProducts) { - foreach($programProducts as $product) $productPairs[$product->id] = $product->name; + foreach($programProducts as $product) + { + $programName = zget($productPrograms, $product->program, '') . '/'; + $productPairs[$product->id] = $programName . $product->name; + } } return $productPairs; } - /** * Get program by id. * diff --git a/module/project/control.php b/module/project/control.php index 0d712bdd9a..a316d3233c 100755 --- a/module/project/control.php +++ b/module/project/control.php @@ -283,7 +283,8 @@ class project extends control if($objectType == 'program') { - $allProducts = array(0 => '') + $this->program->getProductPairsWithProgram($selectedProgramID, 'all', 'noclosed'); + $withProgram = $this->config->systemMode == 'ALM' ? true : false; + $allProducts = array(0 => '') + $this->program->getProductPairs($selectedProgramID, 'all', 'noclosed', '', 0, $withProgram); $data['allProducts'] = html::select("products[]", $allProducts, '', "class='form-control chosen' onchange='loadBranches(this)'"); $data['plans'] = html::select('plans[][][]', '', '', 'class=\'form-control chosen\' multiple'); } @@ -603,13 +604,16 @@ class project extends control $this->config->executionCommonList[$this->app->getClientLang()][0] : $this->config->executionCommonList[$this->app->getClientLang()][1]; + $withProgram = $this->config->systemMode == 'ALM' ? true : false; + $allProducts = array('0' => '') + $this->program->getProductPairs($programID, 'all', 'noclosed', '', $shadow, $withProgram); + $this->view->title = $this->lang->project->create; $this->view->gobackLink = (isset($output['from']) and $output['from'] == 'global') ? $this->createLink('project', 'browse') : ''; $this->view->pmUsers = $this->loadModel('user')->getPairs('noclosed|nodeleted|pmfirst'); $this->view->users = $this->user->getPairs('noclosed|nodeleted'); $this->view->copyProjects = $this->project->getPairsByModel($model); $this->view->products = $products; - $this->view->allProducts = array('0' => '') + $this->program->getProductPairsWithProgram(0, 'all', 'noclosed', '', $shadow); + $this->view->allProducts = $allProducts; $this->view->productPlans = array('0' => '') + $productPlans; $this->view->branchGroups = $this->loadModel('branch')->getByProducts(array_keys($products), 'noclosed'); $this->view->programID = $programID; @@ -713,12 +717,14 @@ class project extends control return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $locateLink)); } + $withProgram = $this->config->systemMode == 'ALM' ? true : false; + $linkedBranches = array(); $linkedBranchList = array(); $productPlans = array(0 => ''); $branches = $this->project->getBranchesByProject($projectID); $linkedProductIdList = empty($branches) ? '' : array_keys($branches); - $allProducts = $this->program->getProductPairsWithProgram($project->parent, 'all', 'noclosed'); + $allProducts = $this->program->getProductPairs($project->parent, 'all', 'noclosed', '', 0, $withProgram); $linkedProducts = $this->loadModel('product')->getProducts($projectID, 'all', '', true, $linkedProductIdList); $parentProject = $this->program->getByID($project->parent); $plans = $this->productplan->getGroupByProduct(array_keys($linkedProducts), 'skipParent|unexpired'); @@ -2228,43 +2234,48 @@ class project extends control } } - $branchGroups = $this->loadModel('branch')->getByProducts(array_keys($allProducts), 'ignoreNormal|noclosed'); - $productsGroupByProgram = $this->product->getProductsGroupByProgram(); - - $currentProducts = array(); - $otherProducts = array(); - foreach($productsGroupByProgram as $programID => $programProducts) + $branchGroups = $this->loadModel('branch')->getByProducts(array_keys($allProducts), 'ignoreNormal|noclosed'); + if($this->config->systemMode == 'ALM') { - if($programID != $project->parent) - { - foreach($programProducts as $productID => $productName) - { - if(!empty($branchGroups[$productID])) - { - foreach($branchGroups[$productID] as $branchID => $branchName) - { - if(isset($linkedProducts[$productID]) and isset($linkedBranches[$productID][$branchID])) continue; + $productsGroupByProgram = $this->product->getProductsGroupByProgram(); - $otherProducts["{$productID}_{$branchID}"] = $productName . '_' . $branchName; + $currentProducts = array(); + $otherProducts = array(); + foreach($productsGroupByProgram as $programID => $programProducts) + { + if($programID != $project->parent) + { + foreach($programProducts as $productID => $productName) + { + if(!empty($branchGroups[$productID])) + { + foreach($branchGroups[$productID] as $branchID => $branchName) + { + if(isset($linkedProducts[$productID]) and isset($linkedBranches[$productID][$branchID])) continue; + + $otherProducts["{$productID}_{$branchID}"] = $productName . '_' . $branchName; + } + } + else + { + if(isset($linkedProducts[$productID])) continue; + $otherProducts[$productID] = $productName; } } - else - { - if(isset($linkedProducts[$productID])) continue; - $otherProducts[$productID] = $productName; - } + } + else + { + $currentProducts += $programProducts; } } - else - { - $currentProducts += $programProducts; - } + + $this->view->currentProducts = $currentProducts; + $this->view->otherProducts = $otherProducts; } /* Assign. */ $this->view->title = $this->lang->project->manageProducts . $this->lang->colon . $project->name; $this->view->project = $project; - $this->view->currentProducts = $currentProducts; $this->view->linkedProducts = $linkedProducts; $this->view->linkedBranches = $linkedBranches; $this->view->branches = $branches; @@ -2275,7 +2286,6 @@ class project extends control $this->view->branchGroups = $branchGroups; $this->view->allBranches = $this->branch->getByProducts(array_keys($allProducts), 'ignoreNormal'); $this->view->allProducts = $allProducts; - $this->view->otherProducts = $otherProducts; $this->display(); } diff --git a/module/project/model.php b/module/project/model.php index 58f2142c85..472a23d353 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -2849,6 +2849,17 @@ class projectModel extends model $this->lang->project->menuOrder = $this->lang->$navGroup->menuOrder; $this->lang->project->dividerMenu = $this->lang->$navGroup->dividerMenu; + if(empty($project->hasProduct)) + { + unset($this->lang->project->menu->settings['subMenu']->products); + } + else + { + unset($this->lang->project->menu->settings['subMenu']->module); + unset($this->lang->project->menu->settings['subMenu']->managerepo); + unset($this->lang->project->menu->projectplan); + } + $this->loadModel('common')->resetProjectPriv($projectID); } diff --git a/module/project/view/manageproducts.html.php b/module/project/view/manageproducts.html.php index ca1c6fe424..5bac169764 100644 --- a/module/project/view/manageproducts.html.php +++ b/module/project/view/manageproducts.html.php @@ -23,9 +23,11 @@ project->manageProducts;?> + config->systemMode == 'ALM'):?>
+
@@ -46,9 +48,34 @@
- - - + + config->systemMode == 'ALM') + { + unset($currentProducts[$productID]); + } + else + { + unset($allProducts[$productID]); + } + } + + if(isset($branchGroups[$productID][$branchID])) unset($branchGroups[$productID][$branchID]); + + if(isset($branchGroups[$productID]) and empty($branchGroups[$productID])) + { + if($this->config->systemMode == 'ALM') + { + unset($currentProducts[$productID]); + } + else + { + unset($allProducts[$productID]); + } + } + ?> @@ -57,7 +84,10 @@
project->unlinkedProducts;?>
- $productName):?> + config->systemMode == 'ALM' ? $currentProducts : $allProducts; + foreach($unlinkedProducts as $productID => $productName): + ?>
'>
@@ -75,6 +105,8 @@
+ + config->systemMode == 'ALM'):?> +
diff --git a/module/story/control.php b/module/story/control.php index 0877c6779d..ef31bfa269 100755 --- a/module/story/control.php +++ b/module/story/control.php @@ -396,6 +396,7 @@ class story extends control /* Hidden some fields of projects without products. */ $this->view->hiddenProduct = false; + $this->view->hiddenParent = false; $this->view->hiddenPlan = false; $this->view->hiddenURS = false; $this->view->teamUsers = array(); @@ -409,6 +410,7 @@ class story extends control { $this->view->teamUsers = $this->project->getTeamMemberPairs($project->id); $this->view->hiddenProduct = true; + $this->view->hiddenParent = true; if($project->model !== 'scrum') $this->view->hiddenPlan = true; if(!$project->multiple) $this->view->hiddenPlan = true; @@ -883,6 +885,7 @@ class story extends control /* Hidden some fields of projects without products. */ $this->view->hiddenProduct = false; + $this->view->hiddenParent = false; $this->view->hiddenPlan = false; $this->view->hiddenURS = false; $this->view->teamUsers = array(); @@ -892,6 +895,7 @@ class story extends control $project = $this->project->getByShadowProduct($product->id); $this->view->teamUsers = $this->project->getTeamMemberPairs($project->id); $this->view->hiddenProduct = true; + $this->view->hiddenParent = true; if($project->model !== 'scrum') $this->view->hiddenPlan = true; if(!$project->multiple) $this->view->hiddenPlan = true; diff --git a/module/story/view/create.html.php b/module/story/view/create.html.php index 462b4df12f..3f92c9a6f5 100644 --- a/module/story/view/create.html.php +++ b/module/story/view/create.html.php @@ -161,7 +161,7 @@ foreach(explode(',', $config->story->create->requiredFields) as $field) story->parent : $lang->story->requirement;?> - + >
story->parent;?>
@@ -171,7 +171,7 @@ foreach(explode(',', $config->story->create->requiredFields) as $field) - + > story->parent;?> diff --git a/module/story/view/edit.html.php b/module/story/view/edit.html.php index df89e7043a..ea2bc86610 100644 --- a/module/story/view/edit.html.php +++ b/module/story/view/edit.html.php @@ -166,7 +166,7 @@ parent >= 0 and $story->type == 'story'):?> - + story->parent;?> parent, "class='form-control chosen'");?> diff --git a/module/story/view/view.html.php b/module/story/view/view.html.php index aab887a7cf..91b29a8998 100644 --- a/module/story/view/view.html.php +++ b/module/story/view/view.html.php @@ -53,7 +53,7 @@ app->rawModule == 'projectstory') + if($this->app->rawModule == 'projectstory' or $this->app->tab == 'project') { $otherParam = "storyID=&projectID={$this->session->project}"; $tab = 'project'; diff --git a/module/task/js/create.js b/module/task/js/create.js index 36e63a45ff..0dcd61d073 100644 --- a/module/task/js/create.js +++ b/module/task/js/create.js @@ -343,7 +343,7 @@ function setStories(moduleID, executionID) $("#story").addClass('filled').chosen(); /* If there is no story option, select will be hidden and text will be displayed; otherwise, the opposite is true */ - if($('#story option').length > 1) + if($('#story option').length > 1 || parseInt(hasProduct) == 0) { $('#story').parent().removeClass('hidden'); $('#storyBox').addClass('hidden'); diff --git a/module/task/view/create.html.php b/module/task/view/create.html.php index f66321ccb0..8e2f516d47 100644 --- a/module/task/view/create.html.php +++ b/module/task/view/create.html.php @@ -23,6 +23,7 @@ error->gt, $lang->task->estimate, '0'))?> lifetime);?> +hasProduct);?> task->create->requiredFields) as $field) diff --git a/module/testcase/control.php b/module/testcase/control.php index 3fd762ac30..bc0c8115f8 100644 --- a/module/testcase/control.php +++ b/module/testcase/control.php @@ -348,8 +348,6 @@ class testcase extends control $stories = array_chunk($stories, $pager->recPerPage); $this->view->title = $this->lang->story->zeroCase; - $this->view->position[] = html::a($this->createLink('testcase', 'browse', "productID=$productID"), $products[$productID]); - $this->view->position[] = $this->lang->story->zeroCase; $this->view->stories = empty($stories) ? $stories : $stories[$pageID - 1]; $this->view->users = $this->user->getPairs('noletter'); diff --git a/module/tree/control.php b/module/tree/control.php index 769bc0a4f6..1041211554 100644 --- a/module/tree/control.php +++ b/module/tree/control.php @@ -400,15 +400,16 @@ class tree extends control $this->view->branch = $branch; $this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted', $module->owner); - $showProduct = strpos('story|bug|case', $type) !== false ? true : false; - $this->view->showProduct = $showProduct; + $showProduct = strpos('story|bug|case', $type) !== false ? true : false; if($showProduct) { $product = $this->loadModel('product')->getById($module->root); if($product->type != 'normal') $this->view->branches = $this->loadModel('branch')->getPairs($module->root, 'withClosed'); $this->view->product = $product; $this->view->products = $this->product->getPairs('', $product->program); + if($product->shadow) $showProduct = false; } + $this->view->showProduct = $showProduct; /* Remove self and childs from the $optionMenu. Because it's parent can't be self or childs. */ $childs = $this->tree->getAllChildId($moduleID); diff --git a/module/tree/model.php b/module/tree/model.php index 0815f377a5..3a11582c03 100644 --- a/module/tree/model.php +++ b/module/tree/model.php @@ -852,7 +852,7 @@ class treeModel extends model { $extra['productID'] = $id; $projectProductLink = helper::createLink('projectstory', 'story', "projectID=$rootID&productID=$id&branch=all"); - $executionProductLink = helper::createLink('execution', 'story', "executionID=$rootID&ordery=&status=byProduct&praram=$id"); + $executionProductLink = helper::createLink('execution', 'story', "executionID=$rootID&storyType=story&orderBy=&type=byProduct&praram=$id"); $link = $this->app->rawModule == 'projectstory' ? $projectProductLink : $executionProductLink; if($productNum > 1) $menu .= "
  • " . html::a($link, $product, '_self', "id='product$id' title=$product");