This commit is contained in:
滔哥
2017-11-03 00:28:03 +08:00
59 changed files with 440 additions and 487 deletions
+2 -2
View File
@@ -20,7 +20,7 @@ CREATE TABLE IF NOT EXISTS `zt_webhook` (
`type` varchar(10) NOT NULL DEFAULT 'default',
`name` varchar(50) NOT NULL,
`url` varchar(255) NOT NULL,
`contentType` enum('json','form') NOT NULL DEFAULT 'json',
`contentType` varchar(30) NOT NULL DEFAULT 'application/json',
`sendType` enum('sync','async') NOT NULL DEFAULT 'sync',
`products` text NOT NULL,
`projects` text NOT NULL,
@@ -56,7 +56,7 @@ CREATE TABLE IF NOT EXISTS `zt_log` (
`action` mediumint(8) unsigned NOT NULL,
`date` datetime NOT NULL,
`url` varchar(255) NOT NULL,
`contentType` varchar(40) NOT NULL,
`contentType` varchar(30) NOT NULL,
`data` text NOT NULL,
`result` text NOT NULL,
PRIMARY KEY `id` (`id`),
+3
View File
@@ -110,6 +110,7 @@ $lang->action->desc->svncommited = '$date, submitted by <strong>$actor</stron
$lang->action->desc->gitcommited = '$date, submitted by <strong>$actor</strong> and the version is <strong>#$extra</strong>.' . "\n";
$lang->action->desc->finished = '$date, finished by <strong>$actor</strong>.' . "\n";
$lang->action->desc->paused = '$date, paused by <strong>$actor</strong>.' . "\n";
$lang->action->desc->verified = '$date, verified by <strong>$actor</strong>.' . "\n";
$lang->action->desc->diff1 = '<strong><i>%s</i></strong> has been changed. Its value was "%s" and the new value is "%s".<br />' . "\n";
$lang->action->desc->diff2 = '<strong><i>%s</i></strong> has been changed. The difference is ' . "\n" . "<blockquote>%s</blockquote>" . "\n<div class='hidden'>%s</div>";
$lang->action->desc->diff3 = 'File Name %s was changed to %s .' . "\n";
@@ -171,6 +172,7 @@ $lang->action->label->editestimate = 'Edited Man-Hour';
$lang->action->label->canceled = 'Cancelled';
$lang->action->label->finished = 'Finished';
$lang->action->label->paused = 'Paused';
$lang->action->label->paused = 'Verified';
$lang->action->label->delayed = 'Delayed';
$lang->action->label->suspended = 'Suspended';
$lang->action->label->login = 'Login';
@@ -262,5 +264,6 @@ $lang->action->search->label['editestimate'] = $lang->action->label->edit
$lang->action->search->label['canceled'] = $lang->action->label->canceled;
$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['login'] = $lang->action->label->login;
$lang->action->search->label['logout'] = $lang->action->label->logout;
+6 -3
View File
@@ -63,7 +63,7 @@ $lang->action->objectTypes['bug'] = 'Bug';
$lang->action->objectTypes['case'] = '用例';
$lang->action->objectTypes['caseresult'] = '用例结果';
$lang->action->objectTypes['stepresult'] = '用例步骤';
$lang->action->objectTypes['testtask'] = '测试版本';
$lang->action->objectTypes['testtask'] = '测试单';
$lang->action->objectTypes['user'] = '用户';
$lang->action->objectTypes['doc'] = '文档';
$lang->action->objectTypes['doclib'] = '文档库';
@@ -112,6 +112,7 @@ $lang->action->desc->svncommited = '$date, 由 <strong>$actor</strong> 提交
$lang->action->desc->gitcommited = '$date, 由 <strong>$actor</strong> 提交代码,版本为<strong>#$extra</strong>。' . "\n";
$lang->action->desc->finished = '$date, 由 <strong>$actor</strong> 完成。' . "\n";
$lang->action->desc->paused = '$date, 由 <strong>$actor</strong> 暂停。' . "\n";
$lang->action->desc->verified = '$date, 由 <strong>$actor</strong> 验收。' . "\n";
$lang->action->desc->diff1 = '修改了 <strong><i>%s</i></strong>,旧值为 "%s",新值为 "%s"。<br />' . "\n";
$lang->action->desc->diff2 = '修改了 <strong><i>%s</i></strong>,区别为:' . "\n" . "<blockquote>%s</blockquote>" . "\n<div class='hidden'>%s</div>";
$lang->action->desc->diff3 = '将文件名 %s 改为 %s 。' . "\n";
@@ -173,6 +174,7 @@ $lang->action->label->editestimate = '编辑了工时';
$lang->action->label->canceled = '取消了';
$lang->action->label->finished = '完成了';
$lang->action->label->paused = '暂停了';
$lang->action->label->verified = '验收了';
$lang->action->label->delayed = '延期';
$lang->action->label->suspended = '挂起';
$lang->action->label->login = '登录系统';
@@ -191,7 +193,7 @@ $lang->action->label->task = '任务|task|view|taskID=%s';
$lang->action->label->build = 'Build|build|view|buildID=%s';
$lang->action->label->bug = 'Bug|bug|view|bugID=%s';
$lang->action->label->case = '用例|testcase|view|caseID=%s';
$lang->action->label->testtask = '测试任务|testtask|view|caseID=%s';
$lang->action->label->testtask = '测试单|testtask|view|caseID=%s';
$lang->action->label->testsuite = '测试套件|testsuite|view|suiteID=%s';
$lang->action->label->caselib = '测试库|testsuite|libview|libID=%s';
$lang->action->label->todo = 'todo|todo|view|todoID=%s';
@@ -213,7 +215,7 @@ $lang->action->search->objectTypeList['caseresult'] = '用例结果';
$lang->action->search->objectTypeList['stepresult'] = '用例步骤';
$lang->action->search->objectTypeList['story'] = '需求';
$lang->action->search->objectTypeList['task'] = '任务';
$lang->action->search->objectTypeList['testtask'] = '测试任务';
$lang->action->search->objectTypeList['testtask'] = '测试单';
$lang->action->search->objectTypeList['user'] = '用户';
$lang->action->search->objectTypeList['doc'] = '文档';
$lang->action->search->objectTypeList['doclib'] = '文档库';
@@ -266,5 +268,6 @@ $lang->action->search->label['editestimate'] = $lang->action->label->edit
$lang->action->search->label['canceled'] = $lang->action->label->canceled;
$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['login'] = $lang->action->label->login;
$lang->action->search->label['logout'] = $lang->action->label->logout;
+1 -1
View File
@@ -23,7 +23,7 @@
<th width='60'><?php echo $lang->project->totalEstimate;?></th>
<th width='60'><?php echo $lang->project->totalConsumed;?></th>
<th width='60'><?php echo $lang->project->totalLeft;?></th>
<th width='115'><?php echo $lang->project->progess;?></th>
<th width='115'><?php echo $lang->project->progress;?></th>
<th width='100' class='{sorter: false}'><?php echo $lang->project->burn;?></th>
</tr>
</thead>
+9 -9
View File
@@ -345,7 +345,7 @@ $lang->admin->menu->safe = array('link' => 'Security|admin|safe', 'alias' =
$lang->admin->menu->cron = array('link' => 'Cron|cron|index', 'subModule' => 'cron');
$lang->admin->menu->trashes = array('link' => 'Recycle|action|trash', 'subModule' => 'action');
$lang->admin->menu->dev = array('link' => 'Develop|dev|api', 'alias' => 'db', 'subModule' => 'dev,editor');
$lang->admin->menu->entry = array('link' => 'API|entry|browse', 'alias' => 'create,edit', 'subModule' => 'entry,webhook');
$lang->admin->menu->api = array('link' => 'API|webhook|browse', 'alias' => 'create,edit', 'subModule' => 'entry,webhook');
$lang->admin->menu->sso = 'RangerTeam|admin|sso';
$lang->convert = new stdclass();
@@ -434,14 +434,14 @@ $lang->error->editedByOther = 'This record might have been changed. Please ref
$lang->error->tutorialData = 'No data can be imported in tutorial mode. Please exit tutorial first!';
$lang->error->entry = array();
$lang->error->entry['300001'] = 'Param code not set.';
$lang->error->entry['300002'] = 'Param token not set.';
$lang->error->entry['310001'] = 'Entry not exist.';
$lang->error->entry['310002'] = 'Key of entry not set.';
$lang->error->entry['320001'] = 'IP denied.';
$lang->error->entry['330001'] = 'Invalid token.';
$lang->error->entry['340001'] = 'Session code not set.';
$lang->error->entry['340002'] = 'Session verify failed.';
$lang->error->entry['301'] = 'Param code not set.';
$lang->error->entry['302'] = 'Param token not set.';
$lang->error->entry['311'] = 'Entry not exist.';
$lang->error->entry['312'] = 'Key of entry not set.';
$lang->error->entry['321'] = 'IP denied.';
$lang->error->entry['331'] = 'Invalid token.';
$lang->error->entry['341'] = 'Session code not set.';
$lang->error->entry['342'] = 'Session verify failed.';
/* 分页信息。*/
$lang->pager = new stdclass();
-1
View File
@@ -40,7 +40,6 @@ $lang->product->menuOrder[40] = 'doc';
$lang->product->menuOrder[45] = 'project';
$lang->product->menuOrder[50] = 'branch';
$lang->product->menuOrder[55] = 'module';
$lang->product->menuOrder[57] = 'category';
$lang->product->menuOrder[60] = 'view';
$lang->product->menuOrder[65] = 'create';
$lang->product->menuOrder[70] = 'all';
+16 -16
View File
@@ -122,7 +122,7 @@ $lang->searchObjects['user'] = '用户';
$lang->searchObjects['build'] = '版本';
$lang->searchObjects['release'] = '发布';
$lang->searchObjects['productplan'] = $lang->productCommon . '计划';
$lang->searchObjects['testtask'] = '测试版本';
$lang->searchObjects['testtask'] = '测试单';
$lang->searchObjects['doc'] = '文档';
$lang->searchObjects['testcase'] = '用例库';
$lang->searchObjects['testreport'] = '测试报告';
@@ -222,7 +222,7 @@ $lang->project->menu->story = array('link' => '需求|project|story|projectI
$lang->project->menu->bug = 'Bug|project|bug|projectID=%s';
$lang->project->menu->dynamic = '动态|project|dynamic|projectID=%s';
$lang->project->menu->build = array('link' => '版本|project|build|projectID=%s', 'subModule' => 'build');
$lang->project->menu->testtask = array('link' => '测试|project|testtask|projectID=%s');
$lang->project->menu->testtask = array('link' => '测试单|project|testtask|projectID=%s');
$lang->project->menu->team = array('link' => '团队|project|team|projectID=%s', 'alias' => 'managemembers');
$lang->project->menu->doc = array('link' => '文档|doc|objectLibs|type=project&objectID=%s&from=project', 'subModule' => 'doc');
$lang->project->menu->product = $lang->productCommon . '|project|manageproducts|projectID=%s';
@@ -243,7 +243,7 @@ $lang->qa->menu = new stdclass();
$lang->qa->menu->product = array('link' => '%s', 'fixed' => true);
$lang->qa->menu->bug = array('link' => 'Bug|bug|browse|productID=%s');
$lang->qa->menu->testcase = array('link' => '用例|testcase|browse|productID=%s');
$lang->qa->menu->testtask = array('link' => '版本|testtask|browse|productID=%s');
$lang->qa->menu->testtask = array('link' => '测试单|testtask|browse|productID=%s');
$lang->qa->menu->testsuite = array('link' => '套件|testsuite|browse|productID=%s');
$lang->qa->menu->report = array('link' => '报告|testreport|browse|productID=%s');
$lang->qa->menu->caselib = array('link' => '用例库|testsuite|library');
@@ -255,7 +255,7 @@ $lang->bug->menu = new stdclass();
$lang->bug->menu->product = array('link' => '%s', 'fixed' => true);
$lang->bug->menu->bug = array('link' => 'Bug|bug|browse|productID=%s', 'alias' => 'view,create,batchcreate,edit,resolve,close,activate,report,batchedit,batchactivate,confirmbug,assignto', 'subModule' => 'tree');
$lang->bug->menu->testcase = array('link' => '用例|testcase|browse|productID=%s');
$lang->bug->menu->testtask = array('link' => '版本|testtask|browse|productID=%s');
$lang->bug->menu->testtask = array('link' => '测试单|testtask|browse|productID=%s');
$lang->bug->menu->testsuite = array('link' => '套件|testsuite|browse|productID=%s');
$lang->bug->menu->report = array('link' => '报告|testreport|browse|productID=%s');
$lang->bug->menu->caselib = array('link' => '用例库|testsuite|library');
@@ -267,7 +267,7 @@ $lang->testcase->menu = new stdclass();
$lang->testcase->menu->product = array('link' => '%s', 'fixed' => true);
$lang->testcase->menu->bug = array('link' => 'Bug|bug|browse|productID=%s');
$lang->testcase->menu->testcase = array('link' => '用例|testcase|browse|productID=%s', 'alias' => 'view,create,batchcreate,edit,batchedit,showimport,groupcase,importfromlib', 'subModule' => 'tree');
$lang->testcase->menu->testtask = array('link' => '版本|testtask|browse|productID=%s', 'alias' => 'view,create,edit,linkcase,cases,start,close,batchrun,groupcase,report');
$lang->testcase->menu->testtask = array('link' => '测试单|testtask|browse|productID=%s', 'alias' => 'view,create,edit,linkcase,cases,start,close,batchrun,groupcase,report');
$lang->testcase->menu->testsuite = array('link' => '套件|testsuite|browse|productID=%s', 'alias' => 'view,create,edit,linkcase');
$lang->testcase->menu->report = array('link' => '报告|testreport|browse|productID=%s', 'alias' => 'view,create,edit');
$lang->testcase->menu->caselib = array('link' => '用例库|testsuite|library');
@@ -285,7 +285,7 @@ $lang->caselib->menu = new stdclass();
$lang->caselib->menu->lib = array('link' => '%s', 'fixed' => true);
$lang->caselib->menu->bug = array('link' => 'Bug|bug|browse|');
$lang->caselib->menu->testcase = array('link' => '用例|testcase|browse|');
$lang->caselib->menu->testtask = array('link' => '版本|testtask|browse|');
$lang->caselib->menu->testtask = array('link' => '测试单|testtask|browse|');
$lang->caselib->menu->testsuite = array('link' => '套件|testsuite|browse|');
$lang->caselib->menu->report = array('link' => '报告|testreport|browse|');
$lang->caselib->menu->caselib = array('link' => '用例库|testsuite|library', 'alias' => 'createlib,createcase,libview,edit,batchcreatecase,showimport', 'subModule' => 'tree,testcase');
@@ -345,7 +345,7 @@ $lang->admin->menu->safe = array('link' => '安全|admin|safe', 'alias' =>
$lang->admin->menu->cron = array('link' => '计划任务|cron|index', 'subModule' => 'cron');
$lang->admin->menu->trashes = array('link' => '回收站|action|trash', 'subModule' => 'action');
$lang->admin->menu->dev = array('link' => '二次开发|dev|api', 'alias' => 'db', 'subModule' => 'dev,editor');
$lang->admin->menu->entry = array('link' => '接口|entry|browse', 'alias' => 'create,edit', 'subModule' => 'entry,webhook');
$lang->admin->menu->api = array('link' => '接口|webhook|browse', 'alias' => 'create,edit', 'subModule' => 'entry,webhook');
$lang->admin->menu->sso = '然之集成|admin|sso';
$lang->convert = new stdclass();
@@ -434,14 +434,14 @@ $lang->error->editedByOther = '该记录可能已经被改动。请刷新页
$lang->error->tutorialData = '新手模式下不会插入数据,请退出新手模式操作';
$lang->error->entry = array();
$lang->error->entry['300001'] = '缺少code参数';
$lang->error->entry['300002'] = '缺少token参数';
$lang->error->entry['310001'] = '应用不存在';
$lang->error->entry['310002'] = '应用未设置密钥';
$lang->error->entry['320001'] = '该IP访问被限制访问';
$lang->error->entry['330001'] = '不合法的token参数';
$lang->error->entry['340001'] = '缺少session code';
$lang->error->entry['340002'] = 'session验证失败';
$lang->error->entry['301'] = '缺少code参数';
$lang->error->entry['302'] = '缺少token参数';
$lang->error->entry['311'] = '应用不存在';
$lang->error->entry['312'] = '应用未设置密钥';
$lang->error->entry['321'] = '该IP访问被限制访问';
$lang->error->entry['331'] = '不合法的token参数';
$lang->error->entry['341'] = '缺少session code';
$lang->error->entry['342'] = 'session验证失败';
/* 分页信息。*/
$lang->pager = new stdclass();
@@ -680,7 +680,7 @@ if(isset($config->global->flow) and $config->global->flow == 'onlyTest')
$lang->menu->bug = 'Bug|bug|index';
$lang->menu->testcase = '用例|testcase|index';
$lang->menu->testsuite = '套件|testsuite|index';
$lang->menu->testtask = '测试|testtask|index';
$lang->menu->testtask = '测试单|testtask|index';
$lang->menu->caselib = '用例库|testsuite|library';
$lang->menuOrder[6] = 'bug';
+35
View File
@@ -0,0 +1,35 @@
<?php
$lang->entry->common = 'Entry';
$lang->entry->list = 'Entry List';
$lang->entry->api = 'API';
$lang->entry->webhook = 'Webhook';
$lang->entry->log = 'Log';
$lang->entry->browse = 'Browse';
$lang->entry->create = 'Create';
$lang->entry->edit = 'Edit';
$lang->entry->delete = 'Delete';
$lang->entry->createKey = 'Regenerate';
$lang->entry->id = 'ID';
$lang->entry->name = 'Name';
$lang->entry->code = 'Code';
$lang->entry->key = 'Key';
$lang->entry->ip = 'IP';
$lang->entry->desc = 'Desc';
$lang->entry->createdBy = 'Created By';
$lang->entry->createdDate = 'Created Date';
$lang->entry->editedby = 'Edited By';
$lang->entry->editedDate = 'Edited Date';
$lang->entry->date = 'Request Time';
$lang->entry->url = 'Request URL';
$lang->entry->saveSuccess = 'Save success.';
$lang->entry->confirmDelete = 'Are you sure delete this entry?';
$lang->entry->help = 'Help';
$lang->entry->note = new stdClass();
$lang->entry->note->name = 'Name';
$lang->entry->note->code = 'Code, should be english and number.';
$lang->entry->note->ip = "Use comma between two IPs. IP segment is supported, e.g. 192.168.1.*";
$lang->entry->note->allIP = 'All';
-2
View File
@@ -3,7 +3,6 @@ $lang->entry->common = '应用';
$lang->entry->list = '应用列表';
$lang->entry->api = '接口';
$lang->entry->webhook = 'webhook';
$lang->entry->dingding = '钉钉';
$lang->entry->log = '日志';
$lang->entry->browse = '浏览应用';
@@ -25,7 +24,6 @@ $lang->entry->editedDate = '编辑时间';
$lang->entry->date = '请求时间';
$lang->entry->url = '请求地址';
$lang->entry->apiIndex = '应用入口';
$lang->entry->saveSuccess = '保存成功';
$lang->entry->confirmDelete = '您确认要删除该应用吗?';
$lang->entry->help = '使用说明';
+1 -1
View File
@@ -8,7 +8,7 @@ $config->product->custom = new stdclass();
$config->product->custom->batchEditFields = 'PO,QD,RD,status';
$config->product->list = new stdclass();
$config->product->list->exportFields = 'id,name,activeStories,changedStories,draftStories,closedStories,plans,releases,bugs,unResolvedBugs,assignToNullBugs';
$config->product->list->exportFields = 'id,name,line,activeStories,changedStories,draftStories,closedStories,plans,releases,bugs,unResolvedBugs,assignToNullBugs';
global $lang, $app;
$app->loadLang('story');
+19 -14
View File
@@ -231,7 +231,7 @@ class product extends control
$this->view->poUsers = $this->loadModel('user')->getPairs('nodeleted|pofirst|noclosed');
$this->view->qdUsers = $this->loadModel('user')->getPairs('nodeleted|qdfirst|noclosed');
$this->view->rdUsers = $this->loadModel('user')->getPairs('nodeleted|devfirst|noclosed');
$this->view->categories = $this->loadModel('tree')->getOptionMenu($rootID = 0, $type = 'category');
$this->view->lines = array('') + $this->loadModel('tree')->getLinePairs();
unset($this->lang->product->typeList['']);
$this->display();
@@ -276,7 +276,7 @@ class product extends control
$this->view->poUsers = $this->loadModel('user')->getPairs('nodeleted|pofirst', $product->PO);
$this->view->qdUsers = $this->loadModel('user')->getPairs('nodeleted|qdfirst', $product->QD);
$this->view->rdUsers = $this->loadModel('user')->getPairs('nodeleted|devfirst', $product->RD);
$this->view->categories = $this->loadModel('tree')->getOptionMenu($rootID = 0, $type = 'category');
$this->view->lines = array('') + $this->loadModel('tree')->getLinePairs();
unset($this->lang->product->typeList['']);
$this->display();
@@ -394,7 +394,7 @@ class product extends control
$this->view->actions = $this->loadModel('action')->getList('product', $productID);
$this->view->users = $this->user->getPairs('noletter');
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->categories = $this->loadModel('tree')->getOptionMenu($rootID = 0, $type = 'category');
$this->view->lines = array('') + $this->loadModel('tree')->getLinePairs();
$this->display();
}
@@ -586,20 +586,22 @@ class product extends control
foreach($products as $key => $product) $product->key = $productsPinyin[$product->name];
/* Sort products as categories' order first. */
$categories = $this->loadModel('tree')->getOptionMenu($rootID = 0, $type = 'category');
/* Sort products as lines' order first. */
$lines = $this->loadModel('tree')->getLinePairs();
$productList = array();
foreach($categories as $id => $category)
foreach($lines as $id => $name)
{
foreach($products as $product)
foreach($products as $key => $product)
{
if($product->category == $id)
if($product->line == $id)
{
$product->name = ltrim($category. '/' . $product->name, '/');
$product->name = $name . '/' . $product->name;
$productList[] = $product;
unset($products[$key]);
}
}
}
$productList = array_merge($productList, $products);
$this->view->products = $productList;
$this->display();
@@ -648,7 +650,7 @@ class product extends control
* All product.
*
* @param int $productID
* @param int $category
* @param int $line
* @param string $status
* @param string $orderBy
* @param int $recTotal
@@ -657,7 +659,7 @@ class product extends control
* @access public
* @return void
*/
public function all($productID = 0, $category = 0, $status = 'noclosed', $orderBy = 'order_desc', $recTotal = 0, $recPerPage = 10, $pageID = 1)
public function all($productID = 0, $line = 0, $status = 'noclosed', $orderBy = 'order_desc', $recTotal = 0, $recPerPage = 10, $pageID = 1)
{
$this->session->set('productList', $this->app->getURI(true));
$productID = $this->product->saveState($productID, $this->products);
@@ -670,10 +672,11 @@ class product extends control
$this->app->loadLang('my');
$this->view->title = $this->lang->product->allProduct;
$this->view->position[] = $this->lang->product->allProduct;
$this->view->productStats = $this->product->getStats($orderBy, $pager, $status, $category);
$this->view->categoryTree = $this->loadModel('tree')->getTreeMenu(0, $viewType = 'category', $startModuleID = 0, array('treeModel', 'createCategoryLink'), array('productID' => $productID, 'status' => $status));
$this->view->productStats = $this->product->getStats($orderBy, $pager, $status, $line);
$this->view->lineTree = $this->loadModel('tree')->getTreeMenu(0, $viewType = 'line', $startModuleID = 0, array('treeModel', 'createLineLink'), array('productID' => $productID, 'status' => $status));
$this->view->lines = array('') + $this->tree->getLinePairs();
$this->view->productID = $productID;
$this->view->category = $category;
$this->view->line = $line;
$this->view->status = $status;
$this->view->orderBy = $orderBy;
$this->view->pager = $pager;
@@ -704,9 +707,11 @@ class product extends control
unset($fields[$key]);
}
$lines = $this->loadModel('tree')->getLinePairs();
$productStats = $this->product->getStats($orderBy, null, $status);
foreach($productStats as $i => $product)
{
$product->line = zget($lines, $product->line, '');
$product->activeStories = (int)$product->stories['active'];
$product->changedStories = (int)$product->stories['changed'];
$product->draftStories = (int)$product->stories['draft'];
+2
View File
@@ -55,8 +55,10 @@ $lang->product->confirmDelete = " Do you want to delete {$lang->productCommon}
$lang->product->errorNoProduct = "{$lang->productCommon} is not created yet!";
$lang->product->accessDenied = "You have no access to {$lang->productCommon}.";
$lang->product->id = 'ID';
$lang->product->name = "{$lang->productCommon} Name";
$lang->product->code = "{$lang->productCommon} Code";
$lang->product->line = 'Product Line';
$lang->product->order = 'Sort';
$lang->product->type = "{$lang->productCommon} Type";
$lang->product->status = 'Status';
+1 -1
View File
@@ -58,7 +58,7 @@ $lang->product->accessDenied = "您无权访问该{$lang->productCommon}";
$lang->product->id = "编号";
$lang->product->name = "{$lang->productCommon}名称";
$lang->product->code = "{$lang->productCommon}代号";
$lang->product->category = "{$lang->productCommon}目录";
$lang->product->line = '产品线';
$lang->product->order = '排序';
$lang->product->type = "{$lang->productCommon}类型";
$lang->product->status = '状态';
+6 -6
View File
@@ -203,15 +203,15 @@ class productModel extends model
*
* @param string $status
* @param int $limit
* @param int $category
* @param int $line
* @access public
* @return array
*/
public function getList($status = 'all', $limit = 0, $category = 0)
public function getList($status = 'all', $limit = 0, $line = 0)
{
return $this->dao->select('*')->from(TABLE_PRODUCT)
->where('deleted')->eq(0)
->beginIF($category > 0)->andWhere('category')->eq($category)->fi()
->beginIF($line > 0)->andWhere('line')->eq($line)->fi()
->beginIF($status == 'noclosed')->andWhere('status')->ne('closed')->fi()
->beginIF($status != 'all' and $status != 'noclosed' and $status != 'involved')->andWhere('status')->in($status)->fi()
->beginIF($status == 'involved')
@@ -670,17 +670,17 @@ class productModel extends model
* @param string $orderBy
* @param object $pager
* @param string $status
* @param int $category
* @param int $line
* @access public
* @return array
*/
public function getStats($orderBy = 'order_desc', $pager = null, $status = 'noclosed', $category = 0)
public function getStats($orderBy = 'order_desc', $pager = null, $status = 'noclosed', $line = 0)
{
$this->loadModel('report');
$this->loadModel('story');
$this->loadModel('bug');
$products = $this->getList($status, $limit = 0, $category);
$products = $this->getList($status, $limit = 0, $line);
foreach($products as $productID => $product)
{
if(!$this->checkPriv($product)) unset($products[$productID]);
+11 -9
View File
@@ -20,9 +20,9 @@
<?php echo html::a($this->createLink('product', 'create'), "<i class='icon-plus'></i> " . $lang->product->create,'', "class='btn'") ?>
</div>
<ul class='nav'>
<?php echo "<li id='noclosedTab'>" . html::a(inlink("all", "productID=$productID&category=&status=noclosed"), $lang->product->unclosed) . '</li>';?>
<?php echo "<li id='closedTab'>" . html::a(inlink("all", "productID=$productID&category=&status=closed"), $lang->product->statusList['closed']) . '</li>';?>
<?php echo "<li id='allTab'>" . html::a(inlink("all", "productID=$productID&category=&status=all"), $lang->product->allProduct) . '</li>';?>
<?php echo "<li id='noclosedTab'>" . html::a(inlink("all", "productID=$productID&line=&status=noclosed"), $lang->product->unclosed) . '</li>';?>
<?php echo "<li id='closedTab'>" . html::a(inlink("all", "productID=$productID&line=&status=closed"), $lang->product->statusList['closed']) . '</li>';?>
<?php echo "<li id='allTab'>" . html::a(inlink("all", "productID=$productID&line=&status=all"), $lang->product->allProduct) . '</li>';?>
</ul>
</div>
@@ -30,11 +30,11 @@
<a class='side-handle' data-id='productTree'><i class='icon-caret-left'></i></a>
<div class='side-body'>
<div class='panel panel-sm'>
<div class='panel-heading nobr'><?php echo html::icon($lang->icons['product']);?> <strong><?php echo $lang->product->category;?></strong></div>
<div class='panel-heading nobr'><?php echo html::icon($lang->icons['product']);?> <strong><?php echo $lang->product->line;?></strong></div>
<div class='panel-body'>
<?php echo $categoryTree;?>
<?php echo $lineTree;?>
<div class='text-right'>
<?php common::printLink('tree', 'browse', "rootID=&view=category", $lang->tree->manageCategory);?>
<?php common::printLink('tree', 'browse', "rootID=&view=line", $lang->tree->manageLine);?>
</div>
</div>
</div>
@@ -58,11 +58,12 @@
<?php $canOrder = (common::hasPriv('product', 'updateOrder') and strpos($orderBy, 'order') !== false)?>
<form method='post' action='<?php echo inLink('batchEdit', "productID=$productID");?>' id='productsForm'>
<table class='table table-condensed table-hover table-striped tablesorter table-datatable table-selectable' id='productList'>
<?php $vars = "category=$category&productID=$productID&status=$status&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
<?php $vars = "productID=$productID&line=$line&status=$status&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
<thead>
<tr>
<th class='w-id'><?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th><?php common::printOrderLink('name', $orderBy, $vars, $lang->product->name);?></th>
<th class='w-80px text-left'><?php common::printOrderLink('line', $orderBy, $vars, $lang->product->line);?></th>
<th class='w-80px'><?php echo $lang->product->activeStories;?></th>
<th class='w-80px'><?php echo $lang->product->changedStories;?></th>
<th class='w-80px'><?php echo $lang->product->draftStories;?></th>
@@ -88,6 +89,7 @@
<?php echo html::a($this->createLink('product', 'view', 'product=' . $product->id), sprintf('%03d', $product->id));?>
</td>
<td class='text-left' title='<?php echo $product->name?>'><?php echo html::a($this->createLink('product', 'view', 'product=' . $product->id), $product->name);?></td>
<td class='text-left'><?php echo zget($lines, $product->line);?></td>
<td><?php echo $product->stories['active']?></td>
<td><?php echo $product->stories['changed']?></td>
<td><?php echo $product->stories['draft']?></td>
@@ -105,13 +107,13 @@
</tbody>
<tfoot>
<tr>
<td colspan='<?php echo $canOrder ? 12 : 11?>'>
<td colspan='<?php echo $canOrder ? 13 : 12?>'>
<div class='table-actions clearfix'>
<?php if($canBatchEdit and !empty($productStats)):?>
<?php echo html::selectButton();?>
<?php echo html::submitButton($lang->product->batchEdit);?>
<?php endif;?>
<?php if(!$canOrder and common::hasPriv('product', 'updateOrder')) echo html::a(inlink('all', "productID=$productID&category=$category&status=$status&order=order_desc&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"), $lang->product->updateOrder, '' , "class='btn'");?>
<?php if(!$canOrder and common::hasPriv('product', 'updateOrder')) echo html::a(inlink('all', "productID=$productID&line=$line&status=$status&order=order_desc&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"), $lang->product->updateOrder, '' , "class='btn'");?>
</div>
<?php $pager->show();?>
</td>
+3 -3
View File
@@ -31,9 +31,9 @@
<td><?php echo html::input('code', '', "class='form-control' autocomplete='off'");?></td><td></td>
</tr>
<tr>
<th><?php echo $lang->product->category;?></th>
<td><?php echo html::select('category', $categories, '', "class='form-control chosen'");?></td>
<td><?php if(!$categories) common::printLink('tree', 'browse', "rootID=&view=category", $lang->tree->manageCategory);?></td>
<th><?php echo $lang->product->line;?></th>
<td><?php echo html::select('line', $lines, '', "class='form-control chosen'");?></td>
<td><?php if(!$lines) common::printLink('tree', 'browse', "rootID=&view=line", $lang->tree->manageLine);?></td>
</tr>
<tr>
<th><?php echo $lang->product->PO;?></th>
+3 -3
View File
@@ -32,9 +32,9 @@
<td><?php echo html::input('code', $product->code, "class='form-control' autocomplete='off'");?></td><td></td>
</tr>
<tr>
<th><?php echo $lang->product->category;?></th>
<td><?php echo html::select('category', $categories, $product->category, "class='form-control chosen'");?></td>
<td><?php if(!$categories) common::printLink('tree', 'browse', 'rootID=&view=category', $lang->tree->manageCategory);?></td>
<th><?php echo $lang->product->line;?></th>
<td><?php echo html::select('line', $lines, $product->line, "class='form-control chosen'");?></td>
<td><?php if(!$lines) common::printLink('tree', 'browse', 'rootID=&view=line', $lang->tree->manageLine);?></td>
</tr>
<tr>
<th><?php echo $lang->product->PO;?></th>
+2 -2
View File
@@ -70,8 +70,8 @@
<td><?php echo $product->code;?></td>
</tr>
<tr>
<th><?php echo $lang->product->category;?></th>
<td><?php echo zget($categories, $product->category);?></td>
<th><?php echo $lang->product->line;?></th>
<td><?php echo zget($lines, $product->line);?></td>
</tr>
<tr>
<th><?php echo $lang->product->PO;?></th>
+1 -1
View File
@@ -6,7 +6,7 @@ $config->project->maxBurnDay = '31';
$config->project->weekend = '2';
$config->project->list = new stdclass();
$config->project->list->exportFields = 'id,name,code,PM,end,status,totalEstimate,totalConsumed,totalLeft,progess';
$config->project->list->exportFields = 'id,name,code,PM,end,status,totalEstimate,totalConsumed,totalLeft,progress';
global $lang, $app;
$app->loadLang('task');
+6 -12
View File
@@ -530,7 +530,7 @@ class project extends control
* @access public
* @return void
*/
public function story($projectID = 0, $orderBy = 'order', $type = 'byModule', $param = 0, $recTotal = 0, $recPerPage = 50, $pageID = 1)
public function story($projectID = 0, $orderBy = 'order_desc', $type = 'byModule', $param = 0, $recTotal = 0, $recPerPage = 50, $pageID = 1)
{
/* Load these models. */
$this->loadModel('story');
@@ -1254,7 +1254,7 @@ class project extends control
* @access public
* @return void
*/
public function kanban($projectID, $type = 'story', $orderBy = 'pri_asc')
public function kanban($projectID, $type = 'story', $orderBy = 'order_asc')
{
/* Save to session. */
$uri = $this->app->getURI(true);
@@ -2011,17 +2011,11 @@ class project extends control
$idList = explode(',', trim($this->post->storys, ','));
$orderBy = $this->post->orderBy;
$stories = $this->dao->select('story,`order`')->from(TABLE_PROJECTSTORY)->alias('t1')
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story=t2.id')
->where('t1.story')->in($idList)
->andWhere('t1.project')->eq($projectID)
->orderBy($orderBy)
->fetchPairs('order', 'story');
foreach($stories as $order => $id)
$order = $this->dao->select('*')->from(TABLE_PROJECTSTORY)->where('story')->in($idList)->andWhere('project')->eq($projectID)->orderBy('order_asc')->fetch('order');
foreach($idList as $storyID)
{
$newID = array_shift($idList);
if($id == $newID) continue;
$this->dao->update(TABLE_PROJECTSTORY)->set('`order`')->eq($order)->where('story')->eq($newID)->andWhere('project')->eq($projectID)->exec();
$this->dao->update(TABLE_PROJECTSTORY)->set('`order`')->eq($order)->where('story')->eq($storyID)->andWhere('project')->eq($projectID)->exec();
$order++;
}
}
+3
View File
@@ -86,6 +86,9 @@ table th.col-closed {width:14%}
.board-story.stage-tested.inverse {background-color:#827717;}
.board-story.stage-released.inverse {background-color:#9C27B0;}
.board-assignedTo {color:#D2322D; background-color: #FFEBEE;}
.board-finishedBy {color:#229F24; background-color: #E8F5E9;}
.bug-pri,.task-pri {display: inline-block; width: 16px; height: 16px; text-align: center; border-radius: 8px; border: 1px solid #ddd; font-size: 12px; line-height: 14px;}
.affix {position:fixed; top:0px; width:95%;z-index:1030;}
+6 -7
View File
@@ -12,7 +12,6 @@
#kanbanWrapper tbody td {vertical-align: top; padding: 6px}
#kanbanWrapper tbody th {background: #f1f1f1}
#kanbanWrapper .board-shadow {height: 0; opacity: 0; transition: opacity 0.2s;}
#kanbanWrapper tbody tr.dragging td.col-droppable {background: #fff4e5}
#kanbanWrapper tbody tr.dragging td.col-droppable.drop-to {background: #ffeacc}
#kanbanWrapper tbody tr.dragging td.col-droppable.drop-to .board-story + .board-shadow {margin-top: 6px;}
#kanbanWrapper tbody tr.dragging td.col-droppable.drop-to .board-shadow {height: 28px; background: #999; background: rgba(0,0,0,0.35); opacity: 1;}
@@ -56,12 +55,12 @@
.story-pri.pri-4 {background-color:#795523;}
.board-story {color: #dd7503; background-color: #FFF3E0;}
.board-story.stage-projected {color:#777;}
.board-story.stage-developing {color:#D2322D; background-color: #FFEBEE;}
.board-story.stage-developed {color:#229F24; background-color: #E8F5E9;}
.board-story.stage-testing {color:#EF6C00; background-color: #FFF3E0;}
.board-story.stage-tested {color:#827717; background-color: #F9FBE7}
.board-story.stage-released {color:#9C27B0; background-color: #F3E5F5}
.board-story.board-story-projected {color:#777;}
.board-story.board-story-developing {color:#D2322D; background-color: #FFEBEE;}
.board-story.board-story-developed {color:#229F24; background-color: #E8F5E9;}
.board-story.board-story-testing {color:#EF6C00; background-color: #FFF3E0;}
.board-story.board-story-tested {color:#827717; background-color: #F9FBE7}
.board-story.board-story-released {color:#9C27B0; background-color: #F3E5F5}
.affix {position:fixed; top:0px; width:95%;z-index:1030;}
#kanbanHeader.affix {box-shadow: 0 3px 10px rgba(0,0,0,.1);}
+8 -1
View File
@@ -6,7 +6,14 @@ $(function()
{
var list = '';
for(i = 0; i < data.list.length; i++) list += $(data.list[i]).attr('data-id') + ',';
$.post(createLink('project', 'storySort', 'projectID=' + projectID), {'storys' : list, 'orderBy' : orderBy});
$.post(createLink('project', 'storySort', 'projectID=' + projectID), {'storys' : list, 'orderBy' : orderBy}, function()
{
var $target = $(data.element[0]);
$target.hide();
$target.fadeIn(1000);
order = 'order_asc'
history.pushState({}, 0, createLink('project', 'story', "projectID=" + projectID + '&orderBy=' + order));
});
});
fixedTfootAction('#projectStoryForm');
+3 -3
View File
@@ -38,7 +38,7 @@ $lang->project->totalEstimate = 'Est.';
$lang->project->totalConsumed = 'Consumed';
$lang->project->totalLeft = 'Total Remained';
$lang->project->Left = 'Remained';
$lang->project->progess = 'Progess';
$lang->project->progress = 'Progress';
$lang->project->hours = 'Estimate %s, Consumed %s, Remained %s';
$lang->project->viewBug = 'Bugs';
$lang->project->noProduct = "No {$lang->productCommon}";
@@ -238,10 +238,10 @@ $lang->project->placeholder->totalLeft = 'Total man-hour remained when start Pro
$lang->project->selectGroup = new stdclass();
$lang->project->selectGroup->done = '(Done)';
$lang->project->orderList['order_asc'] = "Order Asc";
$lang->project->orderList['order_desc'] = "Order Desc";
$lang->project->orderList['pri_asc'] = "Priority Asc";
$lang->project->orderList['pri_desc'] = "Priority Desc";
$lang->project->orderList['id_asc'] = "ID Asc";
$lang->project->orderList['id_desc'] = "ID Desc";
$lang->project->orderList['stage_asc'] = "Stage Asc";
$lang->project->orderList['stage_desc'] = "Stage Desc";
+3 -3
View File
@@ -38,7 +38,7 @@ $lang->project->totalEstimate = '总预计';
$lang->project->totalConsumed = '总消耗';
$lang->project->totalLeft = '总剩余';
$lang->project->Left = '剩余';
$lang->project->progess = '进度';
$lang->project->progress = '进度';
$lang->project->hours = '预计 %s 消耗 %s 剩余 %s';
$lang->project->viewBug = '查看bug';
$lang->project->noProduct = "无{$lang->productCommon}{$lang->projectCommon}";
@@ -238,10 +238,10 @@ $lang->project->placeholder->totalLeft = '项目开始时的总预计工时';
$lang->project->selectGroup = new stdclass();
$lang->project->selectGroup->done = '(已结束)';
$lang->project->orderList['order_asc'] = "需求排序正序";
$lang->project->orderList['order_desc'] = "需求排序倒序";
$lang->project->orderList['pri_asc'] = "需求优先级正序";
$lang->project->orderList['pri_desc'] = "需求优先级倒序";
$lang->project->orderList['id_asc'] = "需求ID正序";
$lang->project->orderList['id_desc'] = "需求ID倒序";
$lang->project->orderList['stage_asc'] = "需求阶段正序";
$lang->project->orderList['stage_desc'] = "需求阶段倒序";
+1 -1
View File
@@ -38,7 +38,7 @@ $lang->project->totalEstimate = '總預計';
$lang->project->totalConsumed = '總消耗';
$lang->project->totalLeft = '總剩餘';
$lang->project->Left = '剩餘';
$lang->project->progess = '進度';
$lang->project->progress = '進度';
$lang->project->hours = '預計 %s 消耗 %s 剩餘 %s';
$lang->project->viewBug = '查看bug';
$lang->project->noProduct = "無{$lang->productCommon}{$lang->projectCommon}";
+1
View File
@@ -2314,6 +2314,7 @@ class projectModel extends model
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id')
->where('t1.project')->eq((int)$projectID)
->andWhere('t2.deleted')->eq(0)
->orderBy('t1.`order`_desc')
->fetchAll();
$storyGroups = array();
foreach($stories as $story) $storyGroups[$story->product][$story->module][$story->id] = $story;
+16 -14
View File
@@ -26,22 +26,22 @@
<table class='table table-form'>
<tr>
<th class='w-80px text-right'><?php echo $lang->project->beginAndEnd;?></th>
<td class='w-200px'><?php echo $project->begin . ' ~ ' . $project->end;?></td>
<td class='w-250px'>
<div id='sourceTimeBox'>
<span style='display:inline-block; padding:5px 10px; width:85px'><?php echo $project->begin?></span>
<span style='padding:5px 10px'> ~ </span>
<span style='display:inline-block; padding:5px 10px; width:85px'><?php echo $project->end;?></span>
</div>
<div id='readjustTimeBox' class='hide'>
<span style='display:inline-block; width:85px'><?php echo html::input('begin', $newBegin, "class='form-control form-date'")?></span>
<span style='padding:5px 10px;'> ~ </span>
<span style='display:inline-block; width:85px'><?php echo html::input('end', $newEnd, "class='form-control form-date'");?></span>
</div>
</td>
</td>
<td>
<label class="checkbox-inline"><input name="readjustTime" value="1" id="readjustTime" type="checkbox"> <strong><?php echo $lang->project->readjustTime?></strong></label>
</td>
</tr>
<tr id='readjustTimeBox' class='hide'>
<th></th>
<td colspan='2'>
<div class='input-group'>
<?php echo html::input('begin', $newBegin, "class='form-control form-date'")?>
<span class='input-group-addon'> ~ </span>
<?php echo html::input('end', $newEnd, "class='form-control form-date'")?>
<span class='input-group-addon'>
<label class="checkbox-inline"><input name="readjustTask" value="1" id="readjustTask" type="checkbox"> <strong><?php echo $lang->project->readjustTask?></strong></label>
</span>
</div>
<span id='readjustTaskBox' class='hide'><label class="checkbox-inline"><input name="readjustTask" value="1" id="readjustTask" type="checkbox"> <strong><?php echo $lang->project->readjustTask?></strong></label></span>
</td>
</tr>
<tr>
@@ -61,7 +61,9 @@ $(function()
{
$('#readjustTime').change(function()
{
$('#sourceTimeBox').toggle(!$(this).prop('checked'))
$('#readjustTimeBox').toggle($(this).prop('checked'))
$('#readjustTaskBox').toggle($(this).prop('checked'))
})
})
</script>
+1 -1
View File
@@ -42,7 +42,7 @@
<th class='w-70px'><?php echo $lang->project->totalEstimate;?></th>
<th class='w-70px'><?php echo $lang->project->totalConsumed;?></th>
<th class='w-70px'><?php echo $lang->project->totalLeft;?></th>
<th class='w-150px'><?php echo $lang->project->progess;?></th>
<th class='w-150px'><?php echo $lang->project->progress;?></th>
<th class='w-100px'><?php echo $lang->project->burn;?></th>
<?php if($canOrder):?>
<th class='w-60px sort-default'><?php common::printOrderLink('order', $orderBy, $vars, $lang->project->updateOrder);?></th>
+1 -1
View File
@@ -117,7 +117,7 @@
<div class='input-group'>
<?php echo html::select("products[$i]", $allProducts, $product->id, "class='form-control chosen' onchange='loadBranches(this)'");?>
<span class='input-group-addon fix-border' style='padding:0px'></span>
<?php if($product->type != 'normal') echo html::select("branch[$i]", $branchGroups[$product->id], $product->branch, "class='form-control' style='width:80px'")?>
<?php if($product->type != 'normal' and isset($branchGroups[$product->id])) echo html::select("branch[$i]", $branchGroups[$product->id], $product->branch, "class='form-control' style='width:80px'")?>
</div>
</div>
<?php $i++;?>
+13 -8
View File
@@ -27,18 +27,23 @@ $account = $this->app->user->account
<?php $hasGroupCol = (($type == 'story' and count($stories) > 0) or $type != 'story');?>
<?php if($hasGroupCol):?>
<th class='w-p15 col-story'>
<?php if($type == 'story'):?>
<div class='dropdown inline-block'>
<a data-toggle='dropdown' href='javascript:;'><?php echo $lang->project->orderList[$orderBy]?> <span class='icon-caret-down'></span> </a>
<a data-toggle='dropdown' href='javascript:;'>
<?php if($type == 'story'):?>
<?php echo $lang->project->orderList[$orderBy]?>
<?php else:?>
<?php echo $lang->task->$type;?>
<?php endif;?>
<span class='icon-caret-down'></span>
</a>
<ul class='dropdown-menu text-left'>
<?php foreach ($lang->project->orderList as $key => $value):?>
<li <?php echo $orderBy == $key ? " class='active'" : '' ?>><?php echo html::a($this->createLink('project', 'kanban', "projectID=$projectID&type=story&orderBy=$key"), $value);?></li>
<?php endforeach;?>
<?php foreach ($lang->project->orderList as $key => $value):?>
<li <?php echo ($type == 'story' and $orderBy == $key) ? " class='active'" : '' ?>><?php echo html::a($this->createLink('project', 'kanban', "projectID=$projectID&type=story&orderBy=$key"), $value);?></li>
<?php endforeach;?>
<?php echo "<li" . ($type == 'assignedTo' ? " class='active'" : '') . ">" . html::a(inlink('kanban', "project=$projectID&type=assignedTo"), $lang->project->groups['assignedTo']) . "</li>";?>
<?php echo "<li" . ($type == 'finishedBy' ? " class='active'" : '') . ">" . html::a(inlink('kanban', "project=$projectID&type=finishedBy"), $lang->project->groups['finishedBy']) . "</li>";?>
</ul>
</div>
<?php else:?>
<?php echo $lang->task->$type;?>
<?php endif;?>
</th>
<?php endif;?>
<?php $endCol = array_pop($taskCols);?>
+11 -9
View File
@@ -16,12 +16,14 @@
<?php js::set('moduleID', ($type == 'byModule' ? $param : 0));?>
<?php js::set('productID', ($type == 'byProduct' ? $param : 0));?>
<?php js::set('confirmUnlinkStory', $lang->project->confirmUnlinkStory)?>
<div id='titlebar'>
<div class='heading'><?php echo html::icon($lang->icons['story']);?> <?php echo $lang->project->story;?></div>
<div id='featurebar'>
<ul class='nav'>
<li class='active'><?php if(common::hasPriv('project', 'story')) echo html::a($this->createLink('project', 'story', "project=$project->id"), $lang->project->story);?></li>
<li><?php if(common::hasPriv('project', 'storykanban')) echo html::a($this->createLink('project', 'storykanban', "project=$project->id"), $lang->project->kanban);?></li>
</ul>
<div class='actions'>
<div class='btn-group'>
<?php
common::printIcon('project', 'storyKanban', "project=$project->id", '', 'button', 'columns', '', '', '', '', $lang->project->kanban);
common::printIcon('story', 'export', "productID=$productID&orderBy=id_desc", '', 'button', '', '', 'export');
$this->lang->story->create = $this->lang->project->createStory;
@@ -62,6 +64,9 @@
<tr class='colhead'>
<?php $vars = "projectID={$project->id}&orderBy=%s&type=$type&param=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}"; ?>
<th class='w-id {sorter:false}'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<?php if($canOrder):?>
<th class='w-50px {sorter:false}'> <?php common::printOrderLink('order', $orderBy, $vars, $lang->project->updateOrder);?></th>
<?php endif;?>
<th class='w-pri {sorter:false}'> <?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='{sorter:false}'> <?php common::printOrderLink('title', $orderBy, $vars, $lang->story->title);?></th>
<th class='w-user {sorter:false}'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
@@ -73,9 +78,6 @@
<th title='<?php echo $lang->story->bugCount?>' class='w-30px'><?php echo $lang->story->bugCountAB;?></th>
<th title='<?php echo $lang->story->caseCount?>' class='w-30px'><?php echo $lang->story->caseCountAB;?></th>
<th class='w-110px {sorter:false}'> <?php echo $lang->actions;?></th>
<?php if($canOrder):?>
<th class='w-50px {sorter:false}'> <?php common::printOrderLink('order', $orderBy, $vars, $lang->project->updateOrder);?></th>
<?php endif;?>
</tr>
</thead>
<tbody id='storyTableList' class='sortable'>
@@ -96,6 +98,9 @@
<?php endif;?>
<?php echo html::a($storyLink, sprintf('%03d', $story->id));?>
</td>
<?php if($canOrder):?>
<td class='sort-handler'><i class='icon-move'></i></td>
<?php endif;?>
<td><span class='<?php echo 'pri' . zget($lang->story->priList, $story->pri, $story->pri)?>'><?php echo zget($lang->story->priList, $story->pri, $story->pri);?></span></td>
<td class='text-left' title="<?php echo $story->title?>">
<?php if(isset($branchGroups[$story->product][$story->branch])) echo "<span class='label label-info label-badge'>" . $branchGroups[$story->product][$story->branch] . '</span>';?>
@@ -152,9 +157,6 @@
}
?>
</td>
<?php if($canOrder):?>
<td class='sort-handler'><i class='icon-move'></i></td>
<?php endif;?>
</tr>
<?php endforeach;?>
</tbody>
+9 -10
View File
@@ -10,12 +10,14 @@
?>
<?php include '../../common/view/header.html.php';?>
<?php js::set('confirmUnlinkStory', $lang->project->confirmUnlinkStory)?>
<div id='titlebar'>
<div class='heading'><?php echo html::icon($lang->icons['story']);?> <?php echo $lang->project->story;?></div>
<div id='featurebar'>
<ul class='nav'>
<li><?php if(common::hasPriv('project', 'story')) echo html::a($this->createLink('project', 'story', "project=$project->id"), $lang->project->story);?></li>
<li class='active'><?php if(common::hasPriv('project', 'storykanban')) echo html::a($this->createLink('project', 'storykanban', "project=$project->id"), $lang->project->kanban);?></li>
</ul>
<div class='actions'>
<div class='btn-group'>
<?php
common::printIcon('project', 'story', "project=$project->id", '', 'button', 'list', '', '', '', '', $lang->project->story);
common::printIcon('story', 'export', "productID=$productID&orderBy=id_desc", '', 'button', '', '', 'export');
$this->lang->story->create = $this->lang->project->createStory;
@@ -43,15 +45,12 @@ $account = $this->app->user->account
<table class='boards-layout table' id='kanbanHeader'>
<thead>
<tr>
<?php $endCol = array_pop($cols);?>
<?php foreach ($cols as $col):?>
<th class='col-<?php echo $col?>'><?php echo $lang->story->stageList[$col];?></th>
<?php endforeach;?>
<th class='col-<?php echo $endCol?>'><?php echo $lang->story->stageList[$endCol];?></th>
</tr>
</thead>
</table>
<?php $cols[] = $endCol;?>
<table class='boards-layout table active-disabled table-bordered' id='kanbanWrapper'>
<thead>
<tr>
@@ -64,7 +63,7 @@ $account = $this->app->user->account
<td class='col-droppable col-<?php echo $col?>' data-id='<?php echo $col?>'>
<?php if(!empty($stories[$col])):?>
<?php foreach($stories[$col] as $story):?>
<div class='board board-story board-story-<?php echo $col ?>;?>' data-id='<?php echo $story->id?>' id='task-<?php echo $story->id?>'>
<div class='board board-story board-story-<?php echo $col; ?>' data-id='<?php echo $story->id?>' id='story-<?php echo $story->id?>'>
<div class='board-title'>
<?php echo html::a($this->createLink('story', 'view', "story=$story->id", '', true), $story->title, '', 'class="kanbanFrame" title="' . $story->title . '"');?>
<div class='board-actions'>
@@ -80,10 +79,10 @@ $account = $this->app->user->account
</div>
</div>
<div class='board-footer clearfix'>
<span class='task-id board-id' title='<?php echo $lang->story->id?>'><?php echo $story->id?></span>
<span class='task-pri pri-<?php echo $story->pri?>' title='<?php echo $lang->story->pri?>'></span>
<span class='story-id board-id' title='<?php echo $lang->story->id?>'><?php echo $story->id?></span>
<span class='story-pri pri-<?php echo $story->pri?>' title='<?php echo $lang->story->pri?>'></span>
<div class='pull-right'>
<span class='task-left' title='<?php echo $lang->story->status?>'><?php echo zget($this->lang->story->statusList, $story->status, '');?></span>
<span class='text-left' title='<?php echo $lang->story->status?>'><?php echo zget($this->lang->story->statusList, $story->status, '');?></span>
</div>
</div>
</div>
-211
View File
@@ -1,211 +0,0 @@
<?php
/**
* The task data view file of project module of ZenTaoPMS.
*
* @copyright Copyright 2009-2015 青岛易软天创网络科技有限公司(QingDao Nature Easy Soft Network Technology Co,LTD, www.cnezsoft.com)
* @license ZPL (http://zpl.pub/page/zplv12.html)
* @author Yidong Wang <yidong@cnezsoft.com>
* @package project
* @version $Id$
* @link http://www.zentao.net
*/
?>
<?php include '../../common/view/tablesorter.html.php';?>
<?php $columns = 12; ?>
<table class='table table-condensed table-hover table-striped tablesorter table-fixed table-selectable' id='taskList'>
<thead>
<tr>
<th class='w-id {sorter:false}'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th class='w-pri {sorter:false}'> <?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='{sorter:false}'> <?php common::printOrderLink('name', $orderBy, $vars, $lang->task->name);?></th>
<th class='w-100px {sorter:false}'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='w-70px {sorter:false}'> <?php common::printOrderLink('deadline', $orderBy, $vars, $lang->task->deadlineAB);?></th>
<?php if($this->cookie->windowWidth > $this->config->wideSize):?>
<?php $columns++; ?>
<th class='w-id {sorter:false}'> <?php common::printOrderLink('openedDate', $orderBy, $vars, $lang->task->openedDateAB);?></th>
<?php endif;?>
<th class='w-user {sorter:false}'> <?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->task->assignedToAB);?></th>
<th class='w-user {sorter:false}'> <?php common::printOrderLink('finishedBy', $orderBy, $vars, $lang->task->finishedByAB);?></th>
<?php if($this->cookie->windowWidth > $this->config->wideSize):?>
<?php $columns++; ?>
<th class='w-50px {sorter:false}'> <?php common::printOrderLink('finishedDate', $orderBy, $vars, $lang->task->finishedDateAB);?></th>
<?php endif;?>
<th class='w-35px {sorter:false}'> <?php common::printOrderLink('estimate', $orderBy, $vars, $lang->task->estimateAB);?></th>
<th class='w-50px {sorter:false}'> <?php common::printOrderLink('consumed', $orderBy, $vars, $lang->task->consumedAB);?></th>
<th class='w-40px nobr {sorter:false}'> <?php common::printOrderLink('left', $orderBy, $vars, $lang->task->leftAB);?></th>
<th class='w-50px' title='<?php echo $lang->task->progessTips?>'><?php echo $lang->task->progess;?></th>
<?php if($project->type == 'sprint'): ?>
<th class='w-100px {sorter:false}'><?php common::printOrderLink('story', $orderBy, $vars, $lang->task->story); ?></th>
<?php $columns++; ?>
<?php endif;?>
<th class='w-170px {sorter:false}'><?php echo $lang->actions;?></th>
</tr>
</thead>
<?php if($tasks):?>
<tbody>
<?php foreach($tasks as $task):?>
<?php $class = $task->assignedTo == $app->user->account ? 'style=color:red' : ''; ?>
<tr class='text-center'>
<td class='cell-id'>
<input type='checkbox' name='taskIDList[<?php echo $task->id;?>]' value='<?php echo $task->id;?>'/>
<?php if(!common::printLink('task', 'view', "task=$task->id", sprintf('%03d', $task->id))) printf('%03d', $task->id);?>
</td>
<td><span class='<?php echo 'pri' . zget($lang->task->priList, $task->pri, $task->pri)?>'><?php echo $task->pri == '0' ? '' : zget($lang->task->priList, $task->pri, $task->pri);?></span></td>
<td class='text-left' title="<?php echo $task->name?>">
<?php if(isset($branchGroups[$task->product][$task->branch])) echo "<span title='{$lang->product->branchName[$task->productType]}' class='label label-branch label-badge'>" . $branchGroups[$task->product][$task->branch] . '</span>';?>
<?php if($modulePairs and $task->module) echo "<span title='{$lang->task->module}' class='label label-info label-badge'>" . $modulePairs[$task->module] . '</span>';?>
<?php
if(!common::printLink('task', 'view', "task=$task->id", $task->name, null, "style='color: $task->color'")) echo $task->name;
if($task->fromBug) echo html::a($this->createLink('bug', 'view', "id=$task->fromBug"), "[BUG#$task->fromBug]", '_blank', "class='bug'");
?>
</td>
<td class="<?php echo $task->status;?>">
<?php
$storyChanged = ($task->storyStatus == 'active' and $task->latestStoryVersion > $task->storyVersion);
if($storyChanged)
{
echo "(<span class='warning'>{$lang->story->changed}</span> ";
echo html::a($this->createLink('task', 'confirmStoryChange', "taskID=$task->id"), $lang->confirm, 'hiddenwin');
echo ")";
}
else
{
echo $lang->task->statusList[$task->status];
}
?>
</td>
<td class="<?php if(isset($task->delay)) echo 'delayed';?>"><?php if(substr($task->deadline, 0, 4) > 0) echo substr($task->deadline, 5, 6);?></td>
<?php if($this->cookie->windowWidth > $this->config->wideSize):?>
<td><?php echo substr($task->openedDate, 5, 6);?></td>
<?php endif;?>
<td <?php echo $class;?>><?php echo $task->assignedTo == 'closed' ? 'Closed' : zget($users, $task->assignedTo, $task->assignedTo);?></td>
<td><?php echo zget($users, $task->finishedBy, $task->finishedBy);?></td>
<?php if($this->cookie->windowWidth > $this->config->wideSize):?>
<td><?php echo substr($task->finishedDate, 5, 6);?></td>
<?php endif;?>
<td><?php echo $task->estimate;?></td>
<td><?php echo $task->consumed;?></td>
<td><?php echo $task->left;?></td>
<td><?php echo $task->progess?>%</td>
<?php
if($project->type == 'sprint')
{
echo '<td class="text-left" title="' . $task->storyTitle . '">';
if($task->storyID)
{
if(!common::printLink('story', 'view', "storyid=$task->storyID", $task->storyTitle)) print $task->storyTitle;
}
echo '</td>';
}
?>
<td class='text-right'>
<?php
common::printIcon('task', 'assignTo', "projectID=$task->project&taskID=$task->id", $task, 'list', '', '', 'iframe', true);
common::printIcon('task', 'start', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
common::printIcon('task', 'recordEstimate', "taskID=$task->id", $task, 'list', 'time', '', 'iframe', true);
if($browseType == 'needconfirm')
{
$lang->task->confirmStoryChange = $lang->confirm;
common::printIcon('task', 'confirmStoryChange', "taskid=$task->id", '', 'list', '', 'hiddenwin');
}
common::printIcon('task', 'finish', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
common::printIcon('task', 'close', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
common::printIcon('task', 'edit', "taskID=$task->id", $task, 'list');
common::printIcon('task', 'batchCreate', "project=$projectID&storyID=&moduleID=$moduleID&taskID=$task->id", $task, 'list','plus','','','','',$lang->task->children);
?>
</td>
</tr>
<?php if($task->children):?>
<?php foreach($task->children as $child):?>
<?php $class = $child->assignedTo == $app->user->account ? 'style=color:red' : ''; ?>
<tr class='text-center table-children parent-<?php echo $task->id;?>'>
<td class='cell-id'>
<input type='checkbox' name='taskIDList[<?php echo $child->id;?>]' value='<?php echo $child->id;?>'/>
<?php if(!common::printLink('task', 'view', "task=$child->id", sprintf('%03d', $child->id))) printf('%03d', $child->id);?>
</td>
<td><span class='<?php echo 'pri' . zget($lang->task->priList, $child->pri, $child->pri)?>'><?php echo $child->pri == '0' ? '' : zget($lang->task->priList, $child->pri, $child->pri);?></span></td>
<td class='text-left' title="<?php echo $child->name?>">
<?php if(isset($branchGroups[$child->product][$child->branch])) echo "<span title='{$lang->product->branchName[$child->productType]}' class='label label-branch label-badge'>" . $branchGroups[$child->product][$child->branch] . '</span>';?>
<?php if($modulePairs and $child->module) echo "<span title='{$lang->task->module}' class='label label-info label-badge'>" . $modulePairs[$child->module] . '</span>';?>
<?php
if(!common::printLink('task', 'view', "task=$child->id", $child->name, null, "style='color: $child->color'")) echo $child->name;
if($child->fromBug) echo html::a($this->createLink('bug', 'view', "id=$child->fromBug"), "[BUG#$child->fromBug]", '_blank', "class='bug'");
?>
</td>
<td class="<?php echo $child->status;?>">
<?php
$storyChanged = ($child->storyStatus == 'active' and $child->latestStoryVersion > $child->storyVersion);
if($storyChanged)
{
echo "(<span class='warning'>{$lang->story->changed}</span> ";
echo html::a($this->createLink('task', 'confirmStoryChange', "taskID=$child->id"), $lang->confirm, 'hiddenwin');
echo ")";
}
else
{
echo $lang->task->statusList[$child->status];
}
?>
</td>
<td class="<?php if(isset($child->delay)) echo 'delayed';?>"><?php if(substr($child->deadline, 0, 4) > 0) echo substr($child->deadline, 5, 6);?></td>
<?php if($this->cookie->windowWidth > $this->config->wideSize):?>
<td><?php echo substr($child->openedDate, 5, 6);?></td>
<?php endif;?>
<td <?php echo $class;?>><?php echo $child->assignedTo == 'closed' ? 'Closed' : zget($users, $child->assignedTo, $child->assignedTo);?></td>
<td><?php echo zget($users, $child->finishedBy, $child->finishedBy);?></td>
<?php if($this->cookie->windowWidth > $this->config->wideSize):?>
<td><?php echo substr($child->finishedDate, 5, 6);?></td>
<?php endif;?>
<td><?php echo $child->estimate;?></td>
<td><?php echo $child->consumed;?></td>
<td><?php echo $child->left;?></td>
<td><?php echo $child->progess?>%</td>
<?php
if($project->type == 'sprint')
{
echo '<td class="text-left" title="' . $child->storyTitle . '">';
if($child->storyID)
{
if(!common::printLink('story', 'view', "storyid=$child->storyID", $child->storyTitle)) print $child->storyTitle;
}
echo '</td>';
}
?>
<td class='text-right'>
<?php
common::printIcon('task', 'assignTo', "projectID=$child->project&taskID=$child->id", $child, 'list', '', '', 'iframe', true);
common::printIcon('task', 'start', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
common::printIcon('task', 'recordEstimate', "taskID=$child->id", $child, 'list', 'time', '', 'iframe', true);
if($browseType == 'needconfirm')
{
$lang->task->confirmStoryChange = $lang->confirm;
common::printIcon('task', 'confirmStoryChange', "taskid=$child->id", '', 'list', '', 'hiddenwin');
}
common::printIcon('task', 'finish', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
common::printIcon('task', 'close', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
common::printIcon('task', 'edit', "taskID=$child->id", $child, 'list');
common::printIcon('task', 'batchCreate', "", $child, 'list','plus','','','','',$lang->task->children);
?>
</td>
</tr>
<?php endforeach;?>
<?php endif;?>
<?php endforeach;?>
</tbody>
<?php endif?>
+3 -1
View File
@@ -938,9 +938,11 @@ class story extends control
$storyIDList = array_unique($storyIDList);
$allChanges = $this->story->batchChangeStage($storyIDList, $stage);
if(dao::isError()) die(js::error(dao::getError()));
$action = $stage == 'verified' ? 'Verified' : 'Edited';
foreach($allChanges as $storyID => $changes)
{
$actionID = $this->action->create('story', $storyID, 'Edited');
$actionID = $this->action->create('story', $storyID, $action);
$this->action->logHistory($actionID, $changes);
$this->story->sendmail($storyID, $actionID);
}
+6 -2
View File
@@ -40,7 +40,7 @@ class storyModel extends model
$story->projects = $this->dao->select('t1.project, t2.name, t2.status')->from(TABLE_PROJECTSTORY)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
->where('t1.story')->eq($storyID)
->orderBy('t1.project DESC')
->orderBy('t1.`order` DESC')
->fetchAll('project');
$story->tasks = $this->dao->select('id, name, assignedTo, project, status, consumed, `left`')->from(TABLE_TASK)->where('story')->eq($storyID)->andWhere('deleted')->eq(0)->orderBy('id DESC')->fetchGroup('project');
$story->stages = $this->dao->select('*')->from(TABLE_STORYSTAGE)->where('story')->eq($storyID)->fetchPairs('branch', 'stage');
@@ -978,6 +978,9 @@ class storyModel extends model
$story->lastEditedDate = $now;
$story->stage = $stage;
/* When stage is verified then only change to released. */
if($oldStory->stage == 'verified' and $stage->stage != 'released') $stage->stage = 'verified';
$this->dao->update(TABLE_STORY)->data($story)->autoCheck()->where('id')->eq((int)$storyID)->exec();
if(!dao::isError()) $allChanges[$storyID] = common::createChanges($oldStory, $story);
}
@@ -1576,7 +1579,7 @@ class storyModel extends model
* @access public
* @return array
*/
public function getProjectStories($projectID = 0, $orderBy = 'pri_asc,id_desc', $type = 'byModule', $param = 0, $pager = null)
public function getProjectStories($projectID = 0, $orderBy = 't1.`order`_desc', $type = 'byModule', $param = 0, $pager = null)
{
if(defined('TUTORIAL')) return $this->loadModel('tutorial')->getProjectStories();
@@ -1669,6 +1672,7 @@ class storyModel extends model
->beginIF($productID)->andWhere('t2.product')->eq((int)$productID)->fi()
->beginIF($branch)->andWhere('t2.branch')->in("0,$branch")->fi()
->beginIF($moduleIdList)->andWhere('t2.module')->in($moduleIdList)->fi()
->orderBy('t1.`order` desc')
->fetchAll();
if(!$stories) return array();
return $this->formatStories($stories, $type);
+1 -1
View File
@@ -58,7 +58,7 @@ if($config->global->flow == 'onlyTask')
}
$config->task->datatable = new stdclass();
$config->task->datatable->defaultField = array('id', 'pri', 'name', 'status', 'deadline', 'openedDate', 'assignedTo', 'finishedBy', 'estimate', 'consumed', 'left', 'story', 'actions');
$config->task->datatable->defaultField = array('id', 'pri', 'name', 'status', 'deadline', 'openedDate', 'assignedTo', 'finishedBy', 'estimate', 'consumed', 'left', 'actions');
$config->task->datatable->fieldList['id']['title'] = 'idAB';
$config->task->datatable->fieldList['id']['fixed'] = 'left';
+2
View File
@@ -150,6 +150,8 @@ class taskModel extends model
foreach($tasks->story as $key => $storyID)
{
if(empty($tasks->name[$key])) continue;
if($tasks->type[$key] == 'affair') continue;
if($tasks->type[$key] == 'ditto' && isset($tasks->type[$key - 1]) && $tasks->type[$key - 1] == 'affair') continue;
$inNames = in_array($tasks->name[$key], $taskNames);
if(!$inNames || $inNames && !in_array($storyID, $storyIDs))
+3 -3
View File
@@ -64,8 +64,8 @@ $lang->testreport->fromCaseBugTip= "Bug created after failure of use case in tes
$lang->testreport->errorTrunk = "The trunk version cannot create a test report. Please modify the associated version!";
$lang->testreport->bugSummary = <<<EOD
<strong>%s</strong> Bug(s) generated in total <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->foundBugTip}'><i class='icon-warning-sign'></i></a>,
<strong>%s</strong> Bug(s) remained unresolve <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->legacyBugTip}'><i class='icon-warning-sign'></i></a>,
<strong>%s</strong> Bug(s) failure of case <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->fromCaseBugTip}'><i class='icon-warning-sign'></i></a>.
<strong>%s</strong> Bug(s) generated in total <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->foundBugTip}'><i class='icon-info-sign'></i></a>,
<strong>%s</strong> Bug(s) remained unresolve <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->legacyBugTip}'><i class='icon-info-sign'></i></a>,
<strong>%s</strong> Bug(s) failure of case <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->fromCaseBugTip}'><i class='icon-info-sign></i></a>.
Confirmed bug rate(bug resolution is resolved or delayedg status is resolved or closed): <strong>%s</strong>,Bug created in caserate(Bugs created in cases / Newly generated bugs): <strong>%s</strong>'
EOD;
+3 -3
View File
@@ -64,8 +64,8 @@ $lang->testreport->fromCaseBugTip= "测试时间范围内,用例执行失败
$lang->testreport->errorTrunk = "主干版本不能创建测试报告,请修改关联版本!";
$lang->testreport->bugSummary = <<<EOD
共发现<strong>%s</strong>个Bug <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->foundBugTip}'><i class='icon-warning-sign'></i></a>,
遗留<strong>%s</strong>个Bug <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->legacyBugTip}'><i class='icon-warning-sign'></i></a>。
用例执行产生<strong>%s</strong>个Bug <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->fromCaseBugTip}'><i class='icon-warning-sign'></i></a>。
共发现<strong>%s</strong>个Bug <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->foundBugTip}'><i class='icon-info-sign'></i></a>,
遗留<strong>%s</strong>个Bug <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->legacyBugTip}'><i class='icon-info-sign'></i></a>。
用例执行产生<strong>%s</strong>个Bug <a data-toggle='tooltip' class='text-warning' title='{$lang->testreport->fromCaseBugTip}'><i class='icon-info-sign'></i></a>。
有效Bug率(方案为已解决或延期 / 状态为已解决或已关闭):<strong>%s</strong>,用例发现Bug率(用例创建的Bug / 发现Bug数):<strong>%s</strong>
EOD;
+6 -6
View File
@@ -25,7 +25,7 @@ class tree extends control
public function browse($rootID, $viewType, $currentModuleID = 0, $branch = 0)
{
/* According to the type, set the module root and modules. */
if(strpos('story|bug|case|category', $viewType) !== false)
if(strpos('story|bug|case|line', $viewType) !== false)
{
$product = $this->loadModel('product')->getById($rootID);
if(!empty($product->type) && $product->type != 'normal')
@@ -122,10 +122,10 @@ class tree extends control
$position[] = html::a($this->createLink('doc', 'browse', "libID=$rootID"), $lib->name);
$position[] = $this->lang->tree->manageCustomDoc;
}
elseif($viewType == 'category')
elseif($viewType == 'line')
{
$this->lang->set('menugroup.tree', 'product');
$this->product->setMenu($this->product->getPairs(), $rootID, $branch, 'category', '', 'category');
$this->product->setMenu($this->product->getPairs(), $rootID, $branch, 'line', '', 'line');
$this->lang->tree->menu = $this->lang->product->menu;
$this->lang->tree->menuOrder = $this->lang->product->menuOrder;
@@ -135,10 +135,10 @@ class tree extends control
$this->view->allProduct = $products;
$this->view->currentProduct = $currentProduct;
$this->view->productModules = $this->tree->getOptionMenu($currentProduct, 'category');
$this->view->productModules = $this->tree->getOptionMenu($currentProduct, 'line');
$title = $this->lang->product->common . $this->lang->colon . $this->lang->tree->manageCategory;
$position[] = $this->lang->tree->manageCategory;
$title = $this->lang->product->common . $this->lang->colon . $this->lang->tree->manageLine;
$position[] = $this->lang->tree->manageLine;
}
$parentModules = $this->tree->getParents($currentModuleID);
+4
View File
@@ -19,6 +19,7 @@ $lang->tree->manage = 'Manage Module';
$lang->tree->fix = 'Fix';
$lang->tree->manageProduct = "Manage {$lang->productCommon}";
$lang->tree->manageProject = "Manage {$lang->projectCommon}";
$lang->tree->manageLine = 'Manage Product Line';
$lang->tree->manageBug = 'Manage Bug';
$lang->tree->manageCase = 'Manage Case';
$lang->tree->manageCaseLib = 'Manage Library';
@@ -26,6 +27,7 @@ $lang->tree->manageCustomDoc = 'Manage DocLib';
$lang->tree->updateOrder = 'Update Order';
$lang->tree->manageChild = 'Manage Child Module';
$lang->tree->manageStoryChild = 'Manage Child Story';
$lang->tree->manageLineChild = 'Manage Product Line';
$lang->tree->manageBugChild = 'Manage Child Bug';
$lang->tree->manageCaseChild = 'Manage Child Case';
$lang->tree->manageCaselibChild = 'Manage Child Library';
@@ -42,12 +44,14 @@ $lang->tree->successFixed = 'Fixed.';
$lang->tree->repeatName = 'The name "%s" has existed!';
$lang->tree->name = 'Name';
$lang->tree->line = 'Product Line';
$lang->tree->root = 'Root';
$lang->tree->branch = 'Platform/Branch';
$lang->tree->path = 'Path';
$lang->tree->type = 'Type';
$lang->tree->parent = 'Parent';
$lang->tree->child = 'Child';
$lang->tree->lineChild = 'Child';
$lang->tree->owner = 'Owner';
$lang->tree->order = 'Order';
$lang->tree->short = 'Sort';
+41 -41
View File
@@ -10,32 +10,32 @@
* @link http://www.zentao.net
*/
$lang->tree = new stdclass();
$lang->tree->common = '模块维护';
$lang->tree->edit = '编辑';
$lang->tree->delete = '删除模块';
$lang->tree->browse = '通用模块维护';
$lang->tree->browseTask = '任务模块维护';
$lang->tree->manage = '维护模块';
$lang->tree->fix = '修正数据';
$lang->tree->manageProduct = "维护{$lang->productCommon}视图模块";
$lang->tree->manageProject = "维护{$lang->projectCommon}视图模块";
$lang->tree->manageCategory = '维护目录';
$lang->tree->manageBug = '维护测试视图模块';
$lang->tree->manageCase = '维护用例视图模块';
$lang->tree->manageCaseLib = '维护测试库模块';
$lang->tree->manageCustomDoc = '维护文档库分类';
$lang->tree->updateOrder = '更新排序';
$lang->tree->manageChild = '维护子模块';
$lang->tree->manageStoryChild = '维护子模块';
$lang->tree->manageCategoryChild = '维护子目录';
$lang->tree->manageBugChild = '维护Bug子模块';
$lang->tree->manageCaseChild = '维护用例子模块';
$lang->tree->manageCaselibChild = '维护测试库子模块';
$lang->tree->manageTaskChild = "维护{$lang->projectCommon}子模块";
$lang->tree->syncFromProduct = '复制';
$lang->tree->dragAndSort = "拖放排序";
$lang->tree->sort = "排序";
$lang->tree->addChild = "增加子模块";
$lang->tree->common = '模块维护';
$lang->tree->edit = '编辑';
$lang->tree->delete = '删除模块';
$lang->tree->browse = '通用模块维护';
$lang->tree->browseTask = '任务模块维护';
$lang->tree->manage = '维护模块';
$lang->tree->fix = '修正数据';
$lang->tree->manageProduct = "维护{$lang->productCommon}视图模块";
$lang->tree->manageProject = "维护{$lang->projectCommon}视图模块";
$lang->tree->manageLine = '维护产品线';
$lang->tree->manageBug = '维护测试视图模块';
$lang->tree->manageCase = '维护用例视图模块';
$lang->tree->manageCaseLib = '维护测试库模块';
$lang->tree->manageCustomDoc = '维护文档库分类';
$lang->tree->updateOrder = '更新排序';
$lang->tree->manageChild = '维护子模块';
$lang->tree->manageStoryChild = '维护子模块';
$lang->tree->manageLineChild = '维护产品线';
$lang->tree->manageBugChild = '维护Bug子模块';
$lang->tree->manageCaseChild = '维护用例子模块';
$lang->tree->manageCaselibChild = '维护测试库子模块';
$lang->tree->manageTaskChild = "维护{$lang->projectCommon}子模块";
$lang->tree->syncFromProduct = '复制';
$lang->tree->dragAndSort = "拖放排序";
$lang->tree->sort = "排序";
$lang->tree->addChild = "增加子模块";
$lang->tree->confirmDelete = '该模块及其子模块都会被删除,您确定删除吗?';
$lang->tree->confirmRoot = "模块的所属{$lang->productCommon}修改,会关联修改该模块下的需求、Bug、用例的所属{$lang->productCommon},以及{$lang->projectCommon}和{$lang->productCommon}的关联关系。该操作比较危险,请谨慎操作。是否确认修改?";
@@ -43,18 +43,18 @@ $lang->tree->successSave = '成功保存';
$lang->tree->successFixed = '成功修正数据!';
$lang->tree->repeatName = '模块名“%s”已经存在!';
$lang->tree->name = '模块名称';
$lang->tree->category = '目录名称';
$lang->tree->root = '所属根';
$lang->tree->branch = '平台/分支';
$lang->tree->path = '路径';
$lang->tree->type = '类型';
$lang->tree->parent = '上级模块';
$lang->tree->child = '子模块';
$lang->tree->categoryChild = '子目录';
$lang->tree->owner = '负责人';
$lang->tree->order = '排序';
$lang->tree->short = '简称';
$lang->tree->all = '所有模块';
$lang->tree->projectDoc = "{$lang->projectCommon}文档";
$lang->tree->product = "所属{$lang->productCommon}";
$lang->tree->name = '模块名称';
$lang->tree->line = '产品线名称';
$lang->tree->root = '所属根';
$lang->tree->branch = '平台/分支';
$lang->tree->path = '路径';
$lang->tree->type = '类型';
$lang->tree->parent = '上级模块';
$lang->tree->child = '子模块';
$lang->tree->lineChild = '子产品线';
$lang->tree->owner = '负责人';
$lang->tree->order = '排序';
$lang->tree->short = '简称';
$lang->tree->all = '所有模块';
$lang->tree->projectDoc = "{$lang->projectCommon}文档";
$lang->tree->product = "所属{$lang->productCommon}";
+13 -8
View File
@@ -81,7 +81,7 @@ class treeModel extends model
*/
public function getOptionMenu($rootID, $type = 'story', $startModule = 0, $branch = 0)
{
if($type == 'category') $rootID = 0;
if($type == 'line') $rootID = 0;
$branches = array($branch => '');
if(strpos('story|bug|case', $type) !== false)
@@ -170,6 +170,11 @@ class treeModel extends model
return $modulePairs;
}
public function getLinePairs()
{
return $this->dao->select('id, name')->from(TABLE_MODULE)->where('type')->eq('line')->fetchPairs();
}
/**
* Create an option menu of task in html.
*
@@ -314,7 +319,7 @@ class treeModel extends model
*/
public function getTreeMenu($rootID, $type = 'root', $startModule = 0, $userFunc, $extra = '', $branch = 0)
{
if($type == 'category') $rootID = 0;
if($type == 'line') $rootID = 0;
$branches = array($branch => '');
if($branch)
@@ -763,7 +768,7 @@ class treeModel extends model
}
/**
* Create link of a product.
* Create link of a product line.
*
* @param string $type
* @param object $module
@@ -771,11 +776,11 @@ class treeModel extends model
* @access public
* @return string
*/
public function createCategoryLink($type, $module, $extra)
public function createLineLink($type, $module, $extra)
{
$productID = $extra['productID'];
$status = $extra['status'];
return html::a(helper::createLink('product', 'all', "productID={$productID}&category={$module->id}&status={$status}"), $module->name, '_self', "id='module{$module->id}'");
return html::a(helper::createLink('product', 'all', "productID={$productID}&line={$module->id}&status={$status}"), $module->name, '_self', "id='module{$module->id}'");
}
/**
@@ -959,7 +964,7 @@ class treeModel extends model
*/
public function getSons($rootID, $moduleID, $type = 'root', $branch = 0)
{
if($type == 'category') $rootID = 0;
if($type == 'line') $rootID = 0;
/* if createVersion <= 4.1 or type == 'story', only get modules of its type. */
if(!$this->isMergeModule($rootID, $type) or $type == 'story')
@@ -1205,7 +1210,7 @@ class treeModel extends model
*/
public function manageChild($rootID, $type, $parentModuleID, $childs)
{
if($type == 'category') $rootID = 0;
if($type == 'line') $rootID = 0;
$this->checkUnique($rootID, $type, $parentModuleID, $childs);
$parentModule = $this->getByID($parentModuleID);
@@ -1513,7 +1518,7 @@ class treeModel extends model
*/
public function getProductStructure($rootID, $viewType, $branch = 0, $currentModuleID = 0)
{
if($viewType == 'category') $rootID = 0;
if($viewType == 'line') $rootID = 0;
$branches = array($branch => '');
$product = $this->loadModel('product')->getById($rootID);
+8 -8
View File
@@ -13,9 +13,9 @@
<?php include '../../common/view/header.html.php';?>
<?php js::set('viewType', $viewType);?>
<?php $hasBranch = (strpos('story|bug|case', $viewType) !== false and (!empty($root->type) && $root->type != 'normal')) ? true : false;?>
<?php $name = $viewType == 'category' ? $lang->tree->category : $lang->tree->name;?>
<?php $name = $viewType == 'line' ? $lang->tree->line : $lang->tree->name;?>
<div id='featurebar'>
<div class='heading'><?php echo $viewType == 'category' ? $lang->tree->manageCategory : $lang->tree->common;?></div>
<div class='heading'><?php echo $viewType == 'line' ? $lang->tree->manageLine : $lang->tree->common;?></div>
</div>
<div class='row'>
<div class='col-sm-4'>
@@ -42,7 +42,7 @@
<div class='panel-body'>
<table class='table table-form'>
<tr>
<?php if($viewType != 'category'):?>
<?php if($viewType != 'line'):?>
<td class='parentModule'>
<nobr>
<?php
@@ -107,7 +107,7 @@
</td>
</tr>
<tr>
<?php if($viewType != 'category'):?>
<?php if($viewType != 'line'):?>
<td></td>
<?php endif;?>
<td colspan='2'>
@@ -151,7 +151,7 @@ $(function()
},
itemCreator: function($li, item)
{
var link = item.id !== undefined ? ('<a href="' + createLink('tree', 'browse', 'rootID=<?php echo $rootID ?>&viewType=<?php echo $viewType ?>&moduleID={0}&branch={1}'.format(item.id, item.branch)) + '">' + item.name + '</a>') : ('<span class="tree-toggle">' + item.name + '</span>');
var link = (item.id !== undefined && item.type != 'line') ? ('<a href="' + createLink('tree', 'browse', 'rootID=<?php echo $rootID ?>&viewType=<?php echo $viewType ?>&moduleID={0}&branch={1}'.format(item.id, item.branch)) + '">' + item.name + '</a>') : ('<span class="tree-toggle">' + item.name + '</span>');
var $toggle = $('<span class="module-name" data-id="' + item.id + '">' + link + '</span>');
if(item.type === 'bug') $toggle.append('&nbsp; <span class="text-muted">[B]</span>');
if(item.type === 'case') $toggle.append('&nbsp; <span class="text-muted">[C]</span>');
@@ -181,8 +181,8 @@ $(function()
subModules:
{
linkTemplate: '<?php echo helper::createLink('tree', 'browse', "rootID=$rootID&viewType=$viewType&moduleID={0}&branch={1}"); ?>',
title: '<?php echo $viewType == 'category' ? '': $lang->tree->child ?>',
template: '<a href="javascript:;"><?php echo $viewType == 'category' ? '': $lang->tree->child?></a>'
title: '<?php echo $viewType == 'line' ? '': $lang->tree->child ?>',
template: '<a href="javascript:;"><?php echo $viewType == 'line' ? '': $lang->tree->child?></a>'
}
},
action: function(event)
@@ -246,7 +246,7 @@ $(function()
$tree.find('[data-toggle="tooltip"]').tooltip();
$('#modulemenu > .nav > li > a[href*=tree][href*=browse]').not('[href*=<?php echo $viewType;?>]').parent().removeClass('active');
if(viewType == 'category') $('#modulemenu > .nav > li > a[href*=product][href*=all]').parent('li[data-id=all]').addClass('active');
if(viewType == 'line') $('#modulemenu > .nav > li > a[href*=product][href*=all]').parent('li[data-id=all]').addClass('active');
});
</script>
<?php
+2
View File
@@ -30,10 +30,12 @@ $jsRoot = $webRoot . "js/";
</tr>
<?php endif;?>
<?php $hidden = ($type != 'story' and $module->type == 'story');?>
<?php if($module->type != 'line'):?>
<tr <?php if($hidden) echo "style='display:none'";?>>
<th class='w-80px'><?php echo $lang->tree->parent;?></th>
<td><?php echo html::select('parent', $optionMenu, $module->parent, "class='form-control chosen'");?></td>
</tr>
<?php endif;?>
<tr <?php if($hidden) echo "style='display:none'";?>>
<th class='w-80px'><?php echo $lang->tree->name;?></th>
<td><?php echo html::input('name', $module->name, "class='form-control' autocomplete='off'");?></td>
+10 -8
View File
@@ -110,6 +110,7 @@ class tutorialModel extends model
$story->duplicateStory = 0;
$story->version = 1;
$story->deleted = '0';
$story->order = '0';
$stories = array();
$stories[] = $story;
@@ -202,14 +203,15 @@ class tutorialModel extends model
public function getTeamMembers()
{
$member = new stdclass();
$member->project = 1;
$member->account = $this->app->user->account;
$member->role = $this->app->user->role;
$member->join = $this->app->user->join;
$member->days = 10;
$member->hours = 7.0;
$member->totalHours = 70.0;
$member->realname = $this->app->user->realname;
$member->project = 1;
$member->account = $this->app->user->account;
$member->role = $this->app->user->role;
$member->join = $this->app->user->join;
$member->days = 10;
$member->hours = 7.0;
$member->totalHours = 70.0;
$member->realname = $this->app->user->realname;
$member->limitedUser = 0;
return array($member->account => $member);
}
+4 -1
View File
@@ -1802,7 +1802,10 @@ class upgradeModel extends model
*/
public function initProjectStoryOrder()
{
$storyGroup = $this->dao->select('*')->from(TABLE_PROJECTSTORY)->orderBy('story_asc')->fetchGroup('project', 'story');
$storyGroup = $this->dao->select('t1.*')->from(TABLE_PROJECTSTORY)->alias('t1')
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story=t2.id')
->orderBy('t2.pri_desc,t1.story_asc')
->fetchGroup('project', 'story');
foreach($storyGroup as $projectID => $stories)
{
-3
View File
@@ -5,9 +5,6 @@ $config->webhook->create->requiredFields = 'name, url';
$config->webhook->edit = new stdclass();
$config->webhook->edit->requiredFields = 'name, url';
$config->webhook->contentTypes['json'] = 'application/json';
$config->webhook->contentTypes['form'] = 'application/x-www-form-urlencoded';
$config->webhook->objectTypes['product'] = array('opened', 'edited', 'closed', 'undeleted');
$config->webhook->objectTypes['story'] = array('opened', 'edited', 'commented', 'frombug', 'changed', 'reviewed', 'closed', 'activated');
$config->webhook->objectTypes['productplan'] = array('opened', 'edited');
+2 -3
View File
@@ -151,9 +151,8 @@ class webhook extends control
$webhook = zget($webhooks, $data->webhook, '');
if($webhook)
{
$contentType = zget($this->config->webhook->contentTypes, $webhook->contentType, 'application/json');
$result = $this->webhook->fetchHook($contentType, $webhook->url, $data->data);
$this->webhook->saveLog($data->webhook, $data->action, $webhook->url, $contentType, $data->data, $result);
$result = $this->webhook->fetchHook($webhook, $data->data);
$this->webhook->saveLog($webhook, $data->action, $data->data, $result);
}
$this->dao->update(TABLE_WEBHOOKDATAS)->set('status')->eq('sended')->where('id')->eq($data->id)->exec();
+12 -1
View File
@@ -3,7 +3,6 @@ $(function()
$('#type').change(function()
{
var type = $(this).val();
$('#contentTypeTR').toggle(type != 'dingding');
$('#sendTypeTR').toggle(type != 'dingding');
$('#paramsTR').toggle(type != 'bearychat' && type != 'dingding');
$('#urlNote').html(urlNote[type]);
@@ -21,6 +20,18 @@ $(function()
}
});
$('#allParams, #allActions').click(function()
{
if($(this).prop('checked'))
{
$(this).parents('tr').find('input[type=checkbox]').attr('checked', 'checked');
}
else
{
$(this).parents('tr').find('input[type=checkbox]').removeAttr('checked');
}
});
$('#name').focus();
$('#paramstext').attr('disabled', 'disabled');
});
+12
View File
@@ -12,6 +12,18 @@ $(function()
}
});
$('#allParams, #allActions').click(function()
{
if($(this).prop('checked'))
{
$(this).parents('tr').find('input[type=checkbox]').attr('checked', 'checked');
}
else
{
$(this).parents('tr').find('input[type=checkbox]').removeAttr('checked');
}
});
$('#name').focus();
$('#paramstext').attr('disabled', 'disabled');
});
+62
View File
@@ -0,0 +1,62 @@
<?php
$lang->webhook->common = 'Webhook';
$lang->webhook->list = 'Hook List';
$lang->webhook->api = 'API';
$lang->webhook->entry = 'Entry';
$lang->webhook->log = 'Log';
$lang->webhook->assigned = 'Assigned To';
$lang->webhook->browse = 'Browse';
$lang->webhook->create = 'Create';
$lang->webhook->edit = 'Edit';
$lang->webhook->delete = 'Delete';
$lang->webhook->id = 'ID';
$lang->webhook->type = 'Type';
$lang->webhook->name = 'Name';
$lang->webhook->url = 'Webhook Address';
$lang->webhook->contentType = 'Content Type';
$lang->webhook->sendType = 'Send Type';
$lang->webhook->product = 'Product';
$lang->webhook->project = 'Project';
$lang->webhook->params = 'Params';
$lang->webhook->action = 'Action';
$lang->webhook->desc = 'Desc';
$lang->webhook->createdBy = 'Created By';
$lang->webhook->createdDate = 'Created Date';
$lang->webhook->editedby = 'Edited By';
$lang->webhook->editedDate = 'Edited Date';
$lang->webhook->date = 'Date';
$lang->webhook->data = 'Data';
$lang->webhook->result = 'Result';
$lang->webhook->typeList['bearychat'] = 'Bearychat';
$lang->webhook->typeList['dingding'] = 'Dingding';
$lang->webhook->typeList['default'] = 'Default';
$lang->webhook->sendTypeList['sync'] = 'Synchronization';
$lang->webhook->sendTypeList['async'] = 'Asynchronous';
$lang->webhook->paramsList['objectType'] = 'Object Type';
$lang->webhook->paramsList['objectID'] = 'Object ID';
$lang->webhook->paramsList['product'] = 'Product';
$lang->webhook->paramsList['project'] = 'Project';
$lang->webhook->paramsList['action'] = 'Action';
$lang->webhook->paramsList['actor'] = 'Actor';
$lang->webhook->paramsList['date'] = 'Date';
$lang->webhook->paramsList['comment'] = 'Comment';
$lang->webhook->paramsList['text'] = 'Action Desc';
$lang->webhook->saveSuccess = 'Save success.';
$lang->webhook->confirmDelete = 'Are your sure delete this hook?';
$lang->webhook->trimWords = '';
$lang->webhook->note = new stdClass();
$lang->webhook->note->async = 'If the send type is asynchronous, need open cron.';
$lang->webhook->note->product = 'All actions will trigger the hook if the product is empty, else only actions of the product will trigger it.';
$lang->webhook->note->project = 'All actions will trigger the hook if the project is empty, else only actions of the project will trigger it.';
$lang->webhook->note->typeList['bearychat'] = 'Add a zentao bot in bearychat and get the webhook address.';
$lang->webhook->note->typeList['dingding'] = 'Add a customed bot in dingding and get the webhook address.';
$lang->webhook->note->typeList['default'] = 'Get webhook address from others';
+1 -1
View File
@@ -17,9 +17,9 @@ $lang->webhook->name = '名称';
$lang->webhook->url = 'Hook地址';
$lang->webhook->contentType = '内容类型';
$lang->webhook->sendType = '发送方式';
$lang->webhook->params = '参数';
$lang->webhook->product = '关联产品';
$lang->webhook->project = '关联项目';
$lang->webhook->params = '参数';
$lang->webhook->action = '触发动作';
$lang->webhook->desc = '描述';
$lang->webhook->createdBy = '由谁创建';
+16 -22
View File
@@ -79,11 +79,9 @@ class webhookModel extends model
$action = $actions[$log->action];
$text = $this->app->user->realname . $this->lang->action->label->{$action->action}. $this->lang->action->objectTypes[$action->objectType];
$object = $this->dao->select('*')->from($this->config->objectTables[$action->objectType])->where('id')->eq($action->objectID)->fetch();
$field = $this->config->action->objectNameFields[$action->objectType];
$text .= "[#{$action->objectID}::{$object->$field}]";
if($action->action == 'assigned') $text .= ' ' . $this->lang->webhook->assigned . ' ' . zget($users, $object->assignedTo);
$text = $this->app->user->realname . $this->lang->action->label->{$action->action}. $this->lang->action->objectTypes[$action->objectType] . "[#{$action->objectID}::{$object->$field}]";
$log->action = $text;
$log->actionURL = $this->getViewLink($action->objectType, $action->objectID);
@@ -151,6 +149,7 @@ class webhookModel extends model
->join('products', ',')
->join('projects', ',')
->skipSpecial('url')
->remove('allParams, allActions')
->get();
$webhook->params = $this->post->params ? implode(',', $this->post->params) . ',text' : 'text';
$webhook->actions = $this->post->actions ? json_encode($this->post->actions) : '[]';
@@ -177,6 +176,7 @@ class webhookModel extends model
->join('products', ',')
->join('projects', ',')
->skipSpecial('url')
->remove('allParams, allActions')
->get();
$webhook->params = $this->post->params ? implode(',', $this->post->params) . ',text' : 'text';
$webhook->actions = $this->post->actions ? json_encode($this->post->actions) : '[]';
@@ -217,9 +217,8 @@ class webhookModel extends model
continue;
}
$contentType = zget($this->config->webhook->contentTypes, $webhook->contentType, 'application/json');
$result = $this->fetchHook($contentType, $webhook->url, $postData);
$this->saveLog($id, $actionID, $webhook->url, $contentType, $postData, $result);
$result = $this->fetchHook($webhook, $postData);
$this->saveLog($webhook, $actionID, $postData, $result);
}
return !dao::isError();
}
@@ -268,18 +267,15 @@ class webhookModel extends model
$email = '';
if($actionType == 'assigned')
{
$assignedTo = $object->assignedTo;
foreach($users as $user)
{
if($user->account == $object->assignedTo)
{
$assignedTo = $user->realname;
$mobile = $user->mobile;
$email = $user->email;
$mobile = $user->mobile;
$email = $user->email;
break;
}
}
$text .= ' ' . $this->lang->webhook->assigned . ' ' . $assignedTo;
}
$action->text = $text;
@@ -396,18 +392,17 @@ class webhookModel extends model
/**
* Post hook data.
*
* @param string $contentType
* @param string $url
* @param object $webhook
* @param string $sendData
* @access public
* @return int
*/
public function fetchHook($contentType, $url, $sendData)
public function fetchHook($webhook, $sendData)
{
$header[] = "Content-Type: $contentType;charset=utf-8";
$header[] = "Content-Type: {$webhook->contentType};charset=utf-8";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_URL, $webhook->url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_POSTFIELDS, $sendData);
@@ -451,22 +446,21 @@ class webhookModel extends model
*
* @param int $webhookID
* @param int $actionID
* @param string $url
* @param string $contentType
* @param object $webhook
* @param string $data
* @param string $result
* @access public
* @return bool
*/
public function saveLog($webhookID, $actionID, $url, $contentType, $data, $result)
public function saveLog($webhook, $actionID, $data, $result)
{
$log = new stdclass();
$log->objectType = 'webhook';
$log->objectID = $webhookID;
$log->objectID = $webhook->id;
$log->action = $actionID;
$log->date = helper::now();
$log->url = $url;
$log->contentType = $contentType;
$log->url = $webhook->url;
$log->contentType = $webhook->contentType;
$log->data = $data;
$log->result = $result;
+3 -3
View File
@@ -18,8 +18,8 @@
<tr>
<?php $vars = "orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
<th class='w-60px'><?php common::printOrderLink('id', $orderBy, $vars, $lang->webhook->id);?></th>
<th class='w-100px'><?php common::printOrderLink('type', $orderBy, $vars, $lang->webhook->type);?></th>
<th><?php common::printOrderLink('name', $orderBy, $vars, $lang->webhook->name);?></th>
<th class='w-60px'><?php common::printOrderLink('type', $orderBy, $vars, $lang->webhook->type);?></th>
<th class='w-200px text-left'><?php common::printOrderLink('name', $orderBy, $vars, $lang->webhook->name);?></th>
<th><?php common::printOrderLink('url', $orderBy, $vars, $lang->webhook->url);?></th>
<th class='w-70px'><?php echo $lang->actions;?></th>
</tr>
@@ -28,7 +28,7 @@
<?php foreach($webhooks as $id => $webhook):?>
<tr>
<td class='text-center'><?php echo $id;?></td>
<td><?php echo zget($lang->webhook->typeList, $webhook->type);?></td>
<td class='text-center'><?php echo zget($lang->webhook->typeList, $webhook->type);?></td>
<td class='text' title='<?php echo $webhook->name;?>'><?php echo $webhook->name;?></td>
<td class='text' title='<?php echo $webhook->url;?>'><?php echo $webhook->url;?></td>
<td class='text-right'>
+11 -8
View File
@@ -23,7 +23,7 @@
<form id='webhookForm' method='post' class='ajaxForm'>
<table class='table table-form'>
<tr>
<th class='w-80px'><?php echo $lang->webhook->type;?></th>
<th class='w-100px'><?php echo $lang->webhook->type;?></th>
<td class='w-p50'><?php echo html::select('type', $lang->webhook->typeList, 'default', "class='form-control'");?></td>
<td></td>
</tr>
@@ -37,11 +37,6 @@
<td><?php echo html::input('url', '', "class='form-control'");?></td>
<td id='urlNote'><?php echo $lang->webhook->note->typeList['default'];?></td>
</tr>
<tr id='contentTypeTR'>
<th><?php echo $lang->webhook->contentType;?></th>
<td><?php echo html::select('contentType', $config->webhook->contentTypes, '', "class='form-control'");?></td>
<td></td>
</tr>
<tr id='sendTypeTR'>
<th><?php echo $lang->webhook->sendType;?></th>
<td><?php echo html::select('sendType', $lang->webhook->sendTypeList, '', "class='form-control'");?></td>
@@ -58,11 +53,19 @@
<td><?php echo $lang->webhook->note->project;?></td>
</tr>
<tr id='paramsTR'>
<th><?php echo $lang->webhook->params;?></th>
<th>
<label class='checkbox-inline'>
<input type='checkbox' id='allParams' name='allParams'><strong><?php echo $lang->webhook->params;?></strong>
</label>
</th>
<td class='labelWidth' colspan='2'><?php echo html::checkbox('params', $lang->webhook->paramsList, 'text');?></td>
</tr>
<tr>
<th><?php echo $lang->webhook->action;?></th>
<th>
<label class='checkbox-inline'>
<input type='checkbox' id='allActions' name='allActions'><strong><?php echo $lang->webhook->action;?></strong>
</label>
</th>
<td colspan='2'>
<table class='table table-bordered'>
<?php foreach($config->webhook->objectTypes as $objectType => $actions):?>
+11 -8
View File
@@ -22,7 +22,7 @@
<form id='webhookForm' method='post' class='ajaxForm'>
<table class='table table-form'>
<tr>
<th class='w-80px'><?php echo $lang->webhook->name;?></th>
<th class='w-100px'><?php echo $lang->webhook->name;?></th>
<td class='w-p50'><?php echo html::input('name', $webhook->name, "class='form-control'");?></td>
<td></td>
</tr>
@@ -32,11 +32,6 @@
<td><?php echo zget($lang->webhook->note->typeList, $webhook->type);?></td>
</tr>
<?php if($webhook->type != 'dingding'):?>
<tr>
<th><?php echo $lang->webhook->contentType;?></th>
<td><?php echo html::select('contentType', $config->webhook->contentTypes, $webhook->contentType, "class='form-control'");?></td>
<td></td>
</tr>
<tr>
<th><?php echo $lang->webhook->sendType;?></th>
<td><?php echo html::select('sendType', $lang->webhook->sendTypeList, $webhook->sendType, "class='form-control'");?></td>
@@ -55,12 +50,20 @@
</tr>
<?php if(strpos(',bearychat,dingding,', ",$webhook->type,") === false):?>
<tr>
<th><?php echo $lang->webhook->params;?></th>
<th>
<label class='checkbox-inline'>
<input type='checkbox' id='allParams' name='allParams'><strong><?php echo $lang->webhook->params;?></strong>
</label>
</th>
<td class='labelWidth' colspan='2'><?php echo html::checkbox('params', $lang->webhook->paramsList, $webhook->params);?></td>
</tr>
<?php endif;?>
<tr>
<th><?php echo $lang->webhook->action;?></th>
<th>
<label class='checkbox-inline'>
<input type='checkbox' id='allActions' name='allActions'><strong><?php echo $lang->webhook->action;?></strong>
</label>
</th>
<td colspan='2'>
<table class='table table-bordered'>
<?php foreach($config->webhook->objectTypes as $objectType => $actions):?>
+1 -1
View File
@@ -14,7 +14,7 @@
<div id='featurebar'>
<ul class='nav'>
<?php
echo "<li id='entry'>"; common::printLink('entry', 'browse', '', $lang->webhook->entry); echo '</li>';
//echo "<li id='entry'>"; common::printLink('entry', 'browse', '', $lang->webhook->entry); echo '</li>';
echo "<li id='webhook' class='active'>"; common::printLink('webhook', 'browse', '', $lang->webhook->common); echo '</li>';
?>
</ul>