diff --git a/db/update16.0.beta1.sql b/db/update16.0.beta1.sql new file mode 100644 index 0000000000..6634ac2b81 --- /dev/null +++ b/db/update16.0.beta1.sql @@ -0,0 +1,7 @@ +ALTER TABLE `zt_task` ADD `repo` mediumint unsigned NOT NULL AFTER `activatedDate`; +ALTER TABLE `zt_task` ADD `entry` varchar(255) NOT NULL AFTER `repo`; +ALTER TABLE `zt_task` ADD `lines` varchar(10) NOT NULL AFTER `entry`; +ALTER TABLE `zt_task` ADD `v1` varchar(40) NOT NULL AFTER `lines`; +ALTER TABLE `zt_task` ADD `v2` varchar(40) NOT NULL AFTER `v1`; +ALTER TABLE `zt_task` ADD `mr` mediumint(8) unsigned NOT NULL AFTER `repo`; +ALTER TABLE `zt_bug` ADD `mr` mediumint(8) unsigned NOT NULL AFTER `repo`; diff --git a/db/zentao.sql b/db/zentao.sql index d05177fe58..4ecc3b3137 100644 --- a/db/zentao.sql +++ b/db/zentao.sql @@ -203,6 +203,7 @@ CREATE TABLE IF NOT EXISTS `zt_bug` ( `caseVersion` smallint(6) NOT NULL DEFAULT '1', `result` mediumint(8) unsigned NOT NULL, `repo` mediumint(8) unsigned NOT NULL, + `mr` mediumint(8) unsigned NOT NULL, `entry` varchar(255) NOT NULL, `lines` varchar(10) NOT NULL, `v1` varchar(40) NOT NULL, @@ -1250,6 +1251,12 @@ CREATE TABLE IF NOT EXISTS `zt_task` ( `lastEditedBy` varchar(30) NOT NULL, `lastEditedDate` datetime NOT NULL, `activatedDate` date NOT NULL, + `repo` mediumint(8) unsigned NOT NULL, + `mr` mediumint(8) unsigned NOT NULL, + `entry` varchar(255) NOT NULL, + `lines` varchar(10) NOT NULL, + `v1` varchar(40) NOT NULL, + `v2` varchar(40) NOT NULL, `deleted` enum('0','1') NOT NULL default '0', PRIMARY KEY (`id`), KEY `execution` (`execution`), diff --git a/module/action/lang/en.php b/module/action/lang/en.php index 93ba842862..f0923f5bb5 100755 --- a/module/action/lang/en.php +++ b/module/action/lang/en.php @@ -79,102 +79,104 @@ $lang->action->periods['lastweek'] = $lang->action->dynamic->lastWeek; $lang->action->periods['thismonth'] = $lang->action->dynamic->thisMonth; $lang->action->periods['lastmonth'] = $lang->action->dynamic->lastMonth; -$lang->action->objectTypes['product'] = $lang->productCommon; -$lang->action->objectTypes['branch'] = 'Branch'; -$lang->action->objectTypes['story'] = $lang->SRCommon; -$lang->action->objectTypes['design'] = 'Design'; -$lang->action->objectTypes['productplan'] = 'Plan'; -$lang->action->objectTypes['release'] = 'Release'; -$lang->action->objectTypes['program'] = 'Program'; -$lang->action->objectTypes['project'] = 'Project'; -$lang->action->objectTypes['execution'] = $lang->executionCommon; -$lang->action->objectTypes['task'] = 'Task'; -$lang->action->objectTypes['build'] = 'Build'; -$lang->action->objectTypes['job'] = 'Job'; -$lang->action->objectTypes['bug'] = 'Bug'; -$lang->action->objectTypes['case'] = 'Case'; -$lang->action->objectTypes['caseresult'] = 'Case Result'; -$lang->action->objectTypes['stepresult'] = 'Case Steps'; -$lang->action->objectTypes['caselib'] = 'Library'; -$lang->action->objectTypes['testsuite'] = 'Suite'; -$lang->action->objectTypes['testtask'] = 'Test Build'; -$lang->action->objectTypes['testreport'] = 'Report'; -$lang->action->objectTypes['doc'] = 'Document'; -$lang->action->objectTypes['api'] = 'Interface'; -$lang->action->objectTypes['doclib'] = 'Document Library'; -$lang->action->objectTypes['apistruct'] = 'API struct'; -$lang->action->objectTypes['todo'] = 'Todo'; -$lang->action->objectTypes['risk'] = 'Risk'; -$lang->action->objectTypes['issue'] = 'Issue'; -$lang->action->objectTypes['module'] = 'Module'; -$lang->action->objectTypes['user'] = 'User'; -$lang->action->objectTypes['stakeholder'] = 'Stakeholder'; -$lang->action->objectTypes['budget'] = 'Cost Estimate'; -$lang->action->objectTypes['entry'] = 'Entry'; -$lang->action->objectTypes['webhook'] = 'Webhook'; -$lang->action->objectTypes['team'] = 'Team'; -$lang->action->objectTypes['whitelist'] = 'Whitelist'; -$lang->action->objectTypes['pipeline'] = 'GitLab'; -$lang->action->objectTypes['gitlab'] = 'GitLab'; -$lang->action->objectTypes['jenkins'] = 'Jenkins'; -$lang->action->objectTypes['mr'] = 'Merge Request'; -$lang->action->objectTypes['gitlabproject'] = 'GitLab Project'; -$lang->action->objectTypes['gitlabuser'] = 'GitLab User'; -$lang->action->objectTypes['gitlabgroup'] = 'GitLab Group'; -$lang->action->objectTypes['gitlabbranch'] = 'GitLab Branch'; +$lang->action->objectTypes['product'] = $lang->productCommon; +$lang->action->objectTypes['branch'] = 'Branch'; +$lang->action->objectTypes['story'] = $lang->SRCommon; +$lang->action->objectTypes['design'] = 'Design'; +$lang->action->objectTypes['productplan'] = 'Plan'; +$lang->action->objectTypes['release'] = 'Release'; +$lang->action->objectTypes['program'] = 'Program'; +$lang->action->objectTypes['project'] = 'Project'; +$lang->action->objectTypes['execution'] = $lang->executionCommon; +$lang->action->objectTypes['task'] = 'Task'; +$lang->action->objectTypes['build'] = 'Build'; +$lang->action->objectTypes['job'] = 'Job'; +$lang->action->objectTypes['bug'] = 'Bug'; +$lang->action->objectTypes['case'] = 'Case'; +$lang->action->objectTypes['caseresult'] = 'Case Result'; +$lang->action->objectTypes['stepresult'] = 'Case Steps'; +$lang->action->objectTypes['caselib'] = 'Library'; +$lang->action->objectTypes['testsuite'] = 'Suite'; +$lang->action->objectTypes['testtask'] = 'Test Build'; +$lang->action->objectTypes['testreport'] = 'Report'; +$lang->action->objectTypes['doc'] = 'Document'; +$lang->action->objectTypes['api'] = 'Interface'; +$lang->action->objectTypes['doclib'] = 'Document Library'; +$lang->action->objectTypes['apistruct'] = 'API struct'; +$lang->action->objectTypes['todo'] = 'Todo'; +$lang->action->objectTypes['risk'] = 'Risk'; +$lang->action->objectTypes['issue'] = 'Issue'; +$lang->action->objectTypes['module'] = 'Module'; +$lang->action->objectTypes['user'] = 'User'; +$lang->action->objectTypes['stakeholder'] = 'Stakeholder'; +$lang->action->objectTypes['budget'] = 'Cost Estimate'; +$lang->action->objectTypes['entry'] = 'Entry'; +$lang->action->objectTypes['webhook'] = 'Webhook'; +$lang->action->objectTypes['team'] = 'Team'; +$lang->action->objectTypes['whitelist'] = 'Whitelist'; +$lang->action->objectTypes['pipeline'] = 'GitLab'; +$lang->action->objectTypes['gitlab'] = 'GitLab'; +$lang->action->objectTypes['jenkins'] = 'Jenkins'; +$lang->action->objectTypes['mr'] = 'Merge Request'; +$lang->action->objectTypes['gitlabproject'] = 'GitLab Project'; +$lang->action->objectTypes['gitlabuser'] = 'GitLab User'; +$lang->action->objectTypes['gitlabgroup'] = 'GitLab Group'; +$lang->action->objectTypes['gitlabbranch'] = 'GitLab Branch'; +$lang->action->objectTypes['gitlabbranchpriv'] = 'GitLab Protected Branches'; /* Used to describe operation history. */ $lang->action->desc = new stdclass(); -$lang->action->desc->common = '$date, $action by $actor.' . "\n"; -$lang->action->desc->extra = '$date, $action as $extra by $actor.' . "\n"; -$lang->action->desc->opened = '$date, created by $actor .' . "\n"; -$lang->action->desc->openedbysystem = '$date, opened by system.' . "\n"; -$lang->action->desc->created = '$date, created by $actor .' . "\n"; -$lang->action->desc->added = '$date, added by $actor .' . "\n"; -$lang->action->desc->changed = '$date, changed by $actor .' . "\n"; -$lang->action->desc->edited = '$date, edited by $actor .' . "\n"; -$lang->action->desc->assigned = '$date, $actor assigned to $extra.' . "\n"; -$lang->action->desc->closed = '$date, closed by $actor .' . "\n"; -$lang->action->desc->closedbysystem = '$date, closed by system.' . "\n"; -$lang->action->desc->deleted = '$date, deleted by $actor .' . "\n"; -$lang->action->desc->deletedfile = '$date, $actor deleted $extra.' . "\n"; -$lang->action->desc->editfile = '$date, $actor edited $extra.' . "\n"; -$lang->action->desc->erased = '$date, deleted by $actor .' . "\n"; -$lang->action->desc->undeleted = '$date, restored by $actor .' . "\n"; -$lang->action->desc->hidden = '$date, hidden by $actor .' . "\n"; -$lang->action->desc->commented = '$date, added by $actor.' . "\n"; -$lang->action->desc->activated = '$date, activated by $actor .' . "\n"; -$lang->action->desc->blocked = '$date, blocked by $actor .' . "\n"; -$lang->action->desc->moved = '$date, moved by $actor , which was "$extra".' . "\n"; -$lang->action->desc->confirmed = '$date, $actor confirmed the story change. The latest build is #$extra.' . "\n"; -$lang->action->desc->caseconfirmed = '$date, $actor confirmed the case change. The latest build is #$extra' . "\n"; -$lang->action->desc->bugconfirmed = '$date, $actor confirmed Bug.' . "\n"; -$lang->action->desc->frombug = '$date, converted from $actor. Its ID was $extra.'; -$lang->action->desc->started = '$date, started by $actor.' . "\n"; -$lang->action->desc->restarted = '$date, continued by $actor.' . "\n"; -$lang->action->desc->delayed = '$date, postponed by $actor.' . "\n"; -$lang->action->desc->suspended = '$date, suspended by $actor.' . "\n"; -$lang->action->desc->recordestimate = '$date, recorded by $actor and it cost $extra hours.'; -$lang->action->desc->editestimate = '$date, $actor edited Hour.'; -$lang->action->desc->deleteestimate = '$date, $actor deleted Hour.'; -$lang->action->desc->canceled = '$date, cancelled by $actor.' . "\n"; -$lang->action->desc->svncommited = '$date, $actor committed and the build is #$extra.' . "\n"; -$lang->action->desc->gitcommited = '$date, $actor committed and the build is #$extra.' . "\n"; -$lang->action->desc->finished = '$date, finished by $actor.' . "\n"; -$lang->action->desc->paused = '$date, paused by $actor.' . "\n"; -$lang->action->desc->verified = '$date, verified by $actor.' . "\n"; -$lang->action->desc->diff1 = '%s is changed. It was "%s" and it is "%s".
' . "\n"; -$lang->action->desc->diff2 = '%s is changed. The difference is ' . "\n" . "
%s
" . "\n
%s
"; -$lang->action->desc->diff3 = 'File Name %s was changed to %s .' . "\n"; -$lang->action->desc->linked2bug = '$date, linked to $extra by $actor'; -$lang->action->desc->linked2testtask = '$date, linked to $extra by $actor'; -$lang->action->desc->resolved = '$date, resolved by $actor ' . "\n"; -$lang->action->desc->managed = '$date, by $actor managed.' . "\n"; -$lang->action->desc->estimated = '$date, by $actor estimated.' . "\n"; -$lang->action->desc->run = '$date, by $actor executed.' . "\n"; -$lang->action->desc->syncprogram = '$date, started by $actor(starting the project sets the program status as Ongoing).' . "\n"; -$lang->action->desc->syncproject = '$date, starting the execution sets the project status as Ongoing.' . "\n"; -$lang->action->desc->syncexecution = '$date, starting the task sets the execution status as Ongoing.' . "\n"; +$lang->action->desc->common = '$date, $action by $actor.' . "\n"; +$lang->action->desc->extra = '$date, $action as $extra by $actor.' . "\n"; +$lang->action->desc->opened = '$date, created by $actor .' . "\n"; +$lang->action->desc->openedbysystem = '$date, opened by system.' . "\n"; +$lang->action->desc->created = '$date, created by $actor .' . "\n"; +$lang->action->desc->added = '$date, added by $actor .' . "\n"; +$lang->action->desc->changed = '$date, changed by $actor .' . "\n"; +$lang->action->desc->edited = '$date, edited by $actor .' . "\n"; +$lang->action->desc->assigned = '$date, $actor assigned to $extra.' . "\n"; +$lang->action->desc->closed = '$date, closed by $actor .' . "\n"; +$lang->action->desc->closedbysystem = '$date, closed by system.' . "\n"; +$lang->action->desc->deleted = '$date, deleted by $actor .' . "\n"; +$lang->action->desc->deletedfile = '$date, $actor deleted $extra.' . "\n"; +$lang->action->desc->editfile = '$date, $actor edited $extra.' . "\n"; +$lang->action->desc->erased = '$date, deleted by $actor .' . "\n"; +$lang->action->desc->undeleted = '$date, restored by $actor .' . "\n"; +$lang->action->desc->hidden = '$date, hidden by $actor .' . "\n"; +$lang->action->desc->commented = '$date, added by $actor.' . "\n"; +$lang->action->desc->activated = '$date, activated by $actor .' . "\n"; +$lang->action->desc->blocked = '$date, blocked by $actor .' . "\n"; +$lang->action->desc->moved = '$date, moved by $actor , which was "$extra".' . "\n"; +$lang->action->desc->confirmed = '$date, $actor confirmed the story change. The latest build is #$extra.' . "\n"; +$lang->action->desc->caseconfirmed = '$date, $actor confirmed the case change. The latest build is #$extra' . "\n"; +$lang->action->desc->bugconfirmed = '$date, $actor confirmed Bug.' . "\n"; +$lang->action->desc->frombug = '$date, converted from $actor. Its ID was $extra.'; +$lang->action->desc->started = '$date, started by $actor.' . "\n"; +$lang->action->desc->restarted = '$date, continued by $actor.' . "\n"; +$lang->action->desc->delayed = '$date, postponed by $actor.' . "\n"; +$lang->action->desc->suspended = '$date, suspended by $actor.' . "\n"; +$lang->action->desc->recordestimate = '$date, recorded by $actor and it cost $extra hours.'; +$lang->action->desc->editestimate = '$date, $actor edited Hour.'; +$lang->action->desc->deleteestimate = '$date, $actor deleted Hour.'; +$lang->action->desc->canceled = '$date, cancelled by $actor.' . "\n"; +$lang->action->desc->svncommited = '$date, $actor committed and the build is #$extra.' . "\n"; +$lang->action->desc->gitcommited = '$date, $actor committed and the build is #$extra.' . "\n"; +$lang->action->desc->finished = '$date, finished by $actor.' . "\n"; +$lang->action->desc->paused = '$date, paused by $actor.' . "\n"; +$lang->action->desc->verified = '$date, verified by $actor.' . "\n"; +$lang->action->desc->diff1 = '%s is changed. It was "%s" and it is "%s".
' . "\n"; +$lang->action->desc->diff2 = '%s is changed. The difference is ' . "\n" . "
%s
" . "\n
%s
"; +$lang->action->desc->diff3 = 'File Name %s was changed to %s .' . "\n"; +$lang->action->desc->linked2bug = '$date, linked to $extra by $actor'; +$lang->action->desc->linked2testtask = '$date, linked to $extra by $actor'; +$lang->action->desc->resolved = '$date, resolved by $actor ' . "\n"; +$lang->action->desc->managed = '$date, by $actor managed.' . "\n"; +$lang->action->desc->estimated = '$date, by $actor estimated.' . "\n"; +$lang->action->desc->run = '$date, by $actor executed.' . "\n"; +$lang->action->desc->syncprogram = '$date, started by $actor(starting the project sets the program status as Ongoing).' . "\n"; +$lang->action->desc->syncproject = '$date, starting the execution sets the project status as Ongoing.' . "\n"; +$lang->action->desc->syncexecution = '$date, starting the task sets the execution status as Ongoing.' . "\n"; +$lang->action->desc->importfromgitlab = '$date, Issue associate created from gitlab by $actor.' . "\n"; /* Used to describe the history of operations related to parent-child tasks. */ $lang->action->desc->createchildren = '$date, $actor created a child task $extra。' . "\n"; @@ -304,6 +306,7 @@ $lang->action->label->compilefail = 'Compile Fail'; $lang->action->label->reopen = 'Reopen'; $lang->action->label->approve = 'Passed'; $lang->action->label->reject = 'Rejected'; +$lang->action->label->importfromgitlab = 'Issue associate created'; /* Dynamic information is grouped by object. */ $lang->action->dynamicAction = new stdclass; @@ -354,6 +357,7 @@ $lang->action->dynamicAction->release['notified'] = 'Notify Release'; $lang->action->dynamicAction->release['hidden'] = 'Hide Release'; $lang->action->dynamicAction->story['opened'] = 'Create Story'; +$lang->action->dynamicAction->story['importfromgitlab'] = "Issue associate create story"; $lang->action->dynamicAction->story['edited'] = 'Edit Story'; $lang->action->dynamicAction->story['activated'] = 'Activate Story'; $lang->action->dynamicAction->story['reviewed'] = 'Review Story'; @@ -394,6 +398,7 @@ $lang->action->dynamicAction->kanbanlane['moved'] = 'Move Swimlane'; $lang->action->dynamicAction->team['managedTeam'] = 'Manage Team'; $lang->action->dynamicAction->task['opened'] = 'Create Task'; +$lang->action->dynamicAction->task['importfromgitlab'] = "Issue associate create task"; $lang->action->dynamicAction->task['edited'] = 'Edit Task'; $lang->action->dynamicAction->task['commented'] = 'Task Comment'; $lang->action->dynamicAction->task['assigned'] = 'Assign Task'; @@ -427,6 +432,7 @@ $lang->action->dynamicAction->build['edited'] = 'Edit Build'; $lang->action->dynamicAction->build['deleted'] = 'Delete Build'; $lang->action->dynamicAction->bug['opened'] = 'Report Bug'; +$lang->action->dynamicAction->bug['importfromgitlab'] = "Issue associate create bug"; $lang->action->dynamicAction->bug['edited'] = 'Edit Bug'; $lang->action->dynamicAction->bug['activated'] = 'Activate Bug'; $lang->action->dynamicAction->bug['assigned'] = 'Assign Bug'; @@ -615,6 +621,7 @@ $lang->action->search->label['canceled'] = $lang->action->label->ca $lang->action->search->label['finished'] = $lang->action->label->finished; $lang->action->search->label['paused'] = $lang->action->label->paused; $lang->action->search->label['verified'] = $lang->action->label->verified; +$lang->action->search->label['importfromgitlab'] = $lang->action->label->importfromgitlab; $lang->action->search->label['login'] = $lang->action->label->login; $lang->action->search->label['logout'] = $lang->action->label->logout; diff --git a/module/action/lang/zh-cn.php b/module/action/lang/zh-cn.php index 48f20af743..58fc5a8433 100755 --- a/module/action/lang/zh-cn.php +++ b/module/action/lang/zh-cn.php @@ -79,102 +79,104 @@ $lang->action->periods['lastweek'] = $lang->action->dynamic->lastWeek; $lang->action->periods['thismonth'] = $lang->action->dynamic->thisMonth; $lang->action->periods['lastmonth'] = $lang->action->dynamic->lastMonth; -$lang->action->objectTypes['product'] = $lang->productCommon; -$lang->action->objectTypes['branch'] = '分支'; -$lang->action->objectTypes['story'] = $lang->SRCommon; -$lang->action->objectTypes['design'] = '设计'; -$lang->action->objectTypes['productplan'] = '计划'; -$lang->action->objectTypes['release'] = '发布'; -$lang->action->objectTypes['program'] = '项目集'; -$lang->action->objectTypes['project'] = '项目'; -$lang->action->objectTypes['execution'] = $config->systemMode == 'new' ? '执行' : $lang->executionCommon; -$lang->action->objectTypes['task'] = '任务'; -$lang->action->objectTypes['build'] = '版本'; -$lang->action->objectTypes['job'] = '构建'; -$lang->action->objectTypes['bug'] = 'Bug'; -$lang->action->objectTypes['case'] = '用例'; -$lang->action->objectTypes['caseresult'] = '用例结果'; -$lang->action->objectTypes['stepresult'] = '用例步骤'; -$lang->action->objectTypes['caselib'] = '用例库'; -$lang->action->objectTypes['testsuite'] = '套件'; -$lang->action->objectTypes['testtask'] = '测试单'; -$lang->action->objectTypes['testreport'] = '报告'; -$lang->action->objectTypes['doc'] = '文档'; -$lang->action->objectTypes['api'] = '接口'; -$lang->action->objectTypes['doclib'] = '文档库'; -$lang->action->objectTypes['apistruct'] = '数据结构'; -$lang->action->objectTypes['todo'] = '待办'; -$lang->action->objectTypes['risk'] = '风险'; -$lang->action->objectTypes['issue'] = '问题'; -$lang->action->objectTypes['module'] = '模块'; -$lang->action->objectTypes['user'] = '用户'; -$lang->action->objectTypes['stakeholder'] = '干系人'; -$lang->action->objectTypes['budget'] = '费用估算'; -$lang->action->objectTypes['entry'] = '应用'; -$lang->action->objectTypes['webhook'] = 'Webhook'; -$lang->action->objectTypes['team'] = '团队'; -$lang->action->objectTypes['whitelist'] = '白名单'; -$lang->action->objectTypes['pipeline'] = 'GitLab'; -$lang->action->objectTypes['gitlab'] = 'GitLab'; -$lang->action->objectTypes['jenkins'] = 'Jenkins'; -$lang->action->objectTypes['mr'] = '合并请求'; -$lang->action->objectTypes['gitlabproject'] = 'GitLab项目'; -$lang->action->objectTypes['gitlabuser'] = 'GitLab用户'; -$lang->action->objectTypes['gitlabgroup'] = 'GitLab群组'; -$lang->action->objectTypes['gitlabbranch'] = 'GitLab分支'; +$lang->action->objectTypes['product'] = $lang->productCommon; +$lang->action->objectTypes['branch'] = '分支'; +$lang->action->objectTypes['story'] = $lang->SRCommon; +$lang->action->objectTypes['design'] = '设计'; +$lang->action->objectTypes['productplan'] = '计划'; +$lang->action->objectTypes['release'] = '发布'; +$lang->action->objectTypes['program'] = '项目集'; +$lang->action->objectTypes['project'] = '项目'; +$lang->action->objectTypes['execution'] = $config->systemMode == 'new' ? '执行' : $lang->executionCommon; +$lang->action->objectTypes['task'] = '任务'; +$lang->action->objectTypes['build'] = '版本'; +$lang->action->objectTypes['job'] = '构建'; +$lang->action->objectTypes['bug'] = 'Bug'; +$lang->action->objectTypes['case'] = '用例'; +$lang->action->objectTypes['caseresult'] = '用例结果'; +$lang->action->objectTypes['stepresult'] = '用例步骤'; +$lang->action->objectTypes['caselib'] = '用例库'; +$lang->action->objectTypes['testsuite'] = '套件'; +$lang->action->objectTypes['testtask'] = '测试单'; +$lang->action->objectTypes['testreport'] = '报告'; +$lang->action->objectTypes['doc'] = '文档'; +$lang->action->objectTypes['api'] = '接口'; +$lang->action->objectTypes['doclib'] = '文档库'; +$lang->action->objectTypes['apistruct'] = '数据结构'; +$lang->action->objectTypes['todo'] = '待办'; +$lang->action->objectTypes['risk'] = '风险'; +$lang->action->objectTypes['issue'] = '问题'; +$lang->action->objectTypes['module'] = '模块'; +$lang->action->objectTypes['user'] = '用户'; +$lang->action->objectTypes['stakeholder'] = '干系人'; +$lang->action->objectTypes['budget'] = '费用估算'; +$lang->action->objectTypes['entry'] = '应用'; +$lang->action->objectTypes['webhook'] = 'Webhook'; +$lang->action->objectTypes['team'] = '团队'; +$lang->action->objectTypes['whitelist'] = '白名单'; +$lang->action->objectTypes['pipeline'] = 'GitLab'; +$lang->action->objectTypes['gitlab'] = 'GitLab'; +$lang->action->objectTypes['jenkins'] = 'Jenkins'; +$lang->action->objectTypes['mr'] = '合并请求'; +$lang->action->objectTypes['gitlabproject'] = 'GitLab项目'; +$lang->action->objectTypes['gitlabuser'] = 'GitLab用户'; +$lang->action->objectTypes['gitlabgroup'] = 'GitLab群组'; +$lang->action->objectTypes['gitlabbranch'] = 'GitLab分支'; +$lang->action->objectTypes['gitlabbranchpriv'] = 'GitLab保护分支'; /* 用来描述操作历史记录。*/ $lang->action->desc = new stdclass(); -$lang->action->desc->common = '$date, $action by $actor。' . "\n"; -$lang->action->desc->extra = '$date, $action as $extra by $actor。' . "\n"; -$lang->action->desc->opened = '$date, 由 $actor 创建。' . "\n"; -$lang->action->desc->openedbysystem = '$date, 由系统创建。' . "\n"; -$lang->action->desc->created = '$date, 由 $actor 创建。' . "\n"; -$lang->action->desc->added = '$date, 由 $actor 添加。' . "\n"; -$lang->action->desc->changed = '$date, 由 $actor 变更。' . "\n"; -$lang->action->desc->edited = '$date, 由 $actor 编辑。' . "\n"; -$lang->action->desc->assigned = '$date, 由 $actor 指派给 $extra。' . "\n"; -$lang->action->desc->closed = '$date, 由 $actor 关闭。' . "\n"; -$lang->action->desc->closedbysystem = '$date, 由系统关闭。' . "\n"; -$lang->action->desc->deleted = '$date, 由 $actor 删除。' . "\n"; -$lang->action->desc->deletedfile = '$date, 由 $actor 删除了附件:$extra。' . "\n"; -$lang->action->desc->editfile = '$date, 由 $actor 编辑了附件:$extra。' . "\n"; -$lang->action->desc->erased = '$date, 由 $actor 删除。' . "\n"; -$lang->action->desc->undeleted = '$date, 由 $actor 还原。' . "\n"; -$lang->action->desc->hidden = '$date, 由 $actor 隐藏。' . "\n"; -$lang->action->desc->commented = '$date, 由 $actor 添加备注。' . "\n"; -$lang->action->desc->activated = '$date, 由 $actor 激活。' . "\n"; -$lang->action->desc->blocked = '$date, 由 $actor 阻塞。' . "\n"; -$lang->action->desc->moved = '$date, 由 $actor 移动,之前为 "$extra"。' . "\n"; -$lang->action->desc->confirmed = '$date, 由 $actor 确认' . $lang->SRCommon . '变动,最新版本为#$extra。' . "\n"; -$lang->action->desc->caseconfirmed = '$date, 由 $actor 确认用例变动,最新版本为#$extra。' . "\n"; -$lang->action->desc->bugconfirmed = '$date, 由 $actor 确认Bug。' . "\n"; -$lang->action->desc->frombug = '$date, 由 $actor Bug转化而来,Bug编号为 $extra。'; -$lang->action->desc->started = '$date, 由 $actor 启动。' . "\n"; -$lang->action->desc->restarted = '$date, 由 $actor 继续。' . "\n"; -$lang->action->desc->delayed = '$date, 由 $actor 延期。' . "\n"; -$lang->action->desc->suspended = '$date, 由 $actor 挂起。' . "\n"; -$lang->action->desc->recordestimate = '$date, 由 $actor 记录工时,消耗 $extra 小时。'; -$lang->action->desc->editestimate = '$date, 由 $actor 编辑工时。'; -$lang->action->desc->deleteestimate = '$date, 由 $actor 删除工时。'; -$lang->action->desc->canceled = '$date, 由 $actor 取消。' . "\n"; -$lang->action->desc->svncommited = '$date, 由 $actor 提交代码,版本为#$extra。' . "\n"; -$lang->action->desc->gitcommited = '$date, 由 $actor 提交代码,版本为#$extra。' . "\n"; -$lang->action->desc->finished = '$date, 由 $actor 完成。' . "\n"; -$lang->action->desc->paused = '$date, 由 $actor 暂停。' . "\n"; -$lang->action->desc->verified = '$date, 由 $actor 验收。' . "\n"; -$lang->action->desc->diff1 = '修改了 %s,旧值为 "%s",新值为 "%s"。
' . "\n"; -$lang->action->desc->diff2 = '修改了 %s,区别为:' . "\n" . "
%s
" . "\n
%s
"; -$lang->action->desc->diff3 = '将文件名 %s 改为 %s 。' . "\n"; -$lang->action->desc->linked2bug = '$date 由 $actor 关联到版本 $extra'; -$lang->action->desc->linked2testtask = '$date 由 $actor 关联到测试单 $extra'; -$lang->action->desc->resolved = '$date, 由 $actor 解决。' . "\n"; -$lang->action->desc->managed = '$date, 由 $actor 维护。' . "\n"; -$lang->action->desc->estimated = '$date, 由 $actor 估算。' . "\n"; -$lang->action->desc->run = '$date, 由 $actor 执行。' . "\n"; -$lang->action->desc->syncprogram = '$date, 由 $actor 启动(因项目开始而启动项目集)。' . "\n"; -$lang->action->desc->syncproject = '$date, 系统判断由于执行开始,将项目状态置为进行中。' . "\n"; -$lang->action->desc->syncexecution = '$date, 系统判断由于任务开始,将执行状态置为进行中。' . "\n"; +$lang->action->desc->common = '$date, $action by $actor。' . "\n"; +$lang->action->desc->extra = '$date, $action as $extra by $actor。' . "\n"; +$lang->action->desc->opened = '$date, 由 $actor 创建。' . "\n"; +$lang->action->desc->openedbysystem = '$date, 由系统创建。' . "\n"; +$lang->action->desc->created = '$date, 由 $actor 创建。' . "\n"; +$lang->action->desc->added = '$date, 由 $actor 添加。' . "\n"; +$lang->action->desc->changed = '$date, 由 $actor 变更。' . "\n"; +$lang->action->desc->edited = '$date, 由 $actor 编辑。' . "\n"; +$lang->action->desc->assigned = '$date, 由 $actor 指派给 $extra。' . "\n"; +$lang->action->desc->closed = '$date, 由 $actor 关闭。' . "\n"; +$lang->action->desc->closedbysystem = '$date, 由系统关闭。' . "\n"; +$lang->action->desc->deleted = '$date, 由 $actor 删除。' . "\n"; +$lang->action->desc->deletedfile = '$date, 由 $actor 删除了附件:$extra。' . "\n"; +$lang->action->desc->editfile = '$date, 由 $actor 编辑了附件:$extra。' . "\n"; +$lang->action->desc->erased = '$date, 由 $actor 删除。' . "\n"; +$lang->action->desc->undeleted = '$date, 由 $actor 还原。' . "\n"; +$lang->action->desc->hidden = '$date, 由 $actor 隐藏。' . "\n"; +$lang->action->desc->commented = '$date, 由 $actor 添加备注。' . "\n"; +$lang->action->desc->activated = '$date, 由 $actor 激活。' . "\n"; +$lang->action->desc->blocked = '$date, 由 $actor 阻塞。' . "\n"; +$lang->action->desc->moved = '$date, 由 $actor 移动,之前为 "$extra"。' . "\n"; +$lang->action->desc->confirmed = '$date, 由 $actor 确认' . $lang->SRCommon . '变动,最新版本为#$extra。' . "\n"; +$lang->action->desc->caseconfirmed = '$date, 由 $actor 确认用例变动,最新版本为#$extra。' . "\n"; +$lang->action->desc->bugconfirmed = '$date, 由 $actor 确认Bug。' . "\n"; +$lang->action->desc->frombug = '$date, 由 $actor Bug转化而来,Bug编号为 $extra。'; +$lang->action->desc->started = '$date, 由 $actor 启动。' . "\n"; +$lang->action->desc->restarted = '$date, 由 $actor 继续。' . "\n"; +$lang->action->desc->delayed = '$date, 由 $actor 延期。' . "\n"; +$lang->action->desc->suspended = '$date, 由 $actor 挂起。' . "\n"; +$lang->action->desc->recordestimate = '$date, 由 $actor 记录工时,消耗 $extra 小时。'; +$lang->action->desc->editestimate = '$date, 由 $actor 编辑工时。'; +$lang->action->desc->deleteestimate = '$date, 由 $actor 删除工时。'; +$lang->action->desc->canceled = '$date, 由 $actor 取消。' . "\n"; +$lang->action->desc->svncommited = '$date, 由 $actor 提交代码,版本为#$extra。' . "\n"; +$lang->action->desc->gitcommited = '$date, 由 $actor 提交代码,版本为#$extra。' . "\n"; +$lang->action->desc->finished = '$date, 由 $actor 完成。' . "\n"; +$lang->action->desc->paused = '$date, 由 $actor 暂停。' . "\n"; +$lang->action->desc->verified = '$date, 由 $actor 验收。' . "\n"; +$lang->action->desc->diff1 = '修改了 %s,旧值为 "%s",新值为 "%s"。
' . "\n"; +$lang->action->desc->diff2 = '修改了 %s,区别为:' . "\n" . "
%s
" . "\n
%s
"; +$lang->action->desc->diff3 = '将文件名 %s 改为 %s 。' . "\n"; +$lang->action->desc->linked2bug = '$date 由 $actor 关联到版本 $extra'; +$lang->action->desc->linked2testtask = '$date 由 $actor 关联到测试单 $extra'; +$lang->action->desc->resolved = '$date, 由 $actor 解决。' . "\n"; +$lang->action->desc->managed = '$date, 由 $actor 维护。' . "\n"; +$lang->action->desc->estimated = '$date, 由 $actor 估算。' . "\n"; +$lang->action->desc->run = '$date, 由 $actor 执行。' . "\n"; +$lang->action->desc->syncprogram = '$date, 由 $actor 启动(因项目开始而启动项目集)。' . "\n"; +$lang->action->desc->syncproject = '$date, 系统判断由于执行开始,将项目状态置为进行中。' . "\n"; +$lang->action->desc->syncexecution = '$date, 系统判断由于任务开始,将执行状态置为进行中。' . "\n"; +$lang->action->desc->importfromgitlab = '$date, 由 $actor 从Gitlab的Issue关联创建。' . "\n"; /* 用来描述和父子任务相关的操作历史记录。*/ $lang->action->desc->createchildren = '$date, 由 $actor 创建子任务 $extra。' . "\n"; @@ -304,6 +306,7 @@ $lang->action->label->compilefail = '构建失败'; $lang->action->label->reopen = '重新打开'; $lang->action->label->approve = '通过了'; $lang->action->label->reject = '拒绝了'; +$lang->action->label->importfromgitlab = '从Gitlab关联创建了'; /* 动态信息按照对象分组 */ $lang->action->dynamicAction = new stdclass(); @@ -354,6 +357,7 @@ $lang->action->dynamicAction->release['notified'] = '通知发布'; $lang->action->dynamicAction->release['hidden'] = '隐藏发布'; $lang->action->dynamicAction->story['opened'] = "创建{$lang->SRCommon}"; +$lang->action->dynamicAction->story['importfromgitlab'] = "从Gitlab关联创建{$lang->SRCommon}"; $lang->action->dynamicAction->story['edited'] = "编辑{$lang->SRCommon}"; $lang->action->dynamicAction->story['activated'] = "激活{$lang->SRCommon}"; $lang->action->dynamicAction->story['reviewed'] = "评审{$lang->SRCommon}"; @@ -394,6 +398,7 @@ $lang->action->dynamicAction->kanbanlane['moved'] = '移动泳道'; $lang->action->dynamicAction->team['managedTeam'] = '维护团队'; $lang->action->dynamicAction->task['opened'] = '创建任务'; +$lang->action->dynamicAction->task['importfromgitlab'] = "从Gitlab关联创建任务"; $lang->action->dynamicAction->task['edited'] = '编辑任务'; $lang->action->dynamicAction->task['commented'] = '备注任务'; $lang->action->dynamicAction->task['assigned'] = '指派任务'; @@ -427,6 +432,7 @@ $lang->action->dynamicAction->build['edited'] = '编辑版本'; $lang->action->dynamicAction->build['deleted'] = '删除版本'; $lang->action->dynamicAction->bug['opened'] = '创建Bug'; +$lang->action->dynamicAction->bug['importfromgitlab'] = "从Gitlab关联创建Bug"; $lang->action->dynamicAction->bug['edited'] = '编辑Bug'; $lang->action->dynamicAction->bug['activated'] = '激活Bug'; $lang->action->dynamicAction->bug['assigned'] = '指派Bug'; @@ -615,6 +621,7 @@ $lang->action->search->label['canceled'] = $lang->action->label->ca $lang->action->search->label['finished'] = $lang->action->label->finished; $lang->action->search->label['paused'] = $lang->action->label->paused; $lang->action->search->label['verified'] = $lang->action->label->verified; +$lang->action->search->label['importfromgitlab'] = $lang->action->label->importfromgitlab; $lang->action->search->label['login'] = $lang->action->label->login; $lang->action->search->label['logout'] = $lang->action->label->logout; diff --git a/module/gitlab/control.php b/module/gitlab/control.php index 5206321ea7..d6e34fc2c2 100644 --- a/module/gitlab/control.php +++ b/module/gitlab/control.php @@ -948,7 +948,6 @@ class gitlab extends control if($gitlab) $user = $this->gitlab->apiGetCurrentUser($gitlab->url, $gitlab->token); if(empty($user->is_admin)) die(js::alert($this->lang->gitlab->tokenLimit) . js::locate($this->createLink('gitlab', 'edit', array('gitlabID' => $gitlabID)))); - if($_POST) { $executionList = $this->post->executionList; @@ -958,38 +957,40 @@ class gitlab extends control $failedIssues = array(); foreach($executionList as $issueID => $executionID) { - if($executionID) + if(empty($executionID) and $productList[$issueID] != 0) return $this->send(array('result' => 'fail', 'message' => $this->lang->gitlab->importIssueError, 'locate' => $this->server->http_referer)); + } + + foreach($executionList as $issueID => $executionID) + { + if(empty($executionID)) continue; + + $objectType = $objectTypeList[$issueID]; + + $issue = $this->gitlab->apiGetSingleIssue($gitlabID, $projectID, $issueID); + $issue->objectType = $objectType; + $issue->objectID = 0; // Meet the required parameters for issueToZentaoObject. + if(isset($issue->assignee)) $issue->assignee_id = $issue->assignee->id; + $issue->updated_by_id = $issue->author->id; // Here can be replaced by current zentao user. + + $object = $this->gitlab->issueToZentaoObject($issue, $gitlabID); + $object->product = $productList[$issueID]; + $object->execution = $executionID; + $clonedObject = clone $object; + + if($objectType == 'task') $objectID = $this->loadModel('task')->createTaskFromGitlabIssue($clonedObject, $executionID); + if($objectType == 'bug') $objectID = $this->loadModel('bug')->createBugFromGitlabIssue($clonedObject, $executionID); + if($objectType == 'story') $objectID = $this->loadModel('story')->createStoryFromGitlabIssue($clonedObject, $executionID); + + if($objectID) { - $objectType = $objectTypeList[$issueID]; + $this->loadModel('action')->create($objectType, $objectID, 'ImportFromGitlab', '', $issueID); - $issue = $this->gitlab->apiGetSingleIssue($gitlabID, $projectID, $issueID); - $issue->objectType = $objectType; - $issue->objectID = 0; // Meet the required parameters for issueToZentaoObject. - if(isset($issue->assignee)) $issue->assignee_id = $issue->assignee->id; - $issue->updated_by_id = $issue->author->id; // Here can be replaced by current zentao user. - - $object = $this->gitlab->issueToZentaoObject($issue, $gitlabID); - $object->product = $productList[$issueID]; - $object->execution = $executionID; - $clonedObject = clone $object; - - if($objectType == 'task') $objectID = $this->loadModel('task')->createTaskFromGitlabIssue($clonedObject, $executionID); - if($objectType == 'bug') $objectID = $this->loadModel('bug')->createBugFromGitlabIssue($clonedObject, $executionID); - if($objectType == 'story') $objectID = $this->loadModel('story')->createStoryFromGitlabIssue($clonedObject, $executionID); - - if($objectID) - { - $object->id = $objectID; - $this->gitlab->saveImportedIssue($gitlabID, $projectID, $objectType, $objectID, $issue, $object); - } - else - { - $failedIssues[] = $issue->iid; - } + $object->id = $objectID; + $this->gitlab->saveImportedIssue($gitlabID, $projectID, $objectType, $objectID, $issue, $object); } else { - if($productList[$issueID] != 0) return $this->send(array('result' => 'fail', 'message' => $this->lang->gitlab->importIssueError, 'locate' => $this->server->http_referer)); + $failedIssues[] = $issue->iid; } } diff --git a/module/gitlab/js/managegroupmembers.js b/module/gitlab/js/managegroupmembers.js index 589e0ffc61..a9391db43b 100644 --- a/module/gitlab/js/managegroupmembers.js +++ b/module/gitlab/js/managegroupmembers.js @@ -41,6 +41,25 @@ function addItem(obj) */ function deleteItem(obj) { - if($('#teamForm .table tbody').children().length < 2) return false; + if($('#teamForm .table-form tbody').children().length < 2) return false; $(obj).closest('tr').remove(); -} \ No newline at end of file +} + +$(document).on('change', '[id^="levels"]', function() +{ + $tr = $(this).closest('tr'); + $next = $(this).closest('td').next() + var ownerLevel = 50; + if($(this).val() == ownerLevel) + { + $next.prepend(''); + $next.find('[id^="expires"]').addClass('hidden'); + $tr.find('a[onclick^="deleteItem"]').addClass('disabled'); + } + else + { + $next.find('[id^="expires"]').removeClass('hidden'); + $next.find('input.disabled').remove(); + $tr.find('a[onclick^="deleteItem"]').removeClass('disabled'); + } +}) diff --git a/module/gitlab/js/manageprojectmembers.js b/module/gitlab/js/manageprojectmembers.js index 589e0ffc61..f67e13d81e 100644 --- a/module/gitlab/js/manageprojectmembers.js +++ b/module/gitlab/js/manageprojectmembers.js @@ -41,6 +41,6 @@ function addItem(obj) */ function deleteItem(obj) { - if($('#teamForm .table tbody').children().length < 2) return false; + if($('#teamForm .table-form tbody').children().length < 2) return false; $(obj).closest('tr').remove(); -} \ No newline at end of file +} diff --git a/module/gitlab/lang/en.php b/module/gitlab/lang/en.php index cf6809d55d..b03cf87c94 100644 --- a/module/gitlab/lang/en.php +++ b/module/gitlab/lang/en.php @@ -63,7 +63,7 @@ $lang->gitlab->lblCreate = 'Create GitLab Server'; $lang->gitlab->desc = 'Description'; $lang->gitlab->tokenFirst = 'When the Token is not empty, the Token will be used first'; $lang->gitlab->tips = 'When using a password, please disable the "Prevent cross-site request forgery" option in the GitLab global security settings.'; -$lang->gitlab->emptyError = "cannot be empty"; +$lang->gitlab->emptyError = " cannot be empty"; $lang->gitlab->createSuccess = "Create success"; $lang->gitlab->placeholder = new stdclass; @@ -91,12 +91,14 @@ $lang->gitlab->apiError[1] = 'public is not allowed in a private group.'; $lang->gitlab->apiError[2] = 'is too short (minimum is 8 characters)'; $lang->gitlab->apiError[3] = "can contain only letters, digits, '_', '-' and '.'. Cannot start with '-', end in '.git' or end in '.atom'"; $lang->gitlab->apiError[4] = 'Branch already exists'; +$lang->gitlab->apiError[5] = 'Failed to save group {:path=>["has already been taken"]}'; $lang->gitlab->errorLang[0] = 'You cannot set Internal as its Visibility Level, if it is private in GitLab.'; $lang->gitlab->errorLang[1] = 'You cannot set Public as its Visibility Level, if it is private in GitLab.'; $lang->gitlab->errorLang[2] = 'Password is too short (minimum is 8 characters)'; $lang->gitlab->errorLang[3] = 'It should contain only letters, digits, underscore, hyphen and period. It should not start with hypen, or end with .git or .atom.'; $lang->gitlab->errorLang[4] = 'Branch already exists.'; +$lang->gitlab->errorLang[5] = 'Failed to save group, path has already been taken.'; $lang->gitlab->project = new stdclass; $lang->gitlab->project->id = "Project ID"; @@ -184,7 +186,7 @@ $lang->gitlab->group->memberExpiresAt = 'Expiration time $lang->gitlab->group->repeatError = "Group members cannot be added repeatedly"; $lang->gitlab->branch = new stdclass(); -$lang->gitlab->branch->name = 'Branch Name'; +$lang->gitlab->branch->name = 'Branch name'; $lang->gitlab->branch->from = 'Create from'; $lang->gitlab->branch->create = 'Create'; $lang->gitlab->branch->lastCommitter = 'Last Committer'; diff --git a/module/gitlab/lang/zh-cn.php b/module/gitlab/lang/zh-cn.php index 3b58bb2bcf..658367e491 100644 --- a/module/gitlab/lang/zh-cn.php +++ b/module/gitlab/lang/zh-cn.php @@ -91,12 +91,14 @@ $lang->gitlab->apiError[1] = 'public is not allowed in a private group.'; $lang->gitlab->apiError[2] = 'is too short (minimum is 8 characters)'; $lang->gitlab->apiError[3] = "can contain only letters, digits, '_', '-' and '.'. Cannot start with '-', end in '.git' or end in '.atom'"; $lang->gitlab->apiError[4] = 'Branch already exists'; +$lang->gitlab->apiError[5] = 'Failed to save group {:path=>["has already been taken"]}'; $lang->gitlab->errorLang[0] = '私有分组的项目,可见性级别不能设为内部。'; $lang->gitlab->errorLang[1] = '私有分组的项目,可见性级别不能设为公开。'; $lang->gitlab->errorLang[2] = '密码太短(最少8个字符)'; $lang->gitlab->errorLang[3] = "只能包含字母、数字、'.'-'和'.'。不能以'-'开头、以'.git'结尾或以'.atom'结尾。"; $lang->gitlab->errorLang[4] = '分支名已存在。'; +$lang->gitlab->errorLang[5] = '保存失败,群组URL路径已经被使用。'; $lang->gitlab->project = new stdclass; $lang->gitlab->project->id = "项目ID"; diff --git a/module/gitlab/model.php b/module/gitlab/model.php index 246d7ff619..672e8f7a07 100644 --- a/module/gitlab/model.php +++ b/module/gitlab/model.php @@ -2050,15 +2050,15 @@ class gitlabModel extends model if(empty($project->path)) dao::$errors['path'][] = $this->lang->gitlab->project->emptyPathError; if(dao::isError()) return false; - $reponse = $this->apiCreateProject($gitlabID, $project); + $response = $this->apiCreateProject($gitlabID, $project); - if(!empty($reponse->id)) + if(!empty($response->id)) { - $this->loadModel('action')->create('gitlabproject', $reponse->id, 'created', '', $reponse->name); + $this->loadModel('action')->create('gitlabproject', $response->id, 'created', '', $response->name); return true; } - return $this->apiErrorHandling($reponse); + return $this->apiErrorHandling($response); } /** @@ -2074,15 +2074,15 @@ class gitlabModel extends model if(empty($project->name)) dao::$errors['name'][] = $this->lang->gitlab->project->emptyNameError; if(dao::isError()) return false; - $reponse = $this->apiUpdateProject($gitlabID, $project); + $response = $this->apiUpdateProject($gitlabID, $project); - if(!empty($reponse->id)) + if(!empty($response->id)) { $this->loadModel('action')->create('gitlabproject', $project->id, 'edited', '', $project->name); return true; } - return $this->apiErrorHandling($reponse); + return $this->apiErrorHandling($response); } /** @@ -2119,11 +2119,11 @@ class gitlabModel extends model } } - $reponse = $this->apiCreateUser($gitlabID, $user); + $response = $this->apiCreateUser($gitlabID, $user); - if(!empty($reponse->id)) + if(!empty($response->id)) { - $this->loadModel('action')->create('gitlabuser', $reponse->id, 'created', '', $reponse->name); + $this->loadModel('action')->create('gitlabuser', $response->id, 'created', '', $response->name); /* Bind user. */ if($user->account) @@ -2132,13 +2132,13 @@ class gitlabModel extends model $userBind->providerID = $gitlabID; $userBind->providerType = 'gitlab'; $userBind->account = $user->account; - $userBind->openID = $reponse->id; + $userBind->openID = $response->id; $this->dao->insert(TABLE_OAUTH)->data($userBind)->exec(); } return true; } - return $this->apiErrorHandling($reponse); + return $this->apiErrorHandling($response); } /** @@ -2179,14 +2179,14 @@ class gitlabModel extends model } } - $reponse = $this->apiUpdateUser($gitlabID, $user); + $response = $this->apiUpdateUser($gitlabID, $user); - if(!empty($reponse->id)) + if(!empty($response->id)) { - $this->loadModel('action')->create('gitlabuser', $reponse->id, 'edited', '', $reponse->name); + $this->loadModel('action')->create('gitlabuser', $response->id, 'edited', '', $response->name); /* Delete old bind. */ - $this->dao->delete()->from(TABLE_OAUTH)->where('providerType')->eq('gitlab')->andWhere('providerID')->eq($gitlabID)->andWhere('openID')->eq($reponse->id)->andWhere('account')->ne($user->account)->exec(); + $this->dao->delete()->from(TABLE_OAUTH)->where('providerType')->eq('gitlab')->andWhere('providerID')->eq($gitlabID)->andWhere('openID')->eq($response->id)->andWhere('account')->ne($user->account)->exec(); /* Bind user. */ if($user->account && $changeBind) { @@ -2194,13 +2194,13 @@ class gitlabModel extends model $userBind->providerID = $gitlabID; $userBind->providerType = 'gitlab'; $userBind->account = $user->account; - $userBind->openID = $reponse->id; + $userBind->openID = $response->id; $this->dao->replace(TABLE_OAUTH)->data($userBind)->exec(); } return true; } - return $this->apiErrorHandling($reponse); + return $this->apiErrorHandling($response); } /** @@ -2218,15 +2218,15 @@ class gitlabModel extends model if(empty($group->path)) dao::$errors['path'][] = $this->lang->gitlab->group->path . $this->lang->gitlab->group->emptyError; if(dao::isError()) return false; - $reponse = $this->apiCreateGroup($gitlabID, $group); + $response = $this->apiCreateGroup($gitlabID, $group); - if(!empty($reponse->id)) + if(!empty($response->id)) { - $this->loadModel('action')->create('gitlabgroup', $reponse->id, 'created', '', $reponse->name); + $this->loadModel('action')->create('gitlabgroup', $response->id, 'created', '', $response->name); return true; } - return $this->apiErrorHandling($reponse); + return $this->apiErrorHandling($response); } /** @@ -2243,15 +2243,15 @@ class gitlabModel extends model if(empty($group->name)) dao::$errors['name'][] = $this->lang->gitlab->group->name . $this->lang->gitlab->group->emptyError; if(dao::isError()) return false; - $reponse = $this->apiUpdateGroup($gitlabID, $group); + $response = $this->apiUpdateGroup($gitlabID, $group); - if(!empty($reponse->id)) + if(!empty($response->id)) { - $this->loadModel('action')->create('gitlabgroup', $reponse->id, 'edited', '', $reponse->name); + $this->loadModel('action')->create('gitlabgroup', $response->id, 'edited', '', $response->name); return true; } - return $this->apiErrorHandling($reponse); + return $this->apiErrorHandling($response); } /** @@ -2270,41 +2270,41 @@ class gitlabModel extends model if(empty($branch->ref)) dao::$errors['ref'][] = $this->lang->gitlab->branch->from . $this->lang->gitlab->emptyError; if(dao::isError()) return false; - $reponse = $this->apiCreateBranch($gitlabID, $projectID, $branch); + $response = $this->apiCreateBranch($gitlabID, $projectID, $branch); - if(!empty($reponse->name)) + if(!empty($response->name)) { - $this->loadModel('action')->create('gitlabbranch', 0, 'created', '', $reponse->name); + $this->loadModel('action')->create('gitlabbranch', 0, 'created', '', $response->name); return true; } - return $this->apiErrorHandling($reponse); + return $this->apiErrorHandling($response); } /** * Api error handling. * - * @param object $reponse + * @param object $response * @access public * @return bool */ - public function apiErrorHandling($reponse) + public function apiErrorHandling($response) { - if(!empty($reponse->error)) + if(!empty($response->error)) { - dao::$errors[] = $reponse->error; + dao::$errors[] = $response->error; return false; } - if(!empty($reponse->message)) + if(!empty($response->message)) { - if(is_string($reponse->message)) + if(is_string($response->message)) { - $errorKey = array_search($reponse->message, $this->lang->gitlab->apiError); - dao::$errors[] = $errorKey === false ? $reponse->message : zget($this->lang->gitlab->errorLang, $errorKey); + $errorKey = array_search($response->message, $this->lang->gitlab->apiError); + dao::$errors[] = $errorKey === false ? $response->message : zget($this->lang->gitlab->errorLang, $errorKey); } else { - foreach($reponse->message as $field => $fieldErrors) + foreach($response->message as $field => $fieldErrors) { foreach($fieldErrors as $error) { @@ -2315,7 +2315,7 @@ class gitlabModel extends model } } - if(!$reponse) dao::$errors[] = false; + if(!$response) dao::$errors[] = false; return false; } @@ -2397,9 +2397,9 @@ class gitlabModel extends model $singleBranch = $this->apiGetSingleBranchPriv($gitlabID, $projectID, $priv->name); if(empty($branch) && !empty($singleBranch->id)) dao::$errors['name'][] = $this->lang->gitlab->branch->issetPrivNameError; if(dao::isError()) return false; - if(!empty($branch) && !empty($singleBranch->id)) $this->apiDeleteBranchPriv($gitlabID, $projectID, $branch); + if(!empty($branch) && !empty($singleBranch->id)) $this->apiDeleteBranchPriv($gitlabID, $projectID, $branch); - $response = $this->apiCreateBranchPriv($gitlabID, $projectID, $priv); + $response = $this->apiCreateBranchPriv($gitlabID, $projectID, $priv); if(!empty($response->id)) { diff --git a/module/gitlab/view/binduser.html.php b/module/gitlab/view/binduser.html.php index 107697b1e2..381867a303 100644 --- a/module/gitlab/view/binduser.html.php +++ b/module/gitlab/view/binduser.html.php @@ -21,7 +21,7 @@ gitlab->gitlabAccount;?> - gitlab->zentaoAccount;?> + gitlab->zentaoAccount;?> gitlab->bindingStatus;?> @@ -51,7 +51,8 @@ id]", $userPairs, $gitlabUser->zentaoAccount, "class='form-control select chosen'" );?> zentaoAccount])):?> - zentaoAccount, ''))):?> + zentaoAccount, '');?> + gitlab->binded;?> ' . $lang->gitlab->bindedError . '';?> diff --git a/module/gitlab/view/browse.html.php b/module/gitlab/view/browse.html.php index 07d3783305..b682227146 100644 --- a/module/gitlab/view/browse.html.php +++ b/module/gitlab/view/browse.html.php @@ -47,11 +47,11 @@ isAdminToken) ? '' : 'disabled'; - common::printLink('gitlab', 'browseProject', "gitlabID=$id", " ", '',"title={$lang->gitlab->browseProject} class='btn btn-primary'"); - common::printLink('gitlab', 'browseGroup', "gitlabID=$id", " ", '', "title={$lang->gitlab->browseGroup} class='btn btn-primary'"); - common::printLink('gitlab', 'edit', "gitlabID=$id", " ", '',"title={$lang->gitlab->edit} class='btn btn-primary'"); - common::printLink('gitlab', 'browseUser', "gitlabID=$id", " ", '', "title={$lang->gitlab->browseUser} class='btn {$disabled}' ,'disabled'"); - common::printLink('gitlab', 'bindUser', "id=$id", " ", '', "title={$lang->gitlab->bindUser} class='btn {$disabled}' ,'disabled'"); + common::printLink('gitlab', 'browseProject', "gitlabID=$id", " ", '',"title='{$lang->gitlab->browseProject}' class='btn btn-primary'"); + common::printLink('gitlab', 'browseGroup', "gitlabID=$id", " ", '', "title='{$lang->gitlab->browseGroup}' class='btn btn-primary'"); + common::printLink('gitlab', 'edit', "gitlabID=$id", " ", '',"title='{$lang->gitlab->edit}' class='btn btn-primary'"); + common::printLink('gitlab', 'browseUser', "gitlabID=$id", " ", '', "title='{$lang->gitlab->browseUser}' class='btn {$disabled}' ,'disabled'"); + common::printLink('gitlab', 'bindUser', "id=$id", " ", '', "title='{$lang->gitlab->bindUser}' class='btn {$disabled}' ,'disabled'"); if(common::hasPriv('gitlab', 'delete')) echo html::a($this->createLink('gitlab', 'delete', "gitlabID=$id"), '', 'hiddenwin', "title='{$lang->gitlab->delete}' class='btn'"); ?> diff --git a/module/gitlab/view/browsegroup.html.php b/module/gitlab/view/browsegroup.html.php index 77302dc4a0..30e60c5187 100644 --- a/module/gitlab/view/browsegroup.html.php +++ b/module/gitlab/view/browsegroup.html.php @@ -54,8 +54,8 @@ created_at, 0, 10);?> id", " ", '',"title={$lang->gitlab->group->manageMembers} class='btn btn-primary'"); - common::printLink('gitlab', 'editGroup', "gitlabID=$gitlabID&groupID=$gitlabGroup->id", " ", '', "title={$lang->gitlab->group->edit} class='btn btn-primary'"); + common::printLink('gitlab', 'manageGroupMembers', "gitlabID=$gitlabID&groupID=$gitlabGroup->id", " ", '',"title='{$lang->gitlab->group->manageMembers}' class='btn btn-primary'"); + common::printLink('gitlab', 'editGroup', "gitlabID=$gitlabID&groupID=$gitlabGroup->id", " ", '', "title='{$lang->gitlab->group->edit}' class='btn btn-primary'"); if(common::hasPriv('gitlab', 'delete')) echo html::a($this->createLink('gitlab', 'deleteGroup', "gitlabID=$gitlabID&groupID=$gitlabGroup->id"), '', 'hiddenwin', "title='{$lang->gitlab->deleteGroup}' class='btn'"); ?> diff --git a/module/gitlab/view/browseproject.html.php b/module/gitlab/view/browseproject.html.php index 0b4312e8d4..ab0bcfadad 100644 --- a/module/gitlab/view/browseproject.html.php +++ b/module/gitlab/view/browseproject.html.php @@ -67,9 +67,10 @@ last_activity_at, 0, 10);?> id", " ", '', "title={$lang->gitlab->browseBranch} class='btn btn-primary'"); - common::printLink('gitlab', 'browseBranchPriv', "gitlabID=$gitlabID&projectID=$gitlabProject->id", " ", '', "title={$lang->gitlab->branch->accessLevel} class='btn btn-primary'"); - common::printLink('gitlab', 'editProject', "gitlabID=$gitlabID&projectID=$gitlabProject->id", " ", '', "title={$lang->gitlab->project->edit} class='btn btn-primary'"); + + common::printLink('gitlab', 'browseBranch', "gitlabID=$gitlabID&projectID=$gitlabProject->id", " ", '', "title='{$lang->gitlab->browseBranch}' class='btn btn-primary'"); + common::printLink('gitlab', 'browseBranchPriv', "gitlabID=$gitlabID&projectID=$gitlabProject->id", " ", '', "title='{$lang->gitlab->branch->accessLevel}' class='btn btn-primary'"); + common::printLink('gitlab', 'editProject', "gitlabID=$gitlabID&projectID=$gitlabProject->id", " ", '', "title='{$lang->gitlab->project->edit}' class='btn btn-primary'"); if(common::hasPriv('gitlab', 'delete')) echo html::a($this->createLink('gitlab', 'deleteProject', "gitlabID=$gitlabID&projectID=$gitlabProject->id"), '', 'hiddenwin', "title='{$lang->gitlab->deleteProject}' class='btn'"); ?> diff --git a/module/gitlab/view/browseuser.html.php b/module/gitlab/view/browseuser.html.php index a01e10c2ab..d1c9e3e0d5 100644 --- a/module/gitlab/view/browseuser.html.php +++ b/module/gitlab/view/browseuser.html.php @@ -54,7 +54,7 @@ lastActivityOn, 0, 10);?> id", " ", '', "title={$lang->gitlab->user->edit} class='btn btn-primary'"); + common::printLink('gitlab', 'editUser', "gitlabID=$gitlabID&userID=$gitlabUser->id", " ", '', "title='{$lang->gitlab->user->edit}' class='btn btn-primary'"); if(common::hasPriv('gitlab', 'delete')) echo html::a($this->createLink('gitlab', 'deleteUser', "gitlabID=$gitlabID&userID=$gitlabUser->id"), '', 'hiddenwin', "title='{$lang->gitlab->deleteUser}' class='btn'"); ?> diff --git a/module/gitlab/view/createproject.html.php b/module/gitlab/view/createproject.html.php index 34641ae86b..a2766dbe0b 100644 --- a/module/gitlab/view/createproject.html.php +++ b/module/gitlab/view/createproject.html.php @@ -20,9 +20,9 @@
- + - + diff --git a/module/gitlab/view/editproject.html.php b/module/gitlab/view/editproject.html.php index b160c44bcd..3522ee85ff 100644 --- a/module/gitlab/view/editproject.html.php +++ b/module/gitlab/view/editproject.html.php @@ -20,8 +20,9 @@
gitlab->project->name;?>gitlab->project->name;?> gitlab->project->name}'");?>
gitlab->project->url;?>
- + + diff --git a/module/gitlab/view/managegroupmembers.html.php b/module/gitlab/view/managegroupmembers.html.php index 648d13210e..08d5891c51 100644 --- a/module/gitlab/view/managegroupmembers.html.php +++ b/module/gitlab/view/managegroupmembers.html.php @@ -19,18 +19,24 @@ + diff --git a/module/group/lang/resource.php b/module/group/lang/resource.php index 82bce8e379..8e1c28bbfb 100644 --- a/module/group/lang/resource.php +++ b/module/group/lang/resource.php @@ -1298,7 +1298,7 @@ $lang->resource->mr->unlink = 'unlink'; $lang->resource->mr->approval = 'approval'; $lang->resource->mr->close = 'close'; $lang->resource->mr->reopen = 'reopen'; -$lang->resource->mr->addBug = 'addBug'; +$lang->resource->mr->addReview = 'addReview'; $lang->mr->methodOrder[10] = 'create'; $lang->mr->methodOrder[15] = 'browse'; @@ -1315,7 +1315,7 @@ $lang->mr->methodOrder[75] = 'unlink'; $lang->mr->methodOrder[80] = 'approval'; $lang->mr->methodOrder[85] = 'close'; $lang->mr->methodOrder[90] = 'reopen'; -$lang->mr->methodOrder[95] = 'addBug'; +$lang->mr->methodOrder[95] = 'addReview'; /* Git. */ $lang->resource->git = new stdclass(); diff --git a/module/mr/control.php b/module/mr/control.php index aba3903a58..674f66e75d 100644 --- a/module/mr/control.php +++ b/module/mr/control.php @@ -300,7 +300,7 @@ class mr extends control * @access public * @return void */ - public function diff($MRID, $encoding= '') + public function diff($MRID, $encoding = '') { $this->app->loadLang('productplan'); $this->app->loadLang('bug'); @@ -316,7 +316,7 @@ class mr extends control $this->view->rawMR = $rawMR; if(!isset($rawMR->id) or (isset($rawMR->message) and $rawMR->message == '404 Not found') or empty($rawMR)) return $this->display(); - $diffs = $this->mr->getDiffs($MR, $encoding = ''); + $diffs = $this->mr->getDiffs($MR, $encoding); $arrange = $this->cookie->arrange ? $this->cookie->arrange : 'inline'; if($this->server->request_method == 'POST') @@ -455,7 +455,6 @@ class mr extends control $this->view->modulePairs = $this->loadModel('tree')->getOptionMenu($product->id, 'story'); $this->view->users = $this->loadModel('user')->getPairs('noletter'); $this->view->stories = $stories; - $this->view->summary = $this->loadModel('product')->summary($stories); $this->view->bugs = $bugs; $this->view->tasks = $tasks; $this->view->product = $product; @@ -782,49 +781,37 @@ class mr extends control } /** - * Add a Bug for this review. + * Add a review for this review. * * @param int $repoID - * @param string $file + * @param int $mr * @param int $v1 * @param int $v2 * @access public * @return void */ - public function addBug($repoID, $file, $v1, $v2) + public function addReview($repoID, $mr, $v1, $v2) { /* Handle the exception that when $repoID is empty. */ if($repoID == "0") $this->send(array()); $this->loadModel('repo'); - if($this->get->repoPath) $file = $this->get->repoPath; if(!empty($_POST)) { - $result = $this->mr->saveBug($repoID, $file, $v1, $v2); - if(dao::isError()) die(json_encode($result)); + if($this->post->reviewType == 'bug') $result = $this->mr->saveBug($repoID, $mr, $v1, $v2); + if($this->post->reviewType == 'task') $result = $this->mr->saveTask($repoID, $mr, $v1, $v2); + if($result['result'] == 'fail') die(json_encode($result)); - $bugID = $result['id']; + $objectID = $result['id']; $repo = $this->repo->getRepoById($repoID); /* Handle the exception that when $repo is empty. */ - if(empty($repo)) $this->send(array()); + if(empty($repo) or empty($result)) $this->send(json_encode(array())); - $entry = isset($repo->name) ? $repo->name . '/' . $this->repo->decodePath($file) : ''; - $location = sprintf($this->lang->repo->reviewLocation, $entry, $repo->SCM != 'Subversion' ? substr($v2, 0, 10) : $v2, $this->post->begin, $this->post->end); - if(empty($v1)) - { - $revision = $repo->SCM != 'Subversion' ? substr($v2, 0, 10) : $v2; - $link = $this->repo->createLink('view', "repoID=$repoID&objectID=0&entry={$file}&revision=$v2&showBug=true") . '#L' . $this->post->begin; - } - else - { - $revision = $repo->SCM != 'Subversion' ? substr($v1, 0, 10) : $v1; - $revision .= ' : '; - $revision .= $repo->SCM != 'Subversion' ? substr($v2, 0, 10) : $v2; - $link = $this->repo->createLink('diff', "repoID=$repoID&objectID=0&entry={$file}&oldRevision=$v1&newRevision=$v2&showBug=true") . '#L' . $this->post->begin; - } + $location = sprintf($this->lang->repo->reviewLocation, $this->post->entry ? base64_decode($this->post->entry) : '', $repo->SCM != 'Subversion' ? substr($v2, 0, 10) : $v2, $this->post->begin, $this->post->end); + $link = $this->createLink('mr', 'diff', "mr=$mr") . '#L' . $this->post->begin; - $actionID = $this->loadModel('action')->create('bug', $bugID, 'repoCreated', '', html::a($link, $location)); - $this->loadModel('mail')->sendmail($bugID, $actionID); + $actionID = $this->loadModel('action')->create($this->post->reviewType, $objectID, 'repoCreated', '', html::a($link, $location)); + $this->loadModel('mail')->sendmail($objectID, $actionID); echo json_encode($result); } diff --git a/module/mr/css/common.css b/module/mr/css/common.css index a2da70383a..488645d71d 100644 --- a/module/mr/css/common.css +++ b/module/mr/css/common.css @@ -88,8 +88,8 @@ h3 {font-size: 16px;} /* repo action form */ .repoCode .comment-list, .repoCode .comment-actions {max-width: 900px;} -.repoCode .bugFormContainer {border: 1px solid #bbb; margin: 0 0 0 15px; padding: 10px 20px 10px 10px; max-width: 880px; background: #fff;} -.repoCode .bugFormContainer th {width: 70px;} +.repoCode .reviewFormContainer {border: 1px solid #bbb; margin: 0 0 0 15px; padding: 10px 20px 10px 10px; max-width: 880px; background: #fff;} +.repoCode .reviewFormContainer th {width: 70px;} .repoCode .action-row {display: none;} .repoCode .with-action-row .action-row {display: table-row;} @@ -106,26 +106,26 @@ h3 {font-size: 16px;} .repoCode .comment-cell .panel-body {padding: 6px 10px;} .repoCode .comment-cell .panel-actions.pull-right {margin-right: 0; margin-top: 0;} .repoCode .comment-cell .editing .panel-body, .repoCode .comment-cell .commentContainer.show-form .panel-body {display: none;} -.repoCode .comment-cell .bug-edit-form, {padding: 10px; display: none;} -.repoCode .comment-cell .editing .bug-edit-form, .repoCode .comment-cell .commentContainer.show-form .comment-edit-form {display: block;} +.repoCode .comment-cell .review-edit-form, {padding: 10px; display: none;} +.repoCode .comment-cell .editing .review-edit-form, .repoCode .comment-cell .commentContainer.show-form .comment-edit-form {display: block;} .repoCode .comment {border: 1px solid #e5e5e5; background: #fafafa; padding: 5px 10px; margin-bottom: 10px;} .repoCode .comment .comment-edit-form {margin-top: 10px;} -.repoCode .panel-bug .steps {background: #f1f1f1; padding: 5px 10px;} -.repoCode .panel-bug .bug-edit-form {margin-bottom: 10px;} -.repoCode .panel-bug .panel-body {display: none;} -.repoCode .panel-bug .panel-heading {cursor: pointer;} -.repoCode .panel-bug.show .panel-body {display: block;} -.repoCode .panel-bug.show .icon-chevron-sign-down:before {content: '\e711';} -.repoCode .panel-bug.show-edit-form .bug-edit-form, -.repoCode .panel-bug.show-form .commentForm, +.repoCode .panel-review .steps {background: #f1f1f1; padding: 5px 10px;} +.repoCode .panel-review .review-edit-form {margin-bottom: 10px;} +.repoCode .panel-review .panel-body {display: none;} +.repoCode .panel-review .panel-heading {cursor: pointer;} +.repoCode .panel-review.show .panel-body {display: block;} +.repoCode .panel-review.show .icon-chevron-sign-down:before {content: '\e711';} +.repoCode .panel-review.show-edit-form .review-edit-form, +.repoCode .panel-review.show-form .commentForm, .repoCode .comment.show-form .comment-edit-form {display: block;} -.repoCode .panel-bug .bug-edit-form, -.repoCode .panel-bug.show-form .addComment, -.repoCode .panel-bug .commentForm, +.repoCode .panel-review .review-edit-form, +.repoCode .panel-review.show-form .addComment, +.repoCode .panel-review .commentForm, .repoCode .comment .comment-edit-form, -.repoCode .panel-bug.show-edit-form .panel-body .title, -.repoCode .panel-bug.show-edit-form .bug-date, +.repoCode .panel-review.show-edit-form .panel-body .title, +.repoCode .panel-review.show-edit-form .bug-date, .repoCode .comment.show-form .comment-content, .repoCode .comment.show-form .comment-date {display: none;} .repoCode .text-content {white-space: normal; white-space: pre-line;} @@ -154,8 +154,8 @@ h3 {font-size: 16px;} .repoCode #diff tr.commented .row-tip {right: 0;} .repoCode #diff tr.commented .icon-chat-dot {left: 0;} -.repoCode .panel, .bugFormContainer {transition: border 0.4s;} -.repoCode .panel.highlight, #bugForm.highlight .bugFormContainer {border-color: #e48600;} +.repoCode .panel, .reviewFormContainer {transition: border 0.4s;} +.repoCode .panel.highlight, #reviewForm.highlight .reviewFormContainer {border-color: #e48600;} #bugsPreview {white-space: normal;} #bugsPreview .dropdown-menu {top: -100%; left: 30%; padding-top: 0; min-width: 300px; max-width: 500px;} @@ -166,7 +166,7 @@ h3 {font-size: 16px;} .icon-comments {position: relative; left: -50px;} /* bug form */ -#bugForm, #bugForm table {margin: 0; padding: 0;} +#reviewForm, #reviewForm table {margin: 0; padding: 0;} .panel .table + .panel-footer {border-top: 0; background: #fff;} diff --git a/module/mr/js/diff.js b/module/mr/js/diff.js index a076f1628f..fba408bb13 100644 --- a/module/mr/js/diff.js +++ b/module/mr/js/diff.js @@ -5,6 +5,13 @@ $(document).ready(function() $(".label-exchange").click(function(){ $('#exchange').submit();}); }); +/** + * Change encoding. + * + * @param string $encoding + * @access public + * @return void + */ function changeEncoding(encoding) { $('#encoding').val(encoding); @@ -14,11 +21,8 @@ function changeEncoding(encoding) $(document).ready(function() { var $diffCode = $('.diff'); - var hidePreview; - var $bugsPreview = $('#bugsPreview'); - var $bugsPreviewMenu = $('#bugsPreview').children('.dropdown-menu'); - var $rows = $diffCode.find('tr'); - var rowTip = $('#rowTip').html(); + var $rows = $diffCode.find('tr'); + var rowTip = $('#rowTip').html(); var lastLine; $rows.each(function() { @@ -48,13 +52,11 @@ $(document).ready(function() $(this).removeClass("over"); }); - var isInline = $.cookie('arrange') == 'inline'; - var $bugFormRow = $('' + (isInline ? '' : '') + ''); - var $bugForm = $('#bugForm'); - var $commentCell = $('#commentCell'); - var $bugPanel = $('#bugPanel'); -// $bugForm.find('input[name="begin"], input[name="end"]').attr('max', lastLine); - $bugFormRow.find('td').append($bugForm.removeClass('hide')); + var isInline = $.cookie('arrange') == 'inline'; + var $reviewFormRow = $('' + (isInline ? '' : '') + ''); + var $reviewForm = $('#reviewForm'); + var $reviewPanel = $('#reviewPanel'); + $reviewFormRow.find('td').append($reviewForm.removeClass('hide')); var highlight = function($e) { @@ -62,76 +64,47 @@ $(document).ready(function() $e.addClass('highlight'); }; - var createComment = function(comment, $comments) + var createReview = function(review, line, show) { - console.log(); - var $comment = $commentCell.clone() - .removeClass('hide') - .attr('id', 'comment-' + comment.id) - .attr('data-comment', comment.id); - $comment.find('.realname').text(comment.realname); - $comment.find('.comment-content').text(comment.comment); - $comment.find('.date').text(comment.date); - $comment.find('.edit').toggle(comment.edit); - $comment.find('.comment-edit-form').attr('action', createLink('repo', 'editComment', 'commentID=' + comment.id)); + var $review = $reviewPanel.clone().removeClass('hide').attr('id', review.objectType + '-' + review.id); + $review.find('.realname').text(review.realname); + $review.find('.openedDate').text(review.openedDate); + $review.find('.title').text(review.title); + $review.find('.content').toggle(review.content != '').html(review.content); + $review.find('.code-lines').text(review.lines); + $review.find('input[name="objectID"]').val(review.id); + $review.data(review); - if($comments) - { - if(typeof $comments !== 'object') $comments = $('#bug-' + $comments + ' .comments'); - ($comments.hasClass('comments') ? $comments : $comments.find('.comments')).append($comment); - } + id = review.objectType == 'bug' ? 'Bug' : 'Task'; + id += '#' + review.id; + if(review.view) id = "" + id + ""; + $review.find('.title').closest('.panel-heading').find('.panel-actions').prepend(id); + if(!review.delete) $review.find('.title').closest('.panel-heading').find('.panel-actions .reviewDelete').hide(); - return $comment; - }; + $review.toggleClass('show', show > 1); + if(show > 2) highlight($review); - var createBug = function(bug, line, $commentRow, show) - { - var commentCount, j; - var $bug = $bugPanel.clone().removeClass('hide').attr('id', 'bug-' + bug.id).attr('data-bug', bug.id); - $bug.find('.bugid').text(bug.id); - $bug.find('.realname').text(bug.realname); - $bug.find('.openedDate').text(bug.openedDate); - $bug.find('.title').text(bug.title); - $bug.find('.steps').toggle(bug.steps != '').html(bug.steps); - $bug.find('.edit').toggle(bug.edit); - $bug.find('.code-lines').text(bug.lines); - $bug.find('.delete').toggle(bug.delete); - $bug.find('input[name="objectID"]').val(bug.id); - $bug.find('.bug-edit-form').attr('action', createLink('repo', 'editBug', 'bugID=' + bug.id)); - $bug.find('a.view-bug').attr('href', createLink('bug', 'view', "bugID=" + bug.id)); - $bug.data('data', bug); - $bug.toggleClass('show', show > 1); - if(show > 2) highlight($bug); - - if(bug.comments) - { - commentCount = bug.comments.length; - $bugComments = $bug.find('.comments'); - for(j = 0; j < commentCount; j++) - { - createComment(bug.comments[j], $bugComments); - } - } - - if(!line && bug.line) line = bug.line; + if(!line && review.line) line = review.line; if(line) { - if(!$commentRow) + var $row = $rows.filter('[data-line="' + line + '"]').last(); + if(review.entry) $row = $('#diff[data-entry="' + review.entry + '"]').find('tr').filter('[data-line="' + line + '"]'); + if($row.length == 0) return false; + + $commentRow = $row.next('tr'); + if($row.hasClass('commented')) $commentRow = $row.nextAll('tr.comment-row').first(); + if(!$commentRow.hasClass('comment-row')) { - var $row = $rows.filter('[data-line="' + line + '"]').last(); - $commentRow = $row.next('tr'); - if(!$commentRow.hasClass('comment-row')) - { - $commentRow = $('' + (isInline ? '' : '') + ''); - $row.addClass('commented').after($commentRow); - } + $commentRow = $('' + (isInline ? '' : '') + ''); + $row.addClass('commented').after($commentRow); } - ($commentRow.hasClass('comment-list') ? $commentRow : $commentRow.find('.comment-list')).append($bug); + + $commentRow.find('.comment-list').append($review); if(show && $commentRow.hasClass('comment-row')) $commentRow.addClass('show'); } - return $bug; + return $review; }; var toggleComment = function($row, show) @@ -182,233 +155,50 @@ $(document).ready(function() $rows.removeClass('with-action-row') $row.addClass('with-action-row'); - $bugForm.find('input[name="begin"]').val(line); - $bugForm.find('input[name="end"]').attr('min', line).val(line); - $bugForm.find('select#assignedTo').val(blamePairs[line]); - $bugForm.find('select#assignedTo').trigger("chosen:updated"); + $reviewForm.find('input[name="begin"]').val(line); + $reviewForm.find('input[name="end"]').attr('min', line).val(line); + $reviewForm.find('select#assignedTo').trigger("chosen:updated"); + $reviewForm.find('input#entry').val($row.closest('table#diff').data('entry')); - $row.after($bugFormRow); + $row.after($reviewFormRow); KindEditor.remove('#commentText'); $('#commentText').kindeditor(); - - var getCommiterLink = createLink('repo', 'ajaxgetcommitter', 'repoID=' + repoID + "&entry=" + file + "&revision=" + revision + "&line=" + line); - var connector = getCommiterLink.indexOf('&') >= 0 ? '&' : '?'; - getCommiterLink = getCommiterLink + connector + 'entry=' + file; - $.ajax({url: getCommiterLink}).done(function(responseText) - { - $bugForm.find('#assignedTo').val(responseText).trigger("chosen:updated"); - }); } - highlight($bugForm); - $bugForm.find('input[name="title"]').focus(); + highlight($reviewForm); + $reviewForm.find('input[name="title"]').focus(); $row.addClass('selected'); } e.stopPropagation(); - }).on('click', '.bugCancel', function() + }).on('click', '.reviewDelete', function(e) { - $rows.removeClass('selected'); - $diffCode.removeClass('with-action-row'); - }).on('click', '.bugEdit', function(e) - { - var $panelBug = $(this).closest('.panel-bug'); + var $review = $(this).closest('.panel-review'); + if(!$review.length) return; - if($panelBug.hasClass('show-edit-form')) + if(confirm(confirmDelete)) { - $panelBug.removeClass('show-edit-form'); - e.stopPropagation(); - return; - } - - $panelBug.addClass('show show-edit-form').find('input[name="commentText"]').val($panelBug.find('.title').first().text()).focus(); - e.stopPropagation(); - return false; - }).on('submit', '.bug-edit-form', function() - { - var $form = $(this); - $(this).ajaxSubmit( - { - success:function(text) - { - var $bug = $form.closest('.panel-bug'); - $bug.find('.title').text(text); - $bug.removeClass('show-edit-form'); - }, - beforeSubmit:function(formData, jqForm) - { - var form = jqForm[0]; - if(!form.commentText.value) - { - alert(contentError); - return false; - } - } - }); - return false; - }).on('click', '.bugEditCancel', function() - { - $(this).closest('.panel-bug').removeClass('show-edit-form'); - }).on('click', '.bugDelete', function(e) - { - var $bug = $(this).closest('.panel-bug'); - if(!$bug.length) return; - - if(confirm(confirmDelete)) - { - var link = createLink('repo', 'deleteBug', 'bugID=' + $bug.data('bug') + '&confirm=yes'); + var link = createLink($review.data('objectType'), 'delete', 'id=' + $review.data('id') + '&confirm=yes'); $.get(link, function(data) { - if(data == 'deleted') + var $commentRow = $review.closest('.comment-row'); + if($commentRow.find('.panel-review').length === 1) { - var $commentRow = $bug.closest('.comment-row'); - if($commentRow.find('.panel-bug').length === 1) - { - $commentRow.removeClass('show').prev('tr').removeClass('commented'); - } - $bug.remove(); + $commentRow.removeClass('show').prev('tr').removeClass('commented'); } + $review.remove(); }); } e.stopPropagation(); return false; - }).on('click', '.addComment', function() - { - $(this).closest('.panel-bug').addClass('show-form').find('.commentForm textarea').focus(); - }).on('click', '.commentCancel', function() - { - $(this).closest('.panel-bug').removeClass('show-form'); - }).on('submit', '.commentForm', function() - { - var $form = $(this); - $form.ajaxSubmit( - { - success:function(json) - { - var $panelBug = $form.closest('.panel-bug'); - $form.find('textarea').val(''); - $panelBug.removeClass('show-form'); - createComment($.parseJSON(json), $panelBug.data('bug')); - }, - beforeSubmit:function(formData, jqForm) - { - var form = jqForm[0]; - if(!form.comment.value) - { - alert(commentError); - return false; - } - } - }); - return false; - }).on('click', '.commentEdit', function() - { - var $comment = $(this).closest('.comment'); - - if($comment.hasClass('show-form')) - { - $comment.removeClass('show-form'); - return; - } - $comment.addClass('show-form').find('textarea').val($comment.find('.comment-content').text()).focus(); - }).on('click', '.commentEditCancel', function() - { - $(this).closest('.comment').removeClass('show-form'); - }).on('submit', '.comment-edit-form', function() - { - var $form = $(this); - $form.ajaxSubmit( - { - success:function(html) - { - var $comment = $form.closest('.comment'); - $comment.find('.comment-content').html(html); - $comment.removeClass('show-form'); - }, - beforeSubmit:function(formData, jqForm) - { - var form = jqForm[0]; - if(!form.commentText.value) - { - alert(contentError); - return false; - } - } - }); - return false; - }).on('click', '.commentDelete', function() - { - var $container = $(this).closest('.commentContainer'); - if(!$container.length) return; - - if(confirm(confirmDeleteComment)) - { - var commentID = $container.data('comment'); - var link = createLink('repo', 'deleteComment', 'commentID=' + commentID + '&confirm=yes'); - - $.get(link, function(data) - { - if(data == 'deleted') - { - var $commentRow = $container.closest('.comment-row'); - if($commentRow.find('.bugContainer, .commentContainer').length === 1) - { - $commentRow.removeClass('show').prev('tr').removeClass('commented'); - } - $container.remove(); - } - }); - } - return false; }).on('click', 'tr.commented', function() { toggleComment($(this)); - }).on('click', '.panel-bug > .panel-heading', function() + }).on('click', '.panel-review > .panel-heading', function() { - $(this).closest('.panel-bug').toggleClass('show'); - }).on('mouseenter', 'tr.commented td .preview-icon', function(e) - { - var $cell = $(this).closest('td'); - var $row = $cell.closest('tr'); - var $commentRow = $row.next('tr'); - - var $bugs = $commentRow.find('.panel-bug'), line = '?'; - $bugsPreviewMenu.children('li:not(.dropdown-header)').remove(); - $bugsPreviewMenu.find('.bug-count').text($bugs.length); - $bugsPreviewMenu.find('.comment-count').text($commentRow.find('.comment').length); - $bugs.each(function() - { - var bug = $(this).data('data'); - line = bug.line; - $bugsPreviewMenu.append('
  • #' + bug.id + ' ' + bug.title + '
  • '); - }); - $bugsPreviewMenu.find('.code-line').text(line); - - $bugsPreview.prependTo($cell); - clearTimeout(hidePreview); - $bugsPreviewMenu.css({top: 0-$bugsPreviewMenu.outerHeight(), left: Math.max(0, e.offsetX-$bugsPreviewMenu.outerWidth())}).addClass('show'); - setTimeout(function(){$bugsPreviewMenu.addClass('in');}, 50); - }).on('mouseleave', 'tr.commented td', function() - { - $bugsPreviewMenu.removeClass('in'); - hidePreview = setTimeout(function(){$bugsPreviewMenu.removeClass('show');}, 200); + $(this).closest('.panel-review').toggleClass('show'); }); - $bugsPreviewMenu.on('click', 'li', function(e) - { - var $bug = $($(this).find('a').data('id')); - if($bug.length) - { - $bug.addClass('show'); - toggleComment($bug.closest('tr.comment-row'), true); - highlight($bug); - - $bugsPreviewMenu.removeClass('in'); - hidePreview = setTimeout(function(){$bugsPreviewMenu.removeClass('show');}, 200); - } - e.stopPropagation(); - }); - - $bugForm.submit(function() + $reviewForm.submit(function() { $(this).ajaxSubmit( { @@ -417,20 +207,42 @@ $(document).ready(function() json = $.parseJSON(json); if(json.result == 'fail') { - alert(json.message); - return false; + var message = ''; + if(typeof(json.message) != 'string') + { + for(i in json.message) + { + if(typeof(json.message[i]) == 'string') + { + message += json.message[i] + '\n'; + } + else + { + for(j in json.message[i]) + { + message += json.message[i][j] + '\n'; + } + } + } + } + else + { + message += json.message + '\n'; + } + alert(message); + return false; } - createBug(json, null, null, 3); + createReview(json, json.line, 3); $diffCode.removeClass('with-action-row'); $diffCode.find('tr.with-action-row.selected').removeClass('selected'); - $bugForm.find('#title').val(''); + $reviewForm.find('#title').val(''); KindEditor.html('#commentText', ''); }, beforeSubmit:function(formData, jqForm) { var form = jqForm[0]; - if(!form.product.value) + if(!form.product.value) { alert(productError); return false; @@ -438,7 +250,7 @@ $(document).ready(function() if(!form.title.value) { alert(titleError); - $bugForm.find('input[name="title"]').focus(); + $reviewForm.find('input[name="title"]').focus(); return false; } } @@ -447,27 +259,22 @@ $(document).ready(function() }).on('change', 'input[name="begin"]', function() { var begin = $(this).val(); - var $end = $bugForm.find('input[name="end"]').attr('min', begin); + var $end = $reviewForm.find('input[name="end"]').attr('min', begin); if(parseInt($end.val()) < parseInt(begin)) { $end.val(begin); } }); - if(bugs) + if(reviews) { - var lineBugs, bugsCount, i; - for(var line in bugs) + var lineReviews; + for(var line in reviews) { if(line) - { - lineBugs = bugs[line]; - bugsCount = lineBugs.length; - - for(i = 0; i < bugsCount; i++) - { - createBug(lineBugs[i], line); - } + { + lineReviews = reviews[line]; + for(var i in lineReviews) createReview(lineReviews[i], line); } } } @@ -479,30 +286,30 @@ $(document).ready(function() $('.highlight').removeClass('highlight'); }); + /** + * Anchor + * + * @access public + * @return void + */ function anchor() { - var hash = window.location.hash; - if(hash) + var hash = window.location.hash; + if(!hash) return false; + + var line = hash.substr(1).replace('L', ''); + var $row = $('.diff tr[data-line="' + line +'"]').first(); + if($row.length) return false; + + var anchor = $row.offset().top; + $('body,html').animate({scrollTop:anchor - 50}, 500); + + $row.addClass('highlight'); + if($row.hasClass('commented')) { - var line = hash.substr(1).replace('L', ''); - var $row = $('.diff tr[data-line="' + line +'"]').first(); - if($row.length) - { - var anchor = $row.offset().top; - - $('body,html').animate({scrollTop:anchor - 50}, 500); - - $row.addClass('highlight'); - if($row.hasClass('commented')) - { - toggleComment($row, true); - var $commentRow = $row.next('tr'); - if($commentRow.hasClass('comment-row')) - { - $commentRow.addClass('highlight'); - } - } - } + toggleComment($row, true); + var $commentRow = $row.next('tr'); + if($commentRow.hasClass('comment-row')) $commentRow.addClass('highlight'); } } }); diff --git a/module/mr/lang/en.php b/module/mr/lang/en.php index 3f743f35e7..46b72b57eb 100644 --- a/module/mr/lang/en.php +++ b/module/mr/lang/en.php @@ -21,11 +21,11 @@ $lang->mr->linkStory = 'Link Stories'; $lang->mr->linkBug = 'Link Bugs'; $lang->mr->linkTask = 'Link Tasks'; $lang->mr->unlink = 'UnLink of stories,Bugs,tasks'; -$lang->mr->addBug = 'Add Review'; +$lang->mr->addReview = 'Add Review'; $lang->mr->id = 'ID'; $lang->mr->mriid = "raw MR ID"; -$lang->mr->title = 'Name'; +$lang->mr->title = 'Name'; $lang->mr->status = 'Status'; $lang->mr->author = 'Author'; $lang->mr->assignee = 'Assignee'; @@ -46,7 +46,12 @@ $lang->mr->reject = 'Reject'; $lang->mr->close = 'Close'; $lang->mr->reopen = 'Reopen'; -$lang->mr->approvalResult = 'Approval result'; +$lang->mr->reviewType = 'Review Type'; +$lang->mr->reviewTypeList = array(); +$lang->mr->reviewTypeList['bug'] = 'Bug'; +$lang->mr->reviewTypeList['task'] = 'Task'; + +$lang->mr->approvalResult = 'Approval result'; $lang->mr->approvalResultList = array(); $lang->mr->approvalResultList['approve'] = 'Approve'; $lang->mr->approvalResultList['reject'] = 'Reject'; @@ -90,6 +95,7 @@ $lang->mr->notFound = "Merge Request does not exist!"; $lang->mr->toCreatedMessage = "The merge request you submitted:%s, the build task succeeded."; $lang->mr->toReviewerMessage = "You have one merge request %s waiting."; $lang->mr->failMessage = "Your merge request %s failed. Please check its execution result. "; +$lang->mr->storySummary = "Total %s {$lang->SRCommon} on this page."; $lang->mr->apiError = new stdclass; $lang->mr->apiError->createMR = "Failed to create a merge request through API. Reason: %s"; diff --git a/module/mr/lang/zh-cn.php b/module/mr/lang/zh-cn.php index d4608feb93..6a1acc8962 100644 --- a/module/mr/lang/zh-cn.php +++ b/module/mr/lang/zh-cn.php @@ -21,7 +21,7 @@ $lang->mr->linkStory = '关联需求'; $lang->mr->linkBug = '关联Bug'; $lang->mr->linkTask = '关联任务'; $lang->mr->unlink = '取消关联需求、Bug、任务'; -$lang->mr->addBug = '添加评审'; +$lang->mr->addReview = '添加评审'; $lang->mr->id = 'ID'; $lang->mr->mriid = "MR原始ID"; @@ -46,7 +46,12 @@ $lang->mr->reject = '拒绝'; $lang->mr->close = '关闭'; $lang->mr->reopen = '重新打开'; -$lang->mr->approvalResult = '评审意见'; +$lang->mr->reviewType = '评审类型'; +$lang->mr->reviewTypeList = array(); +$lang->mr->reviewTypeList['bug'] = 'Bug'; +$lang->mr->reviewTypeList['task'] = '任务'; + +$lang->mr->approvalResult = '评审意见'; $lang->mr->approvalResultList = array(); $lang->mr->approvalResultList['approve'] = '通过'; $lang->mr->approvalResultList['reject'] = '拒绝'; @@ -90,6 +95,7 @@ $lang->mr->notFound = "此{$lang->mr->common}不存在。"; $lang->mr->toCreatedMessage = "您提交的合并请求:%s 构建任务执行通过。"; $lang->mr->toReviewerMessage = "有一个合并请求:%s 待审核。"; $lang->mr->failMessage = "您提交的合并请求:%s 构建任务执行失败,查看执行结果。"; +$lang->mr->storySummary = "本页共 %s 个" . $lang->SRCommon; $lang->mr->apiError = new stdclass; $lang->mr->apiError->createMR = "通过API创建合并请求失败,失败原因:%s"; @@ -102,7 +108,7 @@ $lang->mr->closeSuccess = "已关闭合并请求。"; $lang->mr->apiErrorMap[0] = "You can't use same project/branch for source and target"; -$lang->mr->errorLang[0] = '源项目分支不能和目标项目分支一样'; +$lang->mr->errorLang[0] = '源项目分支与目标项目分支不能相同'; $lang->mr->from = "从"; $lang->mr->to = "合并到"; diff --git a/module/mr/model.php b/module/mr/model.php index 428bc645e9..9a577e46c5 100644 --- a/module/mr/model.php +++ b/module/mr/model.php @@ -552,7 +552,7 @@ class mrModel extends model public function getDiffs($MR, $encoding = '') { $diffVersions = $this->apiGetDiffVersions($MR->gitlabID, $MR->targetProject, $MR->mriid); - $gitlab = $this->gitlab->getByID($MR->gitlabID); + $gitlab = $this->gitlab->getByID($MR->gitlabID); $this->loadModel('repo'); $repo = new stdclass; @@ -570,10 +570,10 @@ class mrModel extends model foreach ($diffVersions as $diffVersion) { $singleDiff = $this->apiGetSingleDiffVersion($MR->gitlabID, $MR->targetProject, $MR->mriid, $diffVersion->id); - if ($singleDiff->state == 'empty') continue; + if($singleDiff->state == 'empty') continue; $commits = $singleDiff->commits; $diffs = $singleDiff->diffs; - foreach ($diffs as $index => $diff) + foreach($diffs as $index => $diff) { if(empty($commits[$index])) continue; /* Make sure every file with same commitID is unique in $lines. */ @@ -586,9 +586,10 @@ class mrModel extends model $lines[] = sprintf("--a/%s", $diff->old_path); $lines[] = sprintf("--b/%s", $diff->new_path); $diffLines = explode("\n", $diff->diff); - foreach ($diffLines as $diffLine) $lines[] = $diffLine; + foreach($diffLines as $diffLine) $lines[] = $diffLine; } } + $scm = $this->app->loadClass('scm'); $scm->setEngine($repo); $diff = $scm->engine->parseDiff($lines); @@ -785,45 +786,48 @@ class mrModel extends model * Get review. * * @param int $repoID - * @param string $entry + * @param int $MRID * @param string $revision * @access public * @return array */ - public function getReview($repoID, $entry, $revision) + public function getReview($repoID, $MRID, $revision = '') { + if(empty($repoID) OR empty($MRID)) return array(); + $reviews = array(); $bugs = $this->dao->select('t1.*, t2.realname')->from(TABLE_BUG)->alias('t1') - ->leftJoin(TABLE_USER)->alias('t2') - ->on('t1.openedBy = t2.account') - ->where('t1.repo')->eq($repoID) - ->andWhere('t1.entry')->eq($entry) - ->andWhere('t1.v2')->eq($revision) + ->leftJoin(TABLE_USER)->alias('t2')->on('t1.openedBy = t2.account') + ->where('t1.repo')->eq((int)$repoID) + ->andWhere('t1.mr')->eq((int)$MRID) + ->beginIF($revision)->andWhere('t1.v2')->eq($revision)->fi() ->andWhere('t1.deleted')->eq(0) ->fetchAll('id'); - $comments = $this->dao->select('t1.*, t2.realname')->from(TABLE_ACTION)->alias('t1') - ->leftJoin(TABLE_USER)->alias('t2') - ->on('t1.actor = t2.account') - ->where('t1.objectType')->eq('bug') - ->andWhere('t1.objectID')->in(array_keys($bugs)) - ->andWhere('t1.action')->eq('commented') - ->fetchGroup('objectID', 'id'); foreach($bugs as $bug) { if(common::hasPriv('bug', 'edit')) $bug->edit = true; if(common::hasPriv('bug', 'delete')) $bug->delete = true; + if(common::hasPriv('bug', 'view')) $bug->view = true; $lines = explode(',', trim($bug->lines, ',')); $line = $lines[0]; - $reviews[$line]['bugs'][$bug->id] = $bug; + $reviews[$line]['bug'][$bug->id] = $bug; + } - if(isset($comments[$bug->id])) - { - foreach($comments[$bug->id] as $key => $comment) - { - if($comment->actor == $this->app->user->account) $comment->edit = true; - } - $reviews[$line]['comments'] = $comments; - } + $tasks = $this->dao->select('t1.*, t2.realname')->from(TABLE_TASK)->alias('t1') + ->leftJoin(TABLE_USER)->alias('t2')->on('t1.openedBy = t2.account') + ->where('t1.repo')->eq((int)$repoID) + ->andWhere('t1.mr')->eq((int)$MRID) + ->beginIF($revision)->andWhere('t1.v2')->eq($revision)->fi() + ->andWhere('t1.deleted')->eq(0) + ->fetchAll('id'); + foreach($tasks as $task) + { + if(common::hasPriv('task', 'edit')) $task->edit = true; + if(common::hasPriv('task', 'delete')) $task->delete = true; + if(common::hasPriv('task', 'view')) $task->view = true; + $lines = explode(',', trim($task->lines, ',')); + $line = $lines[0]; + $reviews[$line]['task'][$task->id] = $task; } return $reviews; @@ -881,43 +885,154 @@ class mrModel extends model * Save bug. * * @param int $repoID - * @param string $file + * @param int $mr * @param int $v1 * @param int $v2 * @access public * @return array */ - public function saveBug($repoID, $file, $v1, $v2) + public function saveBug($repoID, $mr, $v1, $v2) { $now = helper::now(); $data = fixer::input('post') - ->add('severity', 3) + ->stripTags('commentText', $this->config->allowedTags) + ->add('pri', 2) + ->add('severity', 2) ->add('openedBy', $this->app->user->account) ->add('openedDate', $now) ->add('openedBuild', 'trunk') - ->add('assignedDate', $now) - ->add('type', 'codeimprovement') + ->add('type', 'codeerror') ->add('repo', $repoID) - ->add('entry', $file) + ->add('mr', $mr) ->add('lines', $this->post->begin . ',' . $this->post->end) ->add('v1', $v1) ->add('v2', $v2) - ->remove('commentText,begin,end,uid') + ->cleanInt('module,execution,mr,repo') + ->remove('begin,end,uid,reviewType,taskExecution,taskModule,taskAssignedTo') ->get(); - $data->steps = $this->loadModel('file')->pasteImage($this->post->commentText, $this->post->uid); - $this->dao->insert(TABLE_BUG)->data($data)->exec(); + $data->steps = $this->loadModel('file')->pasteImage($data->commentText, $this->post->uid); + if($data->assignedTo) $data->assignedDate = $now; + unset($data->commentText); + + $this->loadModel('bug'); + foreach(explode(',', $this->config->bug->create->requiredFields . ',repo,mr') as $requiredField) + { + $requiredField = trim($requiredField); + if(empty($requiredField)) continue; + if(!isset($data->$requiredField)) continue; + if(empty($data->$requiredField)) + { + $fieldName = $requiredField; + if(isset($this->lang->bug->$requiredField)) $fieldName = $this->lang->bug->$requiredField; + dao::$errors[$requiredField][] = sprintf($this->lang->error->notempty, $fieldName); + } + } + if(dao::isError()) return array('result' => 'fail', 'message' => dao::getError()); + + $this->dao->insert(TABLE_BUG)->data($data)->autocheck()->exec(); if(!dao::isError()) { $bugID = $this->dao->lastInsertID(); - $this->file->updateObjectID($this->post->uid, $bugID, 'bug'); + $this->loadModel('file')->updateObjectID($this->post->uid, $bugID, 'bug'); setcookie("repoPairs[$repoID]", $data->product); - return array('result' => 'success', 'id' => $bugID, 'realname' => $this->app->user->realname, 'openedDate' => substr($now, 5, 11), 'edit' => true, 'delete' => true, 'lines' => $data->lines, 'line' => $this->post->begin, 'steps' => $data->steps, 'title' => $data->title); + $bugInfo = array(); + $bugInfo['result'] = 'success'; + $bugInfo['id'] = $bugID; + $bugInfo['realname'] = $this->app->user->realname; + $bugInfo['openedDate'] = substr($now, 5, 11); + $bugInfo['edit'] = common::hasPriv('bug', 'edit'); + $bugInfo['view'] = common::hasPriv('bug', 'view'); + $bugInfo['delete'] = common::hasPriv('bug', 'delete'); + $bugInfo['lines'] = $data->lines; + $bugInfo['line'] = $this->post->begin; + $bugInfo['content'] = $data->steps; + $bugInfo['title'] = $data->title; + $bugInfo['objectType'] = 'bug'; + $bugInfo['entry'] = $data->entry; + return $bugInfo; } - return array('result' => 'fail', 'message' => join("\n", dao::getError())); + return array('result' => 'fail', 'message' => dao::getError()); + } + + /** + * Save task. + * + * @param int $repoID + * @param int $mr + * @param int $v1 + * @param int $v2 + * @access public + * @return array + */ + public function saveTask($repoID, $mr, $v1, $v2) + { + $now = helper::now(); + $data = fixer::input('post')->stripTags('commentText', $this->config->allowedTags)->get(); + + $task = new stdclass(); + $task->execution = (int)$data->taskExecution; + $task->project = (int)$this->dao->select('project')->from(TABLE_PROJECT)->where('id')->eq($task->execution)->fetch('project'); + $task->module = (int)$data->taskModule; + $task->name = $data->title; + $task->type = 'devel'; + $task->pri = '2'; + $task->status = 'wait'; + $task->version = '1'; + $task->openedBy = $this->app->user->account; + $task->assignedTo = $data->taskAssignedTo; + $task->repo = (int)$repoID; + $task->mr = (int)$mr; + $task->lines = $this->post->begin . ',' . $this->post->end; + $task->entry = $data->entry; + $task->v1 = $v1; + $task->v2 = $v2; + $task->desc = $this->loadModel('file')->pasteImage($data->commentText, $this->post->uid); + if($task->assignedTo) $task->assignedDate = $now; + + $this->loadModel('task'); + foreach(explode(',', $this->config->task->create->requiredFields . ',repo,mr') as $requiredField) + { + $requiredField = trim($requiredField); + if(empty($requiredField)) continue; + if(!isset($task->$requiredField)) continue; + if(empty($task->$requiredField)) + { + $fieldName = $requiredField; + if(isset($this->lang->task->$requiredField)) $fieldName = $this->lang->task->$requiredField; + dao::$errors[$requiredField][] = sprintf($this->lang->error->notempty, $fieldName); + } + } + if(dao::isError()) return array('result' => 'fail', 'message' => dao::getError()); + + $this->dao->insert(TABLE_TASK)->data($task)->autocheck()->exec(); + + if(!dao::isError()) + { + $taskID = $this->dao->lastInsertID(); + $this->file->updateObjectID($this->post->uid, $taskID, 'task'); + + $taskInfo = array(); + $taskInfo['result'] = 'success'; + $taskInfo['id'] = $taskID; + $taskInfo['realname'] = $this->app->user->realname; + $taskInfo['openedDate'] = substr($now, 5, 11); + $taskInfo['edit'] = common::hasPriv('task', 'edit'); + $taskInfo['view'] = common::hasPriv('task', 'view'); + $taskInfo['delete'] = common::hasPriv('task', 'delete'); + $taskInfo['lines'] = $task->lines; + $taskInfo['line'] = $this->post->begin; + $taskInfo['content'] = $task->desc; + $taskInfo['title'] = $data->title; + $taskInfo['objectType'] = 'task'; + $taskInfo['entry'] = $task->entry; + return $taskInfo; + } + + return array('result' => 'fail', 'message' => dao::getError()); } /** @@ -963,13 +1078,18 @@ class mrModel extends model /** * Get last review info. * - * @param string $entry + * @param int $repoID * @access public * @return object */ - public function getLastReviewInfo($entry) + public function getLastReviewInfo($repoID) { - return $this->dao->select('*')->from(TABLE_BUG)->where('entry')->eq($entry)->orderby('id_desc')->fetch(); + if(empty($repoID)) return null; + + $lastReview = new stdclass(); + $lastReview->bug = $this->dao->select('*')->from(TABLE_BUG)->where('repo')->eq((int)$repoID)->orderby('id_desc')->fetch(); + $lastReview->task = $this->dao->select('*')->from(TABLE_TASK)->where('repo')->eq((int)$repoID)->orderby('id_desc')->fetch(); + return $lastReview; } /** diff --git a/module/mr/view/diff.html.php b/module/mr/view/diff.html.php index 2610715866..a2d835be88 100644 --- a/module/mr/view/diff.html.php +++ b/module/mr/view/diff.html.php @@ -55,10 +55,13 @@
    + repo->encodingList, $encoding, $lang->repo->encodingList['utf_8']) . "", "data-toggle='dropdown'", 'btn dropdown-toggle btn-sm')?>
    @@ -69,7 +72,7 @@
    -
    gitlab->project->id;?>gitlab->project->id;?> id, "class='form-control' readonly placeholder='{$lang->gitlab->project->id}'");?>
    gitlab->project->name;?>
    name, "class='form-control' readonly");?> '') + $this->lang->gitlab->accessLevels, $member->access_level, "class='form-control chosen'");?> + access_level == $ownerLevel):?> + + expires_at, "class='form-control form-date hidden'");?> + expires_at, "class='form-control form-date'");?> + id);?> ", '', "onclick='addItem(this)' class='btn btn-link'");?> - ", '', "onclick='deleteItem(this)' class='btn btn-link'");?> + ", '', "onclick='deleteItem(this)' class='btn btn-link" . ($member->access_level == $ownerLevel ? ' disabled' : '') . "'");?>
    +
    contents)) continue;?> contents as $content):?> diff --git a/module/mr/view/header.review.html.php b/module/mr/view/header.review.html.php index 0bcae252cc..7292b529b2 100644 --- a/module/mr/view/header.review.html.php +++ b/module/mr/view/header.review.html.php @@ -1,9 +1,6 @@ mr->getLastReviewInfo($file); -$repoModule = isset($lastReview) && isset($lastReview->module) ? $lastReview->module : ''; +$lastReview = $this->mr->getLastReviewInfo($repo->id); /* Get product pairs. */ if(isset($repo->product) and $repo->product) @@ -16,111 +13,97 @@ else } /* get product by cookie or last review in this file. */ -$repoProduct = isset($_COOKIE['repoPairs'][$repoID]) ? $_COOKIE['repoPairs'][$repoID] : ''; -$repoProduct = isset($lastReview) && isset($lastReview->product) ? $lastReview->product : $repoProduct; -$repoProduct = isset($products[$repoProduct]) ? $repoProduct : key($products); -$executions = $this->mr->getExecutionPairs($repoProduct); -$modules = $this->loadModel('tree')->getOptionMenu($repoProduct, $viewType = 'bug', $startModuleID = 0); -$users = $this->loadModel('user')->getPairs('devfirst|nodeleted|noclosed'); -$products = array('' => '') + $products; -$executions = array('' => '') + $executions; +$repoProduct = isset($_COOKIE['repoPairs'][$repoID]) ? $_COOKIE['repoPairs'][$repoID] : ''; +$repoProduct = (!empty($lastReview->bug) && isset($lastReview->bug->product)) ? $lastReview->bug->product : $repoProduct; +$repoProduct = isset($products[$repoProduct]) ? $repoProduct : key($products); +$bugRepoModule = (!empty($lastReview->bug) && $lastReview->bug->product == $repoProduct) ? $lastReview->bug->module : ''; +$executions = $this->mr->getExecutionPairs($repoProduct); +$modules = $this->loadModel('tree')->getOptionMenu($repoProduct, $viewType = 'bug', $startModuleID = 0); +$users = $this->loadModel('user')->getPairs('devfirst|nodeleted|noclosed'); +$products = array('' => '') + $products; +$executions = array('' => '') + $executions; -$cwd = getcwd(); -$commiters = $this->user->getCommiters(); -$blamePairs = array(); -if($suffix and $suffix != 'binary' and strpos($this->config->repo->images, "|$suffix|") === false) +$taskExecutions = $executions; +if(empty($repo->product)) $taskExecutions = array('' => '') + $this->loadModel('execution')->getPairs(); +$repoExecution = (!empty($lastReview->task) && isset($lastReview->task->execution)) ? $lastReview->task->execution : $this->session->execution; +$repoExecution = isset($taskExecutions[$repoExecution]) ? $repoExecution : key($taskExecutions); +$taskModules = array('' => ''); +$taskRepoModule = 0; +$taskMembers = array('' => ''); +if($repoExecution) { - $blames = $this->scm->blame($entry, $info->revision); - foreach($blames as $line => $blame) - { - if(!isset($blame['committer'])) - { - if(isset($blamePairs[$line - 1])) $blamePairs[$line] = $blamePairs[$line - 1]; - continue; - } - $blamePairs[$line] = zget($commiters, $blame['committer'], $blame['committer']); - } + $taskModules = $this->loadModel('tree')->getTaskOptionMenu($repoExecution, 0, 0, 'allModule'); + $taskRepoModule = (!empty($lastReview->task) && $lastReview->task->execution == $repoExecution) ? $lastReview->task->module : ''; + $taskMembers = $this->loadModel('user')->getTeamMemberPairs($repoExecution, 'execution', 'nodeleted'); } -chdir($cwd); -//$reviews = $this->mr->getReview($repoID, $file, $info->revision); -$reviews = $this->mr->getReview($repoID, $file, ''); -$v1 = isset($oldRevision) ? $oldRevision : 0; +$reviews = $this->mr->getReview($repoID, $MR->id); +$v1 = isset($oldRevision) ? $oldRevision : 0; + $this->loadModel('repo'); -// $bugUrl = $this->repo->createLink('addBug', "repoID=$repoID&file=$file&v1=$v1&v2={$info->revision}"); -$bugUrl = $this->createLink('mr', 'addBug', "repoID=$repoID&file=$file&v1=$v1&v2="); -$commentUrl = $this->createLink('mr', 'addComment'); + +$taskModuleSelect = html::select('taskModule', $taskModules, $taskRepoModule, 'class="form-control chosen"'); +$taskUserSelect = html::select('taskAssignedTo', $taskMembers, '', 'class="form-control chosen"'); +$taskExecutionSelect = html::select('taskExecution', $taskExecutions, $repoExecution, 'class="form-control chosen" onchange="changeExecution(this)"'); + +$reviewUrl = $this->createLink('mr', 'addReview', "repoID=$repoID&mr={$MR->id}&v1=$v1&v2="); $productSelect = html::select('product', $products, $repoProduct, 'class="product form-control chosen" onchange="changeProduct(this)"'); $branches = $this->loadModel('branch')->getPairs($repoProduct); -$moduleSelect = html::select('module', $modules, $repoModule, 'class="form-control chosen"'); +$moduleSelect = html::select('module', $modules, $bugRepoModule, 'class="form-control chosen"'); $executionSelect = html::select('execution', $executions, '', 'class="form-control chosen"'); $typeSelect = html::select('repoType', $lang->repo->typeList, '', 'class="form-control chosen"'); $userSelect = html::select('assignedTo', $users, '', 'class="form-control chosen assignedTo"'); -$bugs = array(); + +$lineReviews = array(); foreach($reviews as $line => $lineReview) { - $lineBugs = array(); - foreach ($lineReview['bugs'] as $bugID => $bug) + foreach($lineReview as $objectType => $objects) { - $lineBug = array(); - $lineBug['id'] = $bugID; - $lineBug['line'] = $line; - $lineBug['title'] = $bug->title; - $lineBug['steps'] = $bug->steps; - $lineBug['realname'] = $bug->realname; - $lineBug['openedDate'] = substr($bug->openedDate, 5, 11); - $lineBug['lines'] = $bug->lines; - if($bug->edit) $lineBug['edit'] = true; - if($bug->delete) $lineBug['delete'] = true; - - if(isset($lineReview['comments'])) + foreach($objects as $objectID => $object) { - if(isset($lineReview['comments'][$bugID])) - { - $comments = $lineReview['comments'][$bugID]; - $bugComments = array(); - foreach ($comments as $commentID => $comment) - { - $bugComment = array( - 'id' => $comment->id, - 'edit' => $comment->edit, - 'realname' => $comment->realname, - 'date' => substr($comment->date, 5, 11), - 'comment' => $comment->comment, - ); - $bugComments[] = $bugComment; - } - $lineBug['comments'] = $bugComments; - } + $lineReview = array(); + $lineReview['id'] = $objectID; + $lineReview['line'] = $line; + $lineReview['title'] = $objectType == 'bug' ? $object->title : $object->name; + $lineReview['content'] = $objectType == 'bug' ? $object->steps : $object->desc; + $lineReview['realname'] = $object->realname; + $lineReview['openedDate'] = substr($object->openedDate, 5, 11); + $lineReview['lines'] = $object->lines; + $lineReview['objectType'] = $objectType; + $lineReview['entry'] = $object->entry; + $lineReview['edit'] = common::hasPriv($objectType, 'edit'); + $lineReview['delete'] = common::hasPriv($objectType, 'delete'); + $lineReview['view'] = common::hasPriv($objectType, 'view'); + $lineReviews[$line][] = $lineReview; } - $lineBugs[] = $lineBug; } - - $bugs[$line] = $lineBugs; } -js::set('bugs', $bugs); +js::set('reviews', $lineReviews); js::set('productError', $lang->repo->error->product); js::set('contentError', $lang->repo->error->commentText); js::set('titleError', $lang->repo->error->title); js::set('commentError', $lang->repo->error->comment); js::set('submit', $lang->repo->submit); js::set('cancel', $lang->repo->cancel); -js::set('confirmDelete', $lang->repo->notice->deleteBug); -js::set('confirmDeleteComment', $lang->repo->notice->deleteComment); +js::set('confirmDelete', $lang->repo->notice->deleteReview); js::set('repoID', $repoID); -// js::set('revision', $info->revision); +js::set('MRID', $MR->id); js::set('revision', ''); -js::set('file', $file); -js::set('blamePairs', $blamePairs); ?> - - -
    + + +
    fileName;?>
    + + + + + + - - + + + + - + - @@ -160,8 +152,9 @@ js::set('blamePairs', $blamePairs);
    mr->reviewType;?>mr->reviewTypeList, 'bug', "class='form-control' onchange=changeReviewType(this)")?>
    repo->product?> +
    @@ -131,13 +114,22 @@ js::set('blamePairs', $blamePairs);
    repo->execution?> +
    +
    +
    repo->type?>
    repo->module?>
    repo->assign?> +
    +
    +
    repo->lines?>
    @@ -149,7 +141,7 @@ js::set('blamePairs', $blamePairs);
    repo->title?> +
    - repo->submit, '', 'btn btn-wide btn-primary bugSubmit');?> + repo->submit, '', 'btn btn-wide btn-primary reviewSubmit');?> cancel, "onclick='hiddenForm()'", 'btn btn-wide');?> +
    @@ -169,73 +162,87 @@ js::set('blamePairs', $blamePairs);
    -
    -user->errorDeny, $lang->repo->common, $lang->repo->addBug);?> + +user->errorDeny, $lang->mr->common, $lang->mr->addReview);?>
    -
    +
    - - Bug# - - Bug# - - - - - - - +
    - +

    repo->lines?>    

    -
    - - - -
    -

    -
    - - -
    - - - - -
    -
    - +

    -
    - :     -
    - - - -
    -
    -