diff --git a/lib/zin/wg/bugbasicinfo/v1.php b/lib/zin/wg/bugbasicinfo/v1.php new file mode 100644 index 0000000000..03d285933c --- /dev/null +++ b/lib/zin/wg/bugbasicinfo/v1.php @@ -0,0 +1,174 @@ + '?object', // 当前Bug。 + 'product' => '?object', // 当前产品。 + 'users' => '?array', // 用户列表。 + 'statusText' => '?string', // 状态信息。 + 'modulePath' => '?string' // 模块路径。 + ); + + protected function getModuleItems(object $bug, null|bool|object $product, array $branches): array + { + $modulePath = $this->prop('modulePath', data('modulePath')); + $items = array(); + if($modulePath) + { + if($bug->branch and isset($branches[$bug->branch])) + { + $items[] = array('text' => $branches[$bug->branch]); + } + + foreach($modulePath as $key => $module) + { + $items[] = $product->shadow || !common::hasPriv('bug', 'browse') ? array('text' => $module->name) : array('text' => $module->name, 'url' => createLink('bug', 'browse', "productID={$bug->product}&branch={$bug->branch}&browseType=byModule¶m={$module->id}"), 'icon' => ''); + } + } + if(!$items) $items = array('/'); + return $items; + } + + protected function getItems(): array + { + global $lang, $config; + + $bug = $this->prop('bug', data('bug')); + if(!$bug) return array(); + + $canViewProduct = common::hasPriv('project', 'view'); + $canBrowseBug = common::hasPriv('bug', 'browse'); + $canViewPlan = common::hasPriv('productplan', 'view'); + $canViewCase = common::hasPriv('testcase', 'view'); + + $product = $this->prop('product', data('product')); + $project = $this->prop('project', data('project')); + $users = $this->prop('users', data('users')); + $statusText = $this->prop('statusText', data('statusText')); + $branches = $this->prop('branches', data('branches')); + $branchName = $this->prop('branchName', data('branchName')); + + $branchTitle = sprintf($lang->product->branch, $lang->product->branchName[$product->type]); + $productLink = $bug->product && $canViewProduct ? helper::createLink('product', 'view', "productID={$bug->product}") : ''; + $branchLink = $bug->branch && $canBrowseBug ? helper::createLink('bug', 'browse', "productID={$bug->product}&branch={$bug->branch}") : ''; + $planLink = $bug->plan && $canViewPlan ? helper::createLink('productplan', 'view', "planID={$bug->plan}&type=bug") : ''; + $fromCaseLink = $bug->case && $canViewCase ? helper::createLink('testcase', 'view', "caseID={$bug->case}&caseVersion={$bug->caseVersion}") : ''; + + $items = array(); + if(empty($product->shadow)) + { + $items[$lang->bug->product] = $productLink ? array + ( + 'control' => 'link', + 'url' => $productLink, + 'text' => $product->name, + 'data-app' => 'product' + ) : $product->name; + } + + if($product->type != 'normal') + { + $items[$branchTitle] = $branchLink ? array + ( + 'control' => 'link', + 'url' => $branchLink, + 'text' => $branchName + ) : $branchName; + } + + $items[$lang->task->module] = array + ( + 'control' => 'breadcrumb', + 'items' => $this->getModuleItems($bug, $product, $branches) + ); + + if(empty($product->shadow) || !empty($project->multiple)) + { + $items[$lang->bug->plan] = $planLink ? array + ( + 'control' => 'link', + 'url' => $planLink, + 'text' => $bug->planName + ) : $bug->planName; + } + + $caseText = $bug->case ? "#{$bug->case} {$bug->caseTitle}" : ''; + $items[$lang->bug->fromCase] = $fromCaseLink ? array + ( + 'control' => 'link', + 'url' => $fromCaseLink, + 'text' => $caseText + ) : $caseText; + + $items[$lang->bug->type] = zget($lang->bug->typeList, $bug->type, $bug->type); + + $items[$lang->bug->severity] = array + ( + 'control' => 'severitylabel', + 'level' => $bug->severity + ); + + $items[$lang->bug->pri] = array + ( + 'control' => 'pri', + 'pri' => $bug->pri, + 'text' => $lang->bug->priList + ); + + $items[$lang->bug->status] = array + ( + 'control' => 'status', + 'class' => 'bug-status', + 'status' => $bug->status, + 'text' => $statusText + ); + + $items[$lang->bug->activatedCount] = $bug->activatedCount ? array('content' => $bug->activatedCount) : ''; + $items[$lang->bug->activatedDate] = formatTime($bug->activatedDate); + $items[$lang->bug->confirmed] = $lang->bug->confirmedList[$bug->confirmed]; + $items[$lang->bug->assignedTo] = $bug->assignedTo ? zget($users, $bug->assignedTo) . $lang->at . formatTime($bug->assignedDate) : ''; + + $items[$lang->bug->deadline] = array + ( + 'control' => 'span', + 'content' => html(formatTime($bug->deadline) . (isset($bug->delay) ? sprintf($lang->bug->notice->delayWarning, $bug->delay) : '')) + ); + + $items[$lang->bug->feedbackBy] = $bug->feedbackBy; + $items[$lang->bug->notifyEmail] = $bug->notifyEmail; + + $osList = explode(',', $bug->os); + $osText = ''; + foreach($osList as $os) $osText .= zget($lang->bug->osList, $os) . ' '; + $items[$lang->bug->os] = trim($osText); + + $browserList = explode(',', $bug->browser); + $browserText = ''; + foreach($browserList as $browser) $browserText .= zget($lang->bug->browserList, $browser) . ' '; + $items[$lang->bug->browser] = trim($browserText); + + $items[$lang->bug->keywords] = $bug->keywords; + + $mailtoList = explode(',', $bug->mailto); + $mailtoText = ''; + foreach($mailtoList as $account) $mailtoText .= zget($users, $account) . ' '; + $items[$lang->bug->mailto] = trim($mailtoText); + + return $items; + } + + protected function build() + { + return new datalist + ( + set::className('bug-basic-info'), + set::items($this->getItems()) + ); + } +} diff --git a/lib/zin/wg/buglifeinfo/v1.php b/lib/zin/wg/buglifeinfo/v1.php new file mode 100644 index 0000000000..dd5ee45347 --- /dev/null +++ b/lib/zin/wg/buglifeinfo/v1.php @@ -0,0 +1,72 @@ + '?object', // 当前Bug。 + 'users' => '?array' // 用户列表。 + ); + + protected function getItems(): array + { + global $lang; + + $bug = $this->prop('bug', data('bug')); + if(!$bug) return array(); + + $users = $this->prop('users', data('users')); + $builds = $this->prop('builds', data('builds')); + $items = array(); + + $openedBuildList = explode(',', $bug->openedBuild); + $openedBuildText = ''; + foreach($openedBuildList as $openedBuild) + { + if(!$openedBuild) continue; + $openedBuildText .= zget($builds, $openedBuild) . ' '; + } + + $items[$lang->bug->openedBy] = zget($users, $bug->openedBy) . (formatTime($bug->openedDate) ? $lang->at . $bug->openedDate : ''); + $items[$lang->bug->openedBuild] = trim($openedBuildText); + $items[$lang->bug->lblResolved] = zget($users, $bug->resolvedBy) . (formatTime($bug->resolvedDate) ? $lang->at . formatTime($bug->resolvedDate, DT_DATE1) : ''); + $items[$lang->bug->resolvedBuild] = zget($builds, $bug->resolvedBuild); + + $duplicateBugLink = $bug->duplicateBug ? createLink('bug', 'view', "bugID={$bug->duplicateBug}") : ''; + $duplicateBugText = $bug->duplicateBug ? " #{$bug->duplicateBug}: " . "{$bug->duplicateBugTitle}": ''; + $duplicateBugText = div + ( + span(zget($lang->bug->resolutionList, $bug->resolution)), + $bug->duplicateBug ? span(" #{$bug->duplicateBug}: ") : null, + $bug->duplicateBug ? a( + $bug->duplicateBugTitle, + set::href($duplicateBugLink), + setData('toggle', 'modal'), + setData('size', 'lg') + ) : null + ); + $items[$lang->bug->resolution] = array + ( + 'control' => 'div', + 'content' => $duplicateBugText + ); + + $items[$lang->bug->closedBy] = zget($users, $bug->closedBy) . (formatTime($bug->closedDate) ? $lang->at . $bug->closedDate : ''); + $items[$lang->bug->lblLastEdited] = zget($users, $bug->lastEditedBy, $bug->lastEditedBy) . (formatTime($bug->lastEditedDate) ? $lang->at . $bug->lastEditedDate : ''); + + return $items; + } + + protected function build() + { + return new datalist + ( + set::className('bug-life-info'), + set::items($this->getItems()) + ); + } +} diff --git a/lib/zin/wg/bugrelatedinfo/v1.php b/lib/zin/wg/bugrelatedinfo/v1.php new file mode 100644 index 0000000000..5bbed86648 --- /dev/null +++ b/lib/zin/wg/bugrelatedinfo/v1.php @@ -0,0 +1,109 @@ + '?object', // 当前Bug。 + ); + + protected function getItems(): array + { + global $lang, $app; + + $bug = $this->prop('bug', data('bug')); + if(!$bug) return array(); + + $project = $this->prop('project', data('project')); + $canViewProduct = common::hasPriv('product', 'view'); + $canBrowseExecution = common::hasPriv('execution', 'browse'); + $canViewStory = common::hasPriv('story', 'view'); + $canViewTask = common::hasPriv('task', 'view'); + $executionTitle = isset($project->model) && $project->model == 'kanban' ? $lang->bug->kanban : $lang->bug->execution; + $projectLink = $bug->project && $canViewProduct ? helper::createLink('project', 'view', "projectID={$bug->project}") : ''; + $executionLink = $bug->execution && $canBrowseExecution ? helper::createLink('execution', 'browse', "executionID={$bug->execution}") : ''; + $storyLink = $bug->story && $canViewStory ? helper::createLink('story', 'view', "storyID={$bug->story}") : ''; + $taskLink = $bug->task && $canViewTask ? helper::createLink('task', 'view', "taskID={$bug->task}") : ''; + + $items = array(); + $items[$lang->bug->project] = $projectLink ? array + ( + 'control' => 'link', + 'url' => $projectLink, + 'text' => zget($bug, 'projectName', '') + ) : zget($bug, 'projectName', ''); + + if(empty($project) || !empty($project->multiple)) + { + $items[$executionTitle] = $executionLink ? array + ( + 'control' => 'link', + 'url' => $executionLink, + 'text' => zget($bug, 'executionName', '') + ) : zget($bug, 'executionName', ''); + } + + $storyHtml = $bug->story ? div + ( + label + ( + setClass('dark-outline rounded-full size-sm mr-2'), + $bug->story + ), + $storyLink ? a( + zget($bug, 'storyTitle', ''), + set::href($storyLink), + setData('toggle', 'modal'), + setData('size', 'lg') + ) : span(zget($bug, 'storyTitle', '')), + $bug->storyStatus == 'active' && $bug->latestStoryVersion > $bug->storyVersion && common::hasPriv('bug', 'confirmStoryChange') ? span + ( + ' (', + a + ( + set::href(createLink('bug', 'confirmStoryChange', "bugID={$bug->id}")), + $lang->confirm, + ), + ')' + ) : null + ) : null; + + $items[$lang->bug->story] = array + ( + 'control' => 'div', + 'content' => $storyHtml + ); + + $taskHtml = div + ( + label(setClass('dark-outline rounded-full size-sm mr-2'), $bug->task), + $taskLink ? a( + zget($bug, 'taskName', ''), + set::href($taskLink), + setData('toggle', 'modal'), + setData('size', 'lg') + ) : span(zget($bug, 'taskName', '')) + ); + + $items[$lang->bug->task] = array + ( + 'control' => 'div', + 'content' => $bug->task ? $taskHtml : '' + ); + + return $items; + } + + protected function build() + { + return new datalist + ( + set::className('bug-related-info'), + set::items($this->getItems()), + ); + } +} diff --git a/lib/zin/wg/bugrelatedlist/v1.php b/lib/zin/wg/bugrelatedlist/v1.php new file mode 100644 index 0000000000..98bb164f3b --- /dev/null +++ b/lib/zin/wg/bugrelatedlist/v1.php @@ -0,0 +1,149 @@ + '?object', // 当前Bug。 + ); + + protected function created() + { + $data = $this->prop('data'); + if($data) return; + + $bug = $this->prop('bug'); + if(!$bug) $bug = data('bug'); + if(!$bug) return; + + global $app, $lang; + + $canViewCase = common::hasPriv('testcase', 'view'); + $canViewStory = common::hasPriv('story', 'view'); + $canViewTask = common::hasPriv('task', 'view'); + $canViewMR = common::hasPriv('mr', 'view'); + $linkedCommits = $this->prop('linkedCommits', data('linkedCommits')); + + $data = array(); + + /* Related bugs. */ + $relatedBugList = isset($bug->relatedBugTitles) ? $bug->relatedBugTitles :array(); + $relatedBugItems = array(); + foreach($relatedBugList as $relatedBugID => $relatedBugTitle) + { + $relatedBugItem = new stdclass(); + $relatedBugItem->id = $relatedBugID; + $relatedBugItem->title = $relatedBugTitle; + $relatedBugItems[] = $relatedBugItem; + } + + $data['relatedBug'] = array + ( + 'title' => $lang->bug->relatedBug, + 'items' => $relatedBugItems, + 'url' => createLink('bug', 'view', 'bugID={id}'), + 'data-toggle' => 'modal', + 'data-size' => 'lg' + ); + + /* To cases. */ + $toCaseList = isset($bug->toCases) ? $bug->toCases :array(); + $toCaseItems = array(); + foreach($toCaseList as $caseID => $caseTitle) + { + $toCaseItem = new stdclass(); + $toCaseItem->id = $caseID; + $toCaseItem->title = $caseTitle; + + $toCaseItems[] = $toCaseItem; + } + $data['toCase'] = array + ( + 'title' => $lang->bug->toCase, + 'items' => $toCaseItems, + 'url' => $canViewCase ? createLink('testcase', 'view', 'caseID={id}') : false, + 'props' => $canViewCase ? array('data-toggle' => 'modal', 'data-size' => 'lg') : array() + ); + + /* To stories. */ + $toStoryItems = array(); + if($bug->toStory) + { + $toStoryItem = new stdclass(); + $toStoryItem->id = $bug->toStory; + $toStoryItem->title = $bug->toStoryTitle; + + $toStoryItems[] = $toStoryItem; + } + $data['toStory'] = array + ( + 'title' => $lang->bug->toStory, + 'items' => $toStoryItems, + 'url' => $canViewStory ? createLink('story', 'view', 'story={id}') : false, + 'props' => $canViewStory ? array('data-toggle' => 'modal', 'data-size' => 'lg') : array() + ); + + /* To tasks. */ + $toTaskItems = array(); + if($bug->toTask) + { + $toTaskItem = new stdclass(); + $toTaskItem->id = $bug->toTask; + $toTaskItem->title = $bug->toTaskTitle; + + $toTaskItems[] = $toTaskItem; + } + + $data['toTask'] = array + ( + 'title' => $lang->bug->toTask, + 'items' => $toTaskItems, + 'url' => $canViewTask ? createLink('task', 'view', 'task={id}') : false, + 'props' => $canViewTask ? array('data-toggle' => 'modal', 'data-size' => 'lg') : array() + ); + + + /* Linked MR. */ + $linkMRList = isset($bug->linkMRTitles) ? $bug->linkMRTitles :array(); + $linkMRItems = array(); + foreach($linkMRList as $MRID => $linkMRTitle) + { + $linkMRItem = new stdclass(); + $linkMRItem->id = $MRID; + $linkMRItem->title = $linkMRTitle; + + $linkMRItems[] = $linkMRItem; + } + if(helper::hasFeature('devops')) + { + $data['mr'] = array + ( + 'title' => $lang->bug->linkMR, + 'items' => $linkMRItems, + 'url' => $canViewMR ? createLink('mr', 'view', 'MRID={id}') : false, + 'props' => array('data-app' => 'devops') + ); + + $data['linkCommit'] = array + ( + 'title' => $lang->bug->linkCommit, + 'items' => $linkedCommits, + 'url' => false, + 'onRender' => function($item, $commit) + { + $item['text'] = $commit->comment; + if(hasPriv('repo', 'revision')) + { + $item['url'] = createLink('repo', 'revision', "repoID={$commit->repo}&objectID=0&revision={$commit->revision}"); + $item['data-app'] = 'devops'; + } + } + ); + } + $this->setProp('data', $data); + } +} diff --git a/module/bug/control.php b/module/bug/control.php index 967028ca23..02a6254ee2 100755 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -189,11 +189,8 @@ class bug extends control $this->view->builds = $this->loadModel('build')->getBuildPairs(array($bug->product), 'all', 'noterminate,nodone,hasdeleted'); $this->view->linkCommits = $this->loadModel('repo')->getCommitsByObject($bug->id, 'bug'); $this->view->actions = $this->loadModel('action')->getList('bug', $bug->id); - $this->view->legendBasic = $this->bugZen->getBasicInfoTable($this->view); - $this->view->legendLife = $this->bugZen->getBugLifeTable($this->view); - $this->view->legendMain = $this->bugZen->getMainRelatedTable($this->view); - $this->view->legendMisc = $this->bugZen->getOtherRelatedTable($this->view); $this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('bug', $bugID); + $this->display(); } diff --git a/module/bug/ui/view.html.php b/module/bug/ui/view.html.php index 849f207a4d..43c6ccb536 100644 --- a/module/bug/ui/view.html.php +++ b/module/bug/ui/view.html.php @@ -19,182 +19,12 @@ jsVar('branchID', $bug->branch); jsVar('errorNoExecution', $lang->bug->noExecution); jsVar('errorNoProject', $lang->bug->noProject); +$isInModal = isInModal(); $canCreateBug = hasPriv('bug', 'create'); $canViewRepo = hasPriv('repo', 'revision'); $canViewMR = hasPriv('mr', 'view'); $canViewBug = hasPriv('bug', 'view'); - -$moduleHTML = array(); -$moduleTitle = ''; -$moduleItems = array(); -if(empty($modulePath)) -{ - $moduleTitle .= '/'; - $moduleItems[] = span('/'); -} -else -{ - if($bug->branch and isset($branches[$bug->branch])) - { - $moduleTitle .= $branches[$bug->branch] . '/'; - $moduleItems[] = span($branches[$bug->branch], icon('angle-right')); - } - - foreach($modulePath as $key => $module) - { - $moduleTitle .= $module->name; - $moduleItems[] = $product->shadow ? span($module->name) : a(set::href(helper::createLink('bug', 'browse', "productID=$bug->product&branch=$bug->branch&browseType=byModule¶m=$module->id")), $module->name); - if(isset($modulePath[$key + 1])) - { - $moduleTitle .= '/'; - $moduleItems[] = icon('angle-right'); - } - } -} -$legendBasic['module']['text'] = $moduleItems; - -$buildsHTML = array(); -$openedBuilds = explode(',', $legendLife['openedBuild']['text']); -foreach($openedBuilds as $openedBuild) -{ - if(!$openedBuild) continue; - $buildsHTML[] = div(zget($builds, $openedBuild)); -} - -$osHTML = array(); -$osList = explode(',', $legendBasic['os']['text']); -foreach($osList as $os) -{ - $osHTML[] = span(zget($lang->bug->osList, $os)); - $osHTML[] = ' '; -} - -$browserHTML = array(); -$browserList = explode(',', $legendBasic['browser']['text']); -foreach($browserList as $browser) -{ - $browserHTML[] = span(zget($lang->bug->browserList, $browser)); - $browserHTML[] = ' '; -} - -$mailtoHTML = array(); -if(!empty($legendBasic['mailto']['text'])) -{ - $mailtoList = explode(',', str_replace(' ', '', $legendBasic['mailto']['text'])); - foreach($mailtoList as $account) - { - $mailtoHTML[] = span(zget($users, $account)); - $mailtoHTML[] = ' '; - } -} - -$duplicateLink = $bug->duplicateBug && $canViewBug ? a -( - set('href', $this->createLink('bug', 'view', "bugID={$bug->duplicateBug}")), - setData - ( - array - ( - 'toggle' => 'modal', - 'size' => 'lg', - ) - ), - $bug->duplicateBugTitle -) : ''; -$duplicateBug = $bug->duplicateBug ? span("#{$bug->duplicateBug}:", $duplicateLink) : ''; - -$linkCases = array(); -foreach($legendMisc['toCase']['text'] as $caseID => $caseTitle) -{ - $linkCases[] = div(setClass('mb-2'), - a - ( - set('href', $this->createLink('testcase', 'view', "bugID={$caseID}")), - setData - ( - array - ( - 'toggle' => 'modal', - 'size' => 'lg', - ) - ), - span(label(setClass('dark-outline rounded-full mr-2'), $caseID), $caseTitle) - )); -} - -$relatedBugs = array(); -foreach($legendMisc['relatedBug']['text'] as $relatedBugID => $relatedBugTitle) -{ - $relatedBugs[] = div(a - ( - set('href', $this->createLink('bug', 'view', "bugID={$relatedBugID}")), - setData - ( - array - ( - 'toggle' => 'modal', - 'size' => 'lg', - ) - ), - span(label(setClass('dark-outline rounded-full mr-2'), $relatedBugID), $relatedBugTitle) - )); -} - -$linkMR = array(); -foreach($legendMisc['linkMR']['text'] as $MRID => $linkMRTitle) -{ - $linkMR[] = div(a - ( - $canViewMR ? set('href', $this->createLink('mr', 'view', "MRID={$MRID}")) : null, - setData(array('app' => 'devops')), - span(label(setClass('dark-outline rounded-full mr-2'), $MRID), $linkMRTitle) - )); -} - -$linkCommits = array(); -foreach($legendMisc['linkCommit']['text'] as $commit) -{ - $linkCommits[] = div(a - ( - setData(array('app' => 'devops')), - $canViewRepo ? set('href', $this->createLink('repo', 'revision', "repoID={$commit->repo}&objectID=0&revision={$commit->revision}")) : null, - "{$commit->comment}" - )); -} - -if(isset($bug->delay)) $legendBasic['deadline']['text'] = html($legendBasic['deadline']['text']); - -$legendBasic['os']['text'] = $osHTML; -$legendBasic['browser']['text'] = $browserHTML; -$legendBasic['mailto']['text'] = $mailtoHTML; -$legendBasic['severity']['text'] = severityLabel($legendBasic['severity']['text'], set::text($lang->bug->severityList)); -$legendBasic['pri']['text'] = priLabel($legendBasic['pri']['text'], set::text($lang->bug->priList)); -$legendLife['openedBuild']['text'] = $buildsHTML; -$legendLife['resolution']['text'] = div(zget($lang->bug->resolutionList, $bug->resolution), $duplicateBug); -$legendMain['story']['text'] = $bug->story ? div -( - label - ( - setClass('dark-outline rounded-full size-sm mr-2'), - $bug->story - ), - span($bug->storyTitle), - $bug->storyStatus == 'active' && $bug->latestStoryVersion > $bug->storyVersion && common::hasPriv('bug', 'confirmStoryChange') ? span - ( - ' (', - a - ( - set::href(createLink('bug', 'confirmStoryChange', "bugID=$bug->id")), - $lang->confirm, - ), - ')' - ) : '' -) : ''; -$legendMain['task']['text'] = $bug->task ? div(label(setClass('dark-outline rounded-full size-sm mr-2'), $bug->task), span($bug->taskName)) : '';; -$legendMisc['toCase']['text'] = $linkCases; -$legendMisc['relatedBug']['text'] = $relatedBugs; -$legendMisc['linkCommit']['text'] = $linkCommits; -$legendMisc['linkMR']['text'] = $linkMR; +$operateList = $this->loadModel('common')->buildOperateMenu($bug); /* Handling special tags in bug descriptions. */ $tplStep = strip_tags(trim($lang->bug->tplStep)); @@ -205,146 +35,83 @@ $tplExpect = strip_tags(trim($lang->bug->tplExpect)); $steps = str_replace('
' . $tplExpect, '
' . $tplExpect . '
', $steps); $steps = str_replace('
', '', $steps); -detailHeader -( - to::title - ( - entityLabel - ( - set::entityID($bug->id), - set::level(1), - span(setStyle('color', $bug->color), $bug->title), - $bug->case ? a - ( - set::href($legendBasic['fromCase']['href']), - setClass('font-medium text-base text-gray'), - icon('testcase px-1'), - $lang->case->fromCase . $lang->colon . $bug->case - ) : null - ), - $bug->deleted ? span(setClass('label danger'), $lang->bug->deleted) : null - ), - to::suffix - ( - !isAjaxRequest('modal') && $canCreateBug ? btn - ( - set::icon('plus'), - set::type('primary'), - set::text($lang->bug->create), - set::url($this->createLink('bug', 'create', "productID={$product->id}")) - ) : null - ) -); - -/** - * Build content of table data. - * - * @param array $items - * @access public - * @return array - */ -$buildItems = function($items): array +/* 初始化头部右上方工具栏。Init detail toolbar. */ +$toolbar = array(); +if(!$isInModal && $canCreateBug) { - $itemList = array(); - foreach($items as $item) - { - $itemList[] = item - ( - set::name($item['name']), - !empty($item['href']) ? a - ( - set::href($item['href']), - !empty($item['attr']) && is_array($item['attr']) ? set($item['attr']) : null, - $item['text'] - ) : $item['text'], - set::collapse(!empty($item['text'])) - ); - } - - return $itemList; -}; - -$fileList = array(); -if(!empty($bug->files)) -{ - $fileList[] = fileList + $toolbar[] = array ( - set::files($bug->files), - set::padding(false) + 'icon' => 'plus', + 'type' => 'primary', + 'text' => $lang->bug->create, + 'url' => createLink('bug', 'create', "productID={$product->id}") ); } -$actions = $this->loadModel('common')->buildOperateMenu($bug); -detailBody +/* 初始化底部操作栏。Init bottom actions. */ +$actions = array(); +if(!$bug->deleted) +{ + /* Construct common actions for bug. */ + foreach($operateList['mainActions'] as $operate) + { + if(!empty($operate['id']) && $operate['id'] == 'toStory') $operate['data-url'] = createLink('story', 'create', "product={$bug->product}&branch={$bug->branch}&module={$bug->module}&story=0&execution=0&bugID={$bug->id}"); + $actions[] = $operate; + } + if(!empty($operateList['suffixActions'])) $actions = array_merge($actions, array(array('type' => 'divider')), $operateList['suffixActions']); +} + +/* 初始化主栏内容。Init sections in main column. */ +$sections = array(); +$sections[] = setting() + ->title($lang->bug->legendSteps) + ->control('html') + ->content($steps); + +if($bug->files) +{ + $sections[] = array + ( + 'title' => $lang->files, + 'control' => 'fileList', + 'files' => $bug->files, + 'object' => $bug + ); +} + +/* 初始化侧边栏标签页。Init sidebar tabs. */ +$tabs = array(); + +/* 基本信息。Legend basic items. */ +$tabs[] = setting() + ->group('basic') + ->title($lang->bug->legendBasicInfo) + ->control('bugBasicInfo') + ->statusText($this->processStatus('bug', $bug)); + +/* 一生信息。Legend life items. */ +$tabs[] = setting() + ->group('basic') + ->title($lang->bug->legendLife) + ->control('bugLifeInfo'); + +$tabs[] = setting() + ->group('related') + ->title(!empty($project->multiple) ? $lang->bug->legendPRJExecStoryTask : $lang->bug->legendExecStoryTask) + ->control('bugRelatedInfo'); + +$tabs[] = setting() + ->group('related') + ->title($lang->bug->legendMisc) + ->control('bugRelatedList'); + +detail ( - sectionList - ( - section - ( - set::title($lang->bug->legendSteps), - set::content($steps), - set::useHtml(true) - ), - $fileList - ), - history(), - floatToolbar - ( - set::object($bug), - isAjaxRequest('modal') ? null : to::prefix(backBtn(set::icon('back'), setClass('ghost text-white'), $lang->goback)), - set::main($actions['mainActions']), - set::suffix($actions['suffixActions']) - ), - detailSide - ( - tabs - ( - set::collapse(true), - tabPane - ( - set::key('legendBasicInfo'), - set::title($lang->bug->legendBasicInfo), - set::active(true), - tableData - ( - $buildItems($legendBasic) - ) - ), - tabPane - ( - set::key('legendLife'), - set::title($lang->bug->legendLife), - tableData - ( - $buildItems($legendLife) - ) - ) - ), - tabs - ( - set::collapse(true), - tabPane - ( - set::key('legendMain'), - set::title(!empty($project->multiple) ? $lang->bug->legendPRJExecStoryTask : $lang->bug->legendExecStoryTask), - set::active(true), - tableData - ( - $buildItems($legendMain) - ) - ), - tabPane - ( - set::key('legendMisc'), - set::title($lang->bug->legendMisc), - tableData - ( - set::useTable(false), - $buildItems($legendMisc) - ) - ) - ) - ) + set::urlFormatter(array('{id}' => $bug->id, '{product}' => $bug->product, '{branch}' => $bug->branch, '{project}' => $bug->project, '{execution}' => $bug->execution)), + set::toolbar($toolbar), + set::sections($sections), + set::tabs($tabs), + set::actions($actions) ); modal @@ -394,14 +161,3 @@ modal ) ) ); - -if(!isInModal()) -{ - floatPreNextBtn - ( - !empty($preAndNext->pre) ? set::preLink(createLink('bug', 'view', "bugID={$preAndNext->pre->id}")) : null, - !empty($preAndNext->next) ? set::nextLink(createLink('bug', 'view', "bugID={$preAndNext->next->id}")) : null - ); -} - -render(); diff --git a/module/bug/zen.php b/module/bug/zen.php index c79a5199af..f028d1300f 100644 --- a/module/bug/zen.php +++ b/module/bug/zen.php @@ -450,143 +450,6 @@ class bugZen extends bug return array($modules, $product->QD); } - /** - * 获取BUG详情页面的基本信息列表。 - * Get bug legend basic info. - * - * @param object $view - * @access protected - * @return array - */ - protected function getBasicInfoTable(object $view): array - { - extract((array)$view); - - $this->app->loadLang('product'); - $canViewProduct = common::hasPriv('project', 'view'); - $canBrowseBug = common::hasPriv('bug', 'browse'); - $canViewPlan = common::hasPriv('productplan', 'view'); - $canViewCase = common::hasPriv('testcase', 'view'); - - $branchTitle = sprintf($this->lang->product->branch, $this->lang->product->branchName[$product->type]); - $fromCaseName = $bug->case ? "#{$bug->case} {$bug->caseTitle}" : ''; - $productLink = $bug->product && $canViewProduct ? helper::createLink('product', 'view', "productID={$bug->product}") : ''; - $branchLink = $bug->branch && $canBrowseBug ? helper::createLink('bug', 'browse', "productID={$bug->product}&branch={$bug->branch}") : ''; - $planLink = $bug->plan && $canViewPlan ? helper::createLink('productplan', 'view', "planID={$bug->plan}&type=bug") : ''; - $fromCaseLink = $bug->case && $canViewCase ? helper::createLink('testcase', 'view', "caseID={$bug->case}&caseVersion={$bug->caseVersion}") : ''; - - $legendBasic = array(); - if(empty($product->shadow)) $legendBasic['product'] = array('name' => $this->lang->bug->product, 'text' => $product->name, 'href' => $productLink, 'attr' => array('data-app' => 'product')); - if($product->type != 'normal') $legendBasic['branch'] = array('name' => $branchTitle, 'text' => $branchName, 'href' => $branchLink); - $legendBasic['module'] = array('name' => $this->lang->bug->module, 'text' => $bug->module); - if(empty($product->shadow) || !empty($project->multiple)) $legendBasic['productplan'] = array('name' => $this->lang->bug->plan, 'text' => $bug->planName, 'href' => $planLink); - $legendBasic['fromCase'] = array('name' => $this->lang->bug->fromCase, 'text' => $fromCaseName, 'href' => $fromCaseLink, 'attr' => array('data-toggle' => 'modal', 'data-size' => 'lg')); - $legendBasic['type'] = array('name' => $this->lang->bug->type, 'text' => zget($this->lang->bug->typeList, $bug->type)); - $legendBasic['severity'] = array('name' => $this->lang->bug->severity, 'text' => $bug->severity); - $legendBasic['pri'] = array('name' => $this->lang->bug->pri, 'text' => $bug->pri); - $legendBasic['status'] = array('name' => $this->lang->bug->status, 'text' => $this->processStatus('bug', $bug), 'attr' => array('class' => 'status-' . $bug->status)); - $legendBasic['activatedCount'] = array('name' => $this->lang->bug->activatedCount, 'text' => $bug->activatedCount ? $bug->activatedCount : ''); - $legendBasic['activatedDate'] = array('name' => $this->lang->bug->activatedDate, 'text' => formatTime($bug->activatedDate)); - $legendBasic['confirmed'] = array('name' => $this->lang->bug->confirmed, 'text' => $this->lang->bug->confirmedList[$bug->confirmed]); - $legendBasic['assignedTo'] = array('name' => $this->lang->bug->lblAssignedTo, 'text' => $bug->assignedTo ? zget($users, $bug->assignedTo) . $this->lang->at . formatTime($bug->assignedDate) : ''); - $legendBasic['deadline'] = array('name' => $this->lang->bug->deadline, 'text' => formatTime($bug->deadline) . (isset($bug->delay) ? sprintf($this->lang->bug->notice->delayWarning, $bug->delay) : '')); - $legendBasic['feedbackBy'] = array('name' => $this->lang->bug->feedbackBy, 'text' => $bug->feedbackBy); - $legendBasic['notifyEmail'] = array('name' => $this->lang->bug->notifyEmail, 'text' => $bug->notifyEmail); - $legendBasic['os'] = array('name' => $this->lang->bug->os, 'text' => $bug->os); - $legendBasic['browser'] = array('name' => $this->lang->bug->browser, 'text' => $bug->browser); - $legendBasic['keywords'] = array('name' => $this->lang->bug->keywords, 'text' => $bug->keywords); - $legendBasic['mailto'] = array('name' => $this->lang->bug->mailto, 'text' => $bug->mailto); - - return $legendBasic; - } - - /** - * 获取BUG的一生信息。 - * Get bug a life data. - * - * @param object $view - * @access protected - * @return array - */ - protected function getBugLifeTable(object $view): array - { - extract((array)$view); - - $legendLife = array(); - $legendLife['openedBy'] = array('name' => $this->lang->bug->openedBy, 'text' => zget($users, $bug->openedBy) . (formatTime($bug->openedDate) ? $this->lang->at . $bug->openedDate : '')); - $legendLife['openedBuild'] = array('name' => $this->lang->bug->openedBuild, 'text' => $bug->openedBuild); - $legendLife['resolvedBy'] = array('name' => $this->lang->bug->lblResolved, 'text' => zget($users, $bug->resolvedBy) . (formatTime($bug->resolvedDate) ? $this->lang->at . formatTime($bug->resolvedDate, DT_DATE1) : '')); - $legendLife['resolvedBuild'] = array('name' => $this->lang->bug->resolvedBuild, 'text' => zget($builds, $bug->resolvedBuild)); - $legendLife['resolution'] = array('name' => $this->lang->bug->resolution, 'text' => ''); - $legendLife['closedBy'] = array('name' => $this->lang->bug->closedBy, 'text' => zget($users, $bug->closedBy) . (formatTime($bug->closedDate) ? $this->lang->at . $bug->closedDate : '')); - $legendLife['lastEditedBy'] = array('name' => $this->lang->bug->lblLastEdited, 'text' => zget($users, $bug->lastEditedBy, $bug->lastEditedBy) . (formatTime($bug->lastEditedDate) ? $this->lang->at . $bug->lastEditedDate : '')); - - return $legendLife; - } - - /** - * 获取BUG的项目、迭代、研发需求、任务信息。 - * Get bug main related data. - * - * @param object $view - * @access protected - * @return array - */ - protected function getMainRelatedTable(object $view): array - { - extract((array)$view); - - $canViewProduct = common::hasPriv('product', 'view'); - $canBrowseExecution = common::hasPriv('execution', 'browse'); - $canViewStory = common::hasPriv('story', 'view'); - $canViewTask = common::hasPriv('task', 'view'); - - $executionTitle = isset($project->model) && $project->model == 'kanban' ? $this->lang->bug->kanban : $this->lang->bug->execution; - $projectLink = $bug->project && $canViewProduct ? helper::createLink('project', 'view', "projectID={$bug->project}") : ''; - $executionLink = $bug->execution && $canBrowseExecution ? helper::createLink('execution', 'browse', "executionID={$bug->execution}") : ''; - $storyLink = $bug->story && $canViewStory ? helper::createLink('story', 'view', "storyID={$bug->story}") : ''; - $taskLink = $bug->task && $canViewTask ? helper::createLink('task', 'view', "taskID={$bug->task}") : ''; - - $legendExecStoryTask = array(); - $legendExecStoryTask['project'] = array('name' => $this->lang->bug->project, 'text' => zget($bug, 'projectName', ''), 'href' => $projectLink); - if(empty($project) || !empty($project->multiple)) $legendExecStoryTask['execution'] = array('name' => $executionTitle, 'text' => $bug->executionName, 'href' => $executionLink); - $legendExecStoryTask['story'] = array('name' => $this->lang->bug->story, 'text' => $bug->storyTitle, 'href' => $storyLink, 'attr' => array('data-toggle' => 'modal', 'data-size' => 'lg')); - $legendExecStoryTask['task'] = array('name' => $this->lang->bug->task, 'text' => $bug->taskName, 'href' => $taskLink, 'attr' => array('data-toggle' => 'modal', 'data-size' => 'lg')); - - return $legendExecStoryTask; - } - - /** - * 获取BUG的其他相关信息。 - * Get bug other related data. - * - * @param object $view - * @access protected - * @return array - */ - protected function getOtherRelatedTable(object $view): array - { - extract((array)$view); - - $canViewStory = common::hasPriv('story', 'view'); - $canViewTask = common::hasPriv('task', 'view'); - - $toStoryName = $bug->toStory ? "#{$bug->toStory} {$bug->toStoryTitle}" : ''; - $toTaskName = $bug->toTask ? "#{$bug->toTask} {$bug->toTaskTitle}" : ''; - $toStoryLink = $bug->toStory && $canViewStory ? helper::createLink('story', 'view', "storyID={$bug->toStory}") : ''; - $toTaskLink = $bug->toTask && $canViewTask ? helper::createLink('task', 'view', "taskID={$bug->toTask}") : ''; - - $legendMisc = array(); - $legendMisc['relatedBug'] = array('name' => $lang->bug->relatedBug, 'text' => isset($bug->relatedBugTitles) ? $bug->relatedBugTitles : array()); - $legendMisc['toCase'] = array('name' => $lang->bug->toCase, 'text' => $bug->toCases); - $legendMisc['toStory'] = array('name' => $lang->bug->toStory, 'text' => $toStoryName, 'href' => $toStoryLink, 'attr' => array('data-toggle' => 'modal', 'data-size' => 'lg')); - $legendMisc['toTask'] = array('name' => $lang->bug->toTask, 'text' => $toTaskName, 'href' => $toTaskLink, 'attr' => array('data-toggle' => 'modal', 'data-size' => 'lg')); - $legendMisc['linkMR'] = array('name' => $lang->bug->linkMR, 'text' => $bug->linkMRTitles); - $legendMisc['linkCommit'] = array('name' => $lang->bug->linkCommit, 'text' => $linkCommits); - - return $legendMisc; - } - /** * 设置浏览页面的 cookie。 * Set cookie in browse view.