Merge branch 'master' into zentaopms_239

This commit is contained in:
wangyidong
2022-10-27 11:39:47 +08:00
370 changed files with 9090 additions and 2016 deletions
+3
View File
@@ -103,10 +103,13 @@ zentaoxx:
cp zentaoxx/db_bak/upgradexuanxuan*.sql zentaoxx/db_bak/xuanxuan.sql zentaoxx/db/
rm -rf zentaoxx/db_bak/
sed -i "s/\$$accountAdmin = \$$this->dao->select('account, admin')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch();/\$$accountAdmin = \$$this->dao->select('account')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch();\n\$$admins = \$$this->dao->select('admins')->from(TABLE_COMPANY)->where('id')->eq(\$$this->app->company->id)->fetch('admins');\n\$$adminArray = explode(',', \$$admins);\n\$$accountAdmin->admin = in_array(\$$accountAdmin->account, \$$adminArray) ? 'super' : '';\n/" zentaoxx/extension/xuan/im/model/chat.php
sed -i "s/\$$sysAdmins = \$$this->dao->select('id')->from(TABLE_USER)->where('admin')->eq('super')->fetchPairs();/\$$account = \$$this->loadModel('user')->getById(\$$userID);\n\$$admins = \$$this->dao->select('admins')->from(TABLE_COMPANY)->where('id')->eq(\$$this->app->company->id)->fetch('admins');\n\$$adminArray = explode(',', \$$admins);\nreturn in_array(\$$account, \$$adminArray);\n/" zentaoxx/extension/xuan/im/model/chat.php
sed -i "/->on('tc.ownedBy=tu.account')/{ N ; s/type/tc.type/}" zentaoxx/extension/xuan/im/model/chat.php
sed -i "s/\$$super = \$$this->dao->select('admin')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch('admin');/\$$account = \$$this->dao->select('account')->from(TABLE_USER)->where('id')->eq(\$$userID)->fetch('account');\n\$$admins = \$$this->dao->select('admins')->from(TABLE_COMPANY)->where('id')->eq(\$$this->app->company->id)->fetch('admins');\n\$$adminArray = explode(',', \$$admins);\n\$$super = in_array(\$$account, \$$adminArray) ? 'super' : '';/g" zentaoxx/extension/xuan/im/control.php
sed -i "/foreach(\$$users as \$$user)/i \$$admins = \$$this->dao->select('admins')->from(TABLE_COMPANY)->where('id')->eq(\$$this->app->company->id)->fetch('admins');\$$adminArray = explode(',', \$$admins);" zentaoxx/extension/xuan/im/model/user.php
sed -i "/if(\!isset(\$$user->signed)) \$$user->signed = 0;/a \$$user->admin = in_array(\$$user->account, \$$adminArray) ? 'super' : '';" zentaoxx/extension/xuan/im/model/user.php
sed -i "s/\$$user = \$$this->user->login(\$$account, \$$user->password);/\$$user = \$$this->user->login(\$$user);\n\$$url .= \$$this->config->requestType == 'GET' ? '\&' : '?';\n\$$url .= \"{\$$this->config->sessionVar}={\$$this->app->sessionID}\";\n/" zentaoxx/extension/xuan/im/control.php
sed -i "s/\$$file->fullURL/\$$file->webPath/" zentaoxx/extension/xuan/im/control.php
sed -i 's/XXBVERSION/$(XVERSION)/g' zentaoxx/config/ext/_0_xuanxuan.php
sed -i "/\$$config->xuanxuan->backend /c\\\$$config->xuanxuan->backend = 'zentao';" zentaoxx/config/ext/_0_xuanxuan.php
sed -i 's/site,//' zentaoxx/extension/xuan/im/model/user.php
+64 -30
View File
@@ -1,47 +1,81 @@
## 1. What is ZenTao?
English | [中文](Readme_zh.md)
ZenTao is an open source project management software, developed by Qingdao Nature Easy Soft Network Technology Co. Ltd. Combining product management, project management, QA management, document management, company management and todo management. It is a professional project management software, covering the core process of software development projects.
<p align="center"><a href="https://www.zentao.pm" target="_blank" rel="noopener noreferrer"><img src="doc/img/zentao-en.png" alt="ZenTao Logo"></a></p>
<p align="center">
<a href="https://www.php.net"><img src="https://img.shields.io/badge/php-%3E=5.6-brightgreen.svg?maxAge=2592000" alt="PHP Version"></a>
<a href="https://github.com/easysoft/zentaopms/releases/latest"><img src="https://img.shields.io/github/release/easysoft/zentaopms.svg" alt="Latest Version"></a>
<a href="mailto:chunsheng@easycorp.ltd"><img src="https://img.shields.io/badge/Email-chunsheng@easycorp.ltd-ea644a" alt="Email" /></a>
<a href="https://github.com/easysoft/zentaopms/blob/master/COPYING"><img src="https://img.shields.io/badge/License-AGPL%20or%20ZPL-blue" alt="ZenTao License"></a>
<a href="https://www.zentao.pm"><img src="https://img.shields.io/badge/Website-www.zentao.pm-blue" alt="ZenTao Website"></a>
</p>
ZenTao is practical and pragmatic. It has full features and beautiful interfaces, and is easy to use. ZenTao is well structured and can be flexibly extended. It also has powerful search features, various forms of statistical reports and complete API.
# Introduction
ZenTao is the first opensource project management software in China. It’s a comprehensive, all-in-one platform that covers the main PM process, from product and project management to quality management, documentation management, organization management, and office management.
ZenTao focuses on development project management!
Since its establishment in 2009, ZenTao has helped tens of thousands of teams and organizations improve their project management structures. Currently, ZenTao is being used by some of the largest companies in the world, ranging from those in the sectors of finance and telecoms to manufacturing and software development. They trust ZenTao for streamlining their processes, simplifying communication between clients and employees, increasing transparency, and improving productivity and efficiency.
## 2. Why is it called ZenTao?
# Design Philosophy
Zen(禅) and Tao(道) are the two Chinese characters that have rich meanings in both religion and culture. ZenTao Project Management Software takes the cultural meaning of Zen and Tao, and is expected to convey our understanding and thinking of management. Inspired by The Tao of Programming and The Zen of Programming, we named our software ZenTao.
The name ZenTao came from combining two Chinese characters, Zen(禅) and Tao(道), which have rich inspirations pertaining to culture and history. With its name referring to highly respected aspects of life, it’s only logical to convey their meaning in management by providing transparency, orderliness, and accessibility.
## 3. Design philosophy of ZenTao Project Management Software
ZenTao management concept is built on the 3 popular management methodologies: Scrum, Waterfall, and Kanban:
The main design philosophy of ZenTao Project Management Software is based on Scrum, an internationally popular Agile methodology. Scrum is very pragmatic and easy to operate, so it fits in the fast iterative development of software projects. However, Scrum only defines the core management framework. There are still many details and processes that have to be extended and developed. Based on the philosophy of Scrum and with the observation of the current development situations in China, ZenTao integrates bug management, test case management, release management and document management, and it completely covers the entire lifecycle of software development. In ZenTao, the concepts of product, project and test are clearly defined. Product team, development team and QA team coordinate and check with each other while they function differently. The three teams interact with each other through stories, tasks and bugs, and eventually deliver the product with quality.
- The Scrum model built-in ZenTao is adaptable and flexible, which perfectly matches the rapid iterations of software development projects.
- The Waterfall model built-in ZenTao lays emphasis on stages division and strict process control, which is ideal for projects that are well defined in advance and with fewer changes.
- The Kanban model built-in ZenTao pays more attention to value flow and visualization, which is suitable for the team with a transparent process and efficient transmission of information.
## 4. Why choose ZenTao Project Management Software?
ZenTao clearly defines the concepts of product, project, and QA to help the product owners, developers, and testers coordinate with each other while maintaining separate functionalities. Through stories, tasks, and bugs, the whole teams interact and track issues and improvements to ensure the delivery of quality products.
* ZenTao is a professional development project management software and cannot be replaced by any simple project management software.
* ZenTao has precise and pragmatic management philosphy, which will accelerate Agile development.
* ZenTao has full features as a project management software, so you don’t have to integrate several systems together, like mantisbt + trac + testlink.
* Open source codes and flexible extension mechanism. It is convenient to use and develop based on ZenTao.
* Underlying framework and frontend UI framework are developed independently; robust and stable with beautiful interface and friendly interaction.
* Perfect community mechanism; you can get technical support and help in time.
* Zero input, which means you have no risk for choosing ZenTao, compared with other commercial software that cost you thousands of dollars.
* Support various deployments, either private or cloud.
Besides, with ZenTao's feature-rich modules including data visualization, measurement, DevOps, Doc asset management, and automated testing, ZenTao offers flexible solutions to cover the entire process of software development, allows organizations to work efficiently and productivity, and helps them better control time, cost, and quality.
# Official Website
## 5. Features of ZenTao Project Management Software
- [Website](https://www.zentao.pm/)
- [Manual](https://www.zentao.pm/book/)
- [FAQ](https://www.zentao.pm/page/faq.html)
- [Extension](https://www.zentao.pm/extension-browse.html)
* Product management: including products, stories, plans, releases and roadmaps;
* Project management: including projects, tasks, teams, builds and burn-down charts;
* Quality management: including bugs, test cases, test tasks and test results;
* Document management: including product document library, project document library and customized document library;
* Work management: including to-do management and personal management, such as my tasks, my bugs, my story and my projects;
* Organization management: including department, users, groups and privileges;
* Statistics: various reports;
* Search: powerful search functions to help you find the data you need.
* Extension mechanism: extensible in almost any parts of ZenTao;
* API mechanism: convenient for integration with other systems.
# Demo
## 6. Website
- [ZenTao Opensource](https://demo15.zentao.pm)
- [ZenTao Biz](https://biz.demo15.zentao.pm)
- [ZenTao Max](https://max.demo15.zentao.pm)
Our website is: [www.zentao.pm](http://www.zentao.pm)
# Security Vulnerabilities
If you find any vulnerability in ZenTao system please feel free to contact us at chunsheng@easycorp.ltd. We do appreciate your time and effort.
# License
ZenTao is an opensource project management software licensed on [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html) and [ZPL](http://zpl.pub/page/zplv12.html).
<details>
<summary><h1>Enhanced version<h1/></summary>
ZenTao Biz, ZenTao Max, and ZenTao Cloud are available for you if ZenTao Opensource can not meet your feature requirement.
> [Learn more about the comparison between ZenTao Opensource, ZenTao Biz, and ZenTao Max](https://www.zentao.pm/page/vs.html).
## ZenTao Biz
ZenTao Biz has more powerful functions based on the ZenTao Open Source. It also expands horizontally based on the project management process and covers more roles.
On the one hand, ZenTao Biz provides more complete services for enterprises and its enhanced functions are more suitable for the internal process management of the companies.
On the other hand, ZenTao Biz has more added functions such as operation and maintenance management, OA office management, feedback management, as well as document version management, and online preview. It can support the customer's related work more effectively outside the development process, and provide more comprehensive support for the project management process.
## ZenTao Max
ZenTao Max, the most advanced ZenTao version, allows users to easily monitor and track the entire process of project management. It also helps improve the robustness and maturity of enterprises to greatly increase the probability of project success.
The features such as process control, process definition, project measurement, issue management, risk management, quality assurance, and project reporting are strong enhanced in ZenTao Max. It's also supported the implementation of CMMI standards, help enterprises pass CMMI assessment.
## ZenTao Cloud
> Learn more about [ZenTao Cloud](https://www.zentao.pm/page/saas-pricing.html).
ZenTao Cloud provides a flexible solution for users who prefer the SaaS service and running businesses anywhere and anytime. It's easy to use and super convenient in that it only needs one click to activate an account. Besides, ZenTao Cloud requires no maintenance and will keep updating automatically. With HTTPS agreement, your data will keep safe and no worry about information disclosure. Even better, data on ZenTao Cloud will backup automatically and users can download the backup file at any time.
</details>
+77 -29
View File
@@ -1,41 +1,89 @@
一、什么是禅道项目管理软件?
[English](README.md) | 中文
禅道是第一款国产的开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、 组织管理和事务管理于一体,是一款专业的研发项目管理软件,完整地覆盖了项目管理的核心流程。禅道管理思想注重实效,软件架构合理,操作简洁高效,代码实现合理,内置灵活的扩展机制和api调用机制,支持多语言。
<p align="center"><a href="https://www.zentao.net" target="_blank" rel="noopener noreferrer"><img src="doc/img/zentao-cn.png" alt="ZenTao Logo"></a></p>
二、为什么用“禅道”这个名字?
<p align="center">
<a href="https://www.php.net"><img src="https://img.shields.io/badge/php-%3E=5.6-brightgreen.svg?maxAge=2592000" alt="PHP Version"></a>
<a href="https://github.com/easysoft/zentaopms/releases/latest"><img src="https://img.shields.io/github/release/easysoft/zentaopms.svg" alt="Latest Version"></a>
<a href="mailto:chunsheng@easycorp.ltd"><img src="https://img.shields.io/badge/Email-chunsheng@easycorp.ltd-ea644a" alt="Email" /></a>
<a href="https://github.com/easysoft/zentaopms/blob/master/COPYING"><img src="https://img.shields.io/badge/License-AGPL%20or%20ZPL-blue" alt="ZenTao License"></a>
<a href="https://www.zentao.net"><img src="https://img.shields.io/badge/Website-www.zentao.net-blue" alt="ZenTao Website"></a>
</p>
# 介绍
禅道是第一款国产的开源项目管理软件。它集产品管理、项目管理、质量管理、文档管理、 组织管理和事务管理于一体,是一款专业的研发项目管理软件,完整地覆盖了项目管理的核心流程。
禅道管理思想注重实效,功能完备丰富,操作简洁高效,界面美观大方,搜索功能强大,统计报表丰富多样,软件架构合理,扩展灵活,有完善的 API 可以调用。
# 设计理念
禅和道是中国文化中极具代表意义的两个字,是中国传统文化的结晶。我们之所以选用“禅道”作为我们软件的名字,是希望通过这两个字来传达我们对管理的理解和思考。我们希望通过禅道来进行的管理,可以摒弃繁文缛节,还原管理的本质!
三、禅道的设计理念
禅道项目管理软件的主要管理思想基于国际流行的`Scrum`模型、瀑布模型和看板模型三种项目管理方法:
禅道项目管理软件的主要管理思想基于国际流行的敏捷项目管理方 式——Scrum。scrum是一种注重实效的敏捷项目管理方式。它规定了核心的管理框架,但具体的细节还需要团队自行扩充。禅道在遵循其管理方式基础上,又融入了国内研发现状的很多需求,比如bug管理,测试用例管理,发布管理,文档管理等。因此禅道不仅仅是一款scrum敏捷项目管理工 具,更是一款完备的项目管理软件。基于scrum,又不局限于scrum。
- `Scrum`模型方法注重实效,操作性强,非常适合软件研发项目的快速迭代开发。
禅道还首次创造性的将产品、项目、测试这三者的概念明确分开,互相配合,又互相制约,通过需求、任务、bug来进行交相互动,终通过项目拿到合格的产品。
- 瀑布模型方法注重阶段清晰、流程严谨、范围可控,非常适合预先有明确定义且变动不大的产品研发管理。
四、选择禅道的八大理由:
1. 开源的软件,保证了您使用的放心和灵活。
2. 先进的管理思想,让您在竞争中拔得头筹。
3. 完备的管理功能,无需再整合其他多个系统。
4. 国产软件,中文支持,操作习惯更符合国人。
5. 灵活的扩展机制,可以保证您不局限于禅道自身的功能。
6. 日趋完善的社区机制,可以获得及时的技术支持和帮助,保证您无后顾之忧。
7. 几乎为零的投入,禅道作为开源软件,其投入几乎为零,相比动辄十几万的商业软件,您选择禅道没有任何风险。
8. 开发团队已经公司化运作,保证软件的持久发展。我们从04年从事开源软件开发以来,已经坚持了六年。
- 看板模型方式注重价值流转和可视化,非常适合流程公开透明和信息高效传递的团队。
五、禅道的功能列表:
禅道首次创造性的将产品、项目、测试这三者的概念明确分开,产品人员、开发团队、测试人员,三者分立,互相配合,又互相制约,通过需求、任务、`BUG` 来进行交相互动,终通过项目拿到合格的产品。
1. 产品管理:包括产品、需求、计划、发布、路线图等功能。
2. 项目管理:包括项目、任务、团队、build、燃尽图等功能。
3. 质量管理:包括bug、测试用例、测试任务、测试结果等功能。
4. 文档管理:包括产品文档库、项目文档库、自定义文档库等功能。
5. 事务管理:包括todo管理,我的任务、我的Bug、我的需求、我的项目等个人事务管理功能。
6. 组织管理:包括部门、用户、分组、权限等功能。
7. 统计功能:丰富的统计表。
8. 搜索功能:强大的搜索,帮助您找到相应的数据。
9. 灵活的扩展机制,几乎可以对禅道的任何地方进行扩展。
10. 强大的api机制,方便与其他系统集成。
在数据可视化、度量、`DevOPS`、文档资产管理和自动化测试等模块的加持下,禅道软件形成了项目流程管理、`DevOps`一体化、自动化测试等三大解决方案,完整的覆盖了产品研发的全生命周期管理,助力广大企业高效协作、降本提效。
也许您已经"众里寻她千百度",那么让禅道带给您“蓦然回首,那人却在灯火阑珊处”的惊喜吧!Let's zentao!
# 官方网站
禅道官方网站: [www.zentao.net](http://www.zentao.net)
- [官网](https://www.zentao.net)
- [文档](https://www.zentao.net/book/zentaopms.html)
- [常见问题](https://www.zentao.net/faq.html)
- [插件库](https://www.zentao.net/extension-browse.html)
## Demo
- [开源版](https://demo16.zentao.net)
- [企业版](https://biz.demo16.zentao.net)
- [旗舰版](http://zentaomax.demo.zentao.net)
# 安全漏洞
如果您发现禅道项目管理软件中存在安全漏洞,请发送电子邮件至禅道官方团队,电子邮件地址为 chunsheng@easycorp.ltd ,所有安全漏洞都会被及时的解决。
# 开源协议
禅道是一个基于 [AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html) 和 [ZPL](http://zpl.pub/page/zplv12.html) 双协议的开源项目管理软件。
----
也许您已经"众里寻她千百度",那么让禅道带给您"蓦然回首,那人却在灯火阑珊处"的惊喜吧!
<details>
<summary><h1>增强版本<h1/></summary>
如果开源版的功能不能满足您的需要,可以考虑禅道[企业版](https://www.zentao.net/page/enterprise.html)、[旗舰版](https://www.zentao.net/page/max.html)或[云禅道](https://www.chandao.net)。
## 企业版
> 前往查看[企业版和开源版的对比](https://www.zentao.net/page/enterprise.html#diff)。
禅道企业版是在禅道开源版的基础上增加增强功能的版本,该版本也基于项目管理的流程做了横向拓展,覆盖了更多的角色。
一方面,企业版可以企业提供更完善的服务;增强功能更加适合企业的内部流程化管理。
另一方面,企业版还增加了运维管理、OA办公管理、反馈管理,以及文档的版本管理及在线预览等功能,可以更有效地支持客户在研发管理流程之外的相关工作,为企业项目管理流程提供更全面的支撑。
## 旗舰版
> 前往查看[旗舰版功能对比](https://www.zentao.net/page/max.html#diff)。
旗舰版作为禅道最高的版本系列,可以完整覆盖项目管理的各个过程,帮助企业建立研发管理体系,提高企业管理流程的稳健性和项目管理成熟度,大大增加项目成功的概率。
旗舰版增强了流程控制、过程定义、项目度量、问题管理、风险管控、质量保证、项目报告等方面的功能,同时可以支持CMMI标准的落地实施,帮助企业通过CMMI评估,提升研发管理能力。
## 云禅道
> 前往了解和体验[云禅道](https://www.chandao.net)。
云禅道是禅道企业版和旗舰版的 SaaS 服务,使用便捷,一键即可开通,无需维护,禅道版本自动升级;资源与服务支持灵活扩容,资源按需购买;提供覆盖全国的CDN服务,访问更快;HTTPS协议加密,更加安全;数据自动备份,随时下载备份至本地。
</details>
+1 -1
View File
@@ -1 +1 @@
17.6.2
17.7
+1 -1
View File
@@ -57,7 +57,7 @@ class executionsEntry extends entry
{
foreach($execution->hours as $field => $value) $execution->$field = $value;
$execution = $this->filterFields($execution, 'id,name,project,code,type,parent,begin,end,status,openedBy,openedDate,delay,progress,' . $appendFields);
$execution = $this->filterFields($execution, 'id,name,project,code,type,parent,begin,end,status,openedBy,openedDate,delay,progress,children,' . $appendFields);
$result[] = $this->format($execution, 'openedBy:user,openedDate:time,lastEditedBy:user,lastEditedDate:time,closedBy:user,closedDate:time,canceledBy:user,canceledDate:time,PM:user,PO:user,RD:user,QD:user,whitelist:userList,begin:date,end:date,realBegan:date,realEnd:date,deleted:bool');
}
+1 -1
View File
@@ -25,7 +25,7 @@ class productProjectsEntry extends entry
$appendFields = $this->param('fields', '');
$control = $this->loadController('product', 'project');
$control->project($this->param('status', 'all'), $productID, $this->param('branch', 0), $this->param('involved', 0), $this->param('order', 'order_desc'));
$control->project($this->param('status', 'all'), $productID, $this->param('branch', 0), $this->param('involved', 0), $this->param('order', 'order_desc'), 0, $this->param('limit', 20), $this->param('page', 1));
$data = $this->getData();
if(isset($data->status) and $data->status == 'success')
+3 -1
View File
@@ -23,8 +23,10 @@ class projectReleasesEntry extends entry
if(empty($projectID)) $projectID = $this->param('project');
if(empty($projectID)) return $this->sendError(400, 'Need project id.');
$page = intval($this->param('page', 1));
$limit = intval($this->param('limit', 20));
$control = $this->loadController('projectrelease', 'browse');
$control->browse($projectID, $this->param('execution', 0), $this->param('status', 'all'), $this->param('order', 't1.date_desc'));
$control->browse($projectID, $this->param('execution', 0), $this->param('status', 'all'), $this->param('order', 't1.date_desc'), 0, $limit, $page);
/* Response */
$data = $this->getData();
+1 -1
View File
@@ -36,7 +36,7 @@ class taskRecordEstimateEntry extends Entry
if(!$data) return $this->error('error');
if(isset($data->status) and $data->status == 'fail') return $this->sendError(zget($data, 'code', 400), $data->message);
$effort = array();
$effort = new stdclass();
if($issetEffort and $data->data->efforts) $effort = $data->data->efforts;
if(!$issetEffort and $data->data->estimates) $effort = $data->data->estimates;
$this->send(200, array('effort' => $effort));
+39
View File
@@ -66,4 +66,43 @@ class testtasksEntry extends entry
return $this->send(200, array('page' => $pager->pageID, 'total' => $pager->recTotal, 'limit' => $pager->recPerPage, 'testtasks' => $result));
}
/**
* POST method.
*
* @access public
* @param int $projectID
* @return void
*/
public function post($projectID = 0)
{
if(!$projectID) $projectID = $this->param('project', 0);
$productID = $this->request('product', 0);
$executionID = $this->request('execution', 0);
$buildID = $this->request('build', 0);
if(empty($projectID)) return $this->sendError(400, 'need project id!');
if(empty($productID)) return $this->sendError(400, 'need product id!');
if(empty($executionID)) return $this->sendError(400, 'need execution id!');
if(empty($buildID)) return $this->sendError(400, 'need build id!');
/* Check whether executionID and buildID is valid. */
$executions = $this->loadModel('product')->getExecutionPairsByProduct($productID, '', 'id_desc', $projectID);
$builds = $this->loadModel('build')->getBuildPairs($productID, 'all', 'notrunk');
if(!isset($executions[$executionID])) return $this->sendError(400, 'error execution id!');
if(!isset($builds[$buildID])) return $this->sendError(400, 'error build id!');
$fields = 'product,execution,build,name,begin,end,owner,type,pri,status,desc';
$this->batchSetPost($fields);
$control = $this->loadController('testtask', 'create');
$this->requireFields('name,begin,end');
$control->create($productID, $executionID, $build, $projectID);
$data = $this->getData();
if(!isset($data->id)) return $this->sendError(400, $data->message);
$testtask = $this->loadModel('testtask')->getByID($data->id);
$this->send(201, $testtask);
}
}
+1
View File
@@ -62,6 +62,7 @@ class userEntry extends Entry
$info->profile->role = array('code' => $info->profile->role, 'name' => $this->lang->user->roleList[$info->profile->role]);
$info->profile->admin = strpos($this->app->company->admins, ",{$profile->account},") !== false;
$info->profile->superReviewer = isset($this->config->story) ? strpos(',' . trim(zget($this->config->story, 'superReviewers', ''), ',') . ',', ',' . $this->app->user->account . ',') : false;
$info->profile->view = $this->app->user->view;
if(!$fields) return $this->send(200, $info);
+1 -1
View File
@@ -16,7 +16,7 @@ if(!class_exists('config')){class config{}}
if(!function_exists('getWebRoot')){function getWebRoot(){}}
/* 基本设置。Basic settings. */
$config->version = '17.6.2'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
$config->version = '17.7'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it.
$config->liteVersion = '1.2'; // 迅捷版版本。 The version of Lite.
$config->charset = 'UTF-8'; // ZenTaoPHP的编码。 The encoding of ZenTaoPHP.
$config->cookieLife = time() + 2592000; // Cookie的生存时间。The cookie life time.
+14 -10
View File
@@ -139,6 +139,7 @@ $filter->svn->cat = new stdclass();
$filter->svn->diff = new stdclass();
$filter->task->create = new stdclass();
$filter->task->export = new stdclass();
$filter->task->recordestimate = new stdclass();
$filter->execution->default = new stdclass();
$filter->execution->story = new stdclass();
$filter->testcase->default = new stdclass();
@@ -174,6 +175,7 @@ $filter->productplan->browse = new stdclass();
$filter->projectplan->browse = new stdclass();
$filter->kanban->space = new stdclass();
$filter->execution->kanban = new stdclass();
$filter->execution->all = new stdclass();
$filter->index->index->get['open'] = 'reg::base64';
@@ -300,17 +302,19 @@ $filter->story->track->cookie['preProductID'] = 'int';
$filter->productplan->browse->cookie['viewType'] = 'code';
$filter->projectplan->browse->cookie['viewType'] = 'code';
$filter->task->create->cookie['lastTaskModule'] = 'int';
$filter->task->export->cookie['checkedItem'] = 'reg::checked';
$filter->task->create->cookie['lastTaskModule'] = 'int';
$filter->task->export->cookie['checkedItem'] = 'reg::checked';
$filter->task->recordestimate->cookie['taskEffortFold'] = 'reg::checked';
$filter->execution->default->cookie['kanbanview'] = 'code';
$filter->execution->story->cookie['storyPreExecutionID'] = 'int';
$filter->execution->story->cookie['storyModuleParam'] = 'int';
$filter->execution->story->cookie['storyProductParam'] = 'int';
$filter->execution->story->cookie['storyBranchParam'] = 'int';
$filter->execution->story->cookie['executionStoryOrder'] = 'code';
$filter->execution->export->cookie['checkedItem'] = 'reg::checked';
$filter->execution->kanban->cookie['taskToOpen'] = 'int';
$filter->execution->default->cookie['kanbanview'] = 'code';
$filter->execution->story->cookie['storyPreExecutionID'] = 'int';
$filter->execution->story->cookie['storyModuleParam'] = 'int';
$filter->execution->story->cookie['storyProductParam'] = 'int';
$filter->execution->story->cookie['storyBranchParam'] = 'int';
$filter->execution->story->cookie['executionStoryOrder'] = 'code';
$filter->execution->export->cookie['checkedItem'] = 'reg::checked';
$filter->execution->kanban->cookie['taskToOpen'] = 'int';
$filter->execution->all->cookie['showExecutionBatchEdit'] = 'int';
$filter->testcase->browse->cookie['caseModule'] = 'int';
$filter->testcase->browse->cookie['caseSuite'] = 'int';
+3 -1
View File
@@ -216,6 +216,7 @@ $config->openMethods[] = 'kanban.importplan';
$config->openMethods[] = 'kanban.importrelease';
$config->openMethods[] = 'kanban.importexecution';
$config->openMethods[] = 'kanban.importbuild';
$config->openMethods[] = 'kanban.importticket';
$config->openMethods[] = 'kanban.activatecard';
$config->openMethods[] = 'kanban.finishcard';
$config->openMethods[] = 'kanban.deleteobjectcard';
@@ -225,6 +226,7 @@ $config->openMethods[] = 'tree.viewhistory';
$config->openMethods[] = 'doc.createbasicinfo';
$config->openMethods[] = 'project.createguide';
$config->openMethods[] = 'task.editteam';
$config->openMethods[] = 'feedback.mergeproductmodule';
/* Define the tables. */
define('TABLE_COMPANY', '`' . $config->db->prefix . 'company`');
@@ -403,4 +405,4 @@ $config->waterfallModules = array('workestimation', 'durationestimation', 'budge
$config->showMainMenu = true;
$config->maxPriValue = '256';
$config->importWhiteList = array('user', 'task', 'story', 'bug', 'testcase', 'feedback');
$config->importWhiteList = array('user', 'task', 'story', 'bug', 'testcase', 'feedback', 'ticket');
File diff suppressed because it is too large Load Diff
+68
View File
@@ -1,6 +1,74 @@
CREATE TABLE IF NOT EXISTS `zt_ticket` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL,
`module` mediumint(8) unsigned NOT NULL,
`title` varchar(255) NOT NULL,
`type` varchar(30) NOT NULL,
`desc` text NOT NULL,
`openedBuild` varchar(255) NOT NULL,
`feedback` mediumint(8) NOT NULL,
`assignedTo` varchar(255) NOT NULL,
`assignedDate` datetime NOT NULL,
`realStarted` datetime NOT NULL,
`startedBy` varchar(255) NOT NULL,
`startedDate` datetime NOT NULL,
`deadline` date NOT NULL,
`pri` tinyint unsigned NOT NULL DEFAULT '0',
`estimate` float unsigned NOT NULL,
`left` float unsigned NOT NULL,
`status` varchar(30) NOT NULL,
`openedBy` varchar(30) NOT NULL,
`openedDate` datetime NOT NULL,
`activatedCount` int(10) NOT NULL,
`activatedBy` varchar(30) NOT NULL,
`activatedDate` datetime NOT NULL,
`closedBy` varchar(30) NOT NULL,
`closedDate` datetime NOT NULL,
`closedReason` varchar(30) NOT NULL,
`finishedBy` varchar(30) NOT NULL,
`finishedDate` datetime NOT NULL,
`resolvedBy` varchar(30) NOT NULL,
`resolvedDate` datetime NOT NULL,
`resolution` varchar(1000) NOT NULL,
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
`keywords` varchar(255) NOT NULL,
`repeatTicket` mediumint(8) NOT NULL DEFAULT '0',
`mailto` varchar(255) NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
key `product` (`product`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `zt_ticketsource` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`ticketId` mediumint(8) unsigned NOT NULL,
`customer` varchar(100) NOT NULL,
`contact` varchar(100) NOT NULL,
`notifyEmail` varchar(100) NOT NULL,
`createdDate` datetime NOT NULL,
PRIMARY KEY (`id`),
key `ticketId` (`ticketId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `zt_ticketrelation` (
`id` mediumint unsigned NOT NULL AUTO_INCREMENT,
`ticketId` mediumint unsigned NOT NULL,
`objectId` mediumint NOT NULL,
`objectType` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
KEY `ticketId` (`ticketId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `zt_product` ADD `ticket` varchar(30) NOT NULL AFTER `feedback`;
ALTER TABLE `zt_kanban` ADD `colWidth` smallint(4) NOT NULL DEFAULT '264' AFTER `fluidBoard`;
ALTER TABLE `zt_kanban` ADD `minColWidth` smallint(4) NOT NULL DEFAULT '180' AFTER `colWidth`;
ALTER TABLE `zt_kanban` ADD `maxColWidth` smallint(4) NOT NULL DEFAULT '384' AFTER `minColWidth`;
ALTER TABLE `zt_project` ADD `colWidth` smallint(4) NOT NULL DEFAULT '264' AFTER `fluidBoard`;
ALTER TABLE `zt_project` ADD `minColWidth` smallint(4) NOT NULL DEFAULT '180' AFTER `colWidth`;
ALTER TABLE `zt_project` ADD `maxColWidth` smallint(4) NOT NULL DEFAULT '384' AFTER `minColWidth`;
REPLACE INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'common', 'global', 'syncProduct', '{"feedback":{},"ticket":{}}');
ALTER TABLE `zt_feedback` ADD `pri` tinyint unsigned NOT NULL DEFAULT 2 AFTER `desc`;
ALTER TABLE `zt_feedback` ADD `source` varchar(255) NOT NULL AFTER `notifyEmail`;
+74 -6
View File
@@ -835,9 +835,9 @@ CREATE TABLE IF NOT EXISTS `zt_kanban` (
`displayCards` smallint(6) NOT NULL default '0',
`showWIP` enum('0','1') NOT NULL DEFAULT '1',
`fluidBoard` enum('0','1') NOT NULL DEFAULT '0',
`colWidth` tinyint(3) NOT NULL DEFAULT '0',
`minColWidth` tinyint(3) NOT NULL DEFAULT '0',
`maxColWidth` tinyint(3) NOT NULL DEFAULT '0',
`colWidth` smallint(4) NOT NULL DEFAULT '264',
`minColWidth` smallint(4) NOT NULL DEFAULT '180',
`maxColWidth` smallint(4) NOT NULL DEFAULT '384',
`object` varchar(255) NOT NULL,
`alignment` varchar(10) NOT NULL default 'center',
`createdBy` char(30) NOT NULL,
@@ -1199,9 +1199,9 @@ CREATE TABLE IF NOT EXISTS `zt_project` (
`displayCards` smallint(6) NOT NULL default '0',
`fluidBoard` enum('0','1') NOT NULL DEFAULT '0',
`multiple` enum('0','1') NOT NULL DEFAULT '1',
`colWidth` tinyint(3) NOT NULL DEFAULT '0',
`minColWidth` tinyint(3) NOT NULL DEFAULT '0',
`maxColWidth` tinyint(3) NOT NULL DEFAULT '0',
`colWidth` smallint(4) NOT NULL DEFAULT '264',
`minColWidth` smallint(4) NOT NULL DEFAULT '180',
`maxColWidth` smallint(4) NOT NULL DEFAULT '384',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `parent` (`parent`),
@@ -6313,6 +6313,7 @@ INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'project', '', 'unitList', 'CNY,USD');
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'project', '', 'defaultCurrency', 'CNY');
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'story', '', 'reviewRules', 'allpass');
INSERT INTO `zt_config` (`owner`, `module`, `section`, `key`, `value`) VALUES ('system', 'common', 'global', 'syncProduct', '{"feedback":{},"ticket":{}}');
-- DROP TABLE IF EXISTS `zt_im_chat`;
CREATE TABLE IF NOT EXISTS `zt_im_chat` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
@@ -6336,6 +6337,7 @@ CREATE TABLE IF NOT EXISTS `zt_im_chat` (
`pinnedMessages` text NOT NULL DEFAULT '',
`mergedChats` text NOT NULL DEFAULT '',
`adminInvite` enum('0','1') NOT NULL DEFAULT '0',
`avatar` text NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `gid` (`gid`),
KEY `name` (`name`),
@@ -7099,11 +7101,13 @@ CREATE TABLE IF NOT EXISTS `zt_feedback` (
`type` char(30) NOT NULL,
`solution` char(30) NOT NULL,
`desc` text NOT NULL,
`pri` tinyint unsigned NOT NULL DEFAULT 2,
`status` varchar(30) NOT NULL,
`subStatus` varchar(30) NOT NULL default '',
`public` enum('0','1') NOT NULL DEFAULT '0',
`notify` enum('0','1') NOT NULL DEFAULT '0',
`notifyEmail` varchar(100) NOT NULL,
`source` varchar(255) NOT NULL,
`likes` text NOT NULL,
`result` mediumint(8) unsigned NOT NULL,
`faq` mediumint(8) unsigned NOT NULL,
@@ -7127,6 +7131,69 @@ CREATE TABLE IF NOT EXISTS `zt_feedback` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- DROP TABLE IF EXISTS `zt_ticket`;
CREATE TABLE IF NOT EXISTS `zt_ticket` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`product` mediumint(8) unsigned NOT NULL,
`module` mediumint(8) unsigned NOT NULL,
`title` varchar(255) NOT NULL,
`type` varchar(30) NOT NULL,
`desc` text NOT NULL,
`openedBuild` varchar(255) NOT NULL,
`feedback` mediumint(8) NOT NULL,
`assignedTo` varchar(255) NOT NULL,
`assignedDate` datetime NOT NULL,
`realStarted` datetime NOT NULL,
`startedBy` varchar(255) NOT NULL,
`startedDate` datetime NOT NULL,
`deadline` date NOT NULL,
`pri` tinyint unsigned NOT NULL DEFAULT '0',
`estimate` float unsigned NOT NULL,
`left` float unsigned NOT NULL,
`status` varchar(30) NOT NULL,
`openedBy` varchar(30) NOT NULL,
`openedDate` datetime NOT NULL,
`activatedCount` int(10) NOT NULL,
`activatedBy` varchar(30) NOT NULL,
`activatedDate` datetime NOT NULL,
`closedBy` varchar(30) NOT NULL,
`closedDate` datetime NOT NULL,
`closedReason` varchar(30) NOT NULL,
`finishedBy` varchar(30) NOT NULL,
`finishedDate` datetime NOT NULL,
`resolvedBy` varchar(30) NOT NULL,
`resolvedDate` datetime NOT NULL,
`resolution` varchar(1000) NOT NULL,
`editedBy` varchar(30) NOT NULL,
`editedDate` datetime NOT NULL,
`keywords` varchar(255) NOT NULL,
`repeatTicket` mediumint(8) NOT NULL DEFAULT '0',
`mailto` varchar(255) NOT NULL,
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
key `product` (`product`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `zt_ticketsource` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`ticketId` mediumint(8) unsigned NOT NULL,
`customer` varchar(100) NOT NULL,
`contact` varchar(100) NOT NULL,
`notifyEmail` varchar(100) NOT NULL,
`createdDate` datetime NOT NULL,
PRIMARY KEY (`id`),
key `ticketId` (`ticketId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `zt_ticketrelation` (
`id` mediumint unsigned NOT NULL AUTO_INCREMENT,
`ticketId` mediumint unsigned NOT NULL,
`objectId` mediumint NOT NULL,
`objectType` varchar(100) NOT NULL,
PRIMARY KEY (`id`),
KEY `ticketId` (`ticketId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `zt_bug` ADD `feedback` mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER `caseVersion`;
ALTER TABLE `zt_story` ADD `feedback` mediumint(8) unsigned NOT NULL DEFAULT '0' AFTER `fromBug`;
ALTER TABLE `zt_user` ADD `feedback` enum('0', '1') NOT NULL DEFAULT '0' AFTER `locked`;
@@ -7632,6 +7699,7 @@ ADD `grade` tinyint(3) unsigned NOT NULL DEFAULT '0' AFTER `path`,
ADD `order` smallint(5) unsigned NOT NULL DEFAULT '0' AFTER `grade`;
ALTER TABLE `zt_product` ADD `feedback` varchar(30) COLLATE 'utf8_general_ci' NOT NULL AFTER `RD`;
ALTER TABLE `zt_product` ADD `ticket` varchar(30) COLLATE 'utf8_general_ci' NOT NULL AFTER `feedback`;
ALTER TABLE `zt_leave` ADD `level` tinyint(3) NOT NULL;
ALTER TABLE `zt_leave` ADD `assignedTo` varchar(30) NOT NULL;
+190
View File
@@ -1,3 +1,193 @@
2022-10-19 17.7
完成的需求
开源版
32322 Bug批量导入页面中先校验必填字段再校验重复数据
37245 研发需求列表增加一键展开、收起功能
37259 列表左侧模块导航样式优化
37261 修改研发需求列表中字段的排列顺序
37266 研发需求列表中的操作按钮增加分组显示
37277 研发需求列表中层级关系的样式优化
37283 删除列表中的斑马纹背景
37513 研发需求列表替换ZUI3组件
37810 有父子层级的列表增加一键展开、收起功能
37811 列表中指派给字段的交互优化
37812 列表中负责人字段的样式优化
37813 列表中优先级颜色调整
37814 列表中父子层级的样式优化
37815 列表中级别颜色调整
37816 列表检索标签选中样式优化
37833 叶兰绿主题风格更新
37835 列表删除斑马纹背景
37841 研发需求列表中,操作列增加分组显示
37842 禅道蓝主题风格更新
37849 任务列表操作列增加分组显示
37854 bug列表确认字段的内容颜色调整
37857 bug列表的字段顺序调整
37858 用例检索标签增加分组显示
37861 用例列表操作列交换开始和结果按钮的位置
37862 项目集列表删除“显示已关闭”的勾选按钮
37863 项目集列表层级关系的展示
37864 项目集列表中延期标签位置调整
37865 项目集列表中预算字段增加超出提示
37866 项目集列表中项目集的内容样式优化
37868 项目集列表操作列的更多按钮调整
37869 删除项目集列表中项目的图标
37975 项目列表字段顺序调整
37976 项目列表操作列更多按钮样式优化
37977 项目列表批量编辑项目功能增加打开按钮
37978 产品列表的批量编辑功能增加打开按钮
37979 产品列表层级关系的样式优化
37980 产品列表新增负责人字段
37982 产品列表删除用户需求字段
37983 产品列表删除bug关闭字段
37984 产品列表下方增加统计信息
37985 产品列表页面中,修改产品线的按钮样式优化
37986 产品列表的字段顺序调整
37989 计划列表操作列增加分组显示
37990 计划列表下方增加数据的统计信息
37992 创建多人任务时,工时填写不大于0时增加提示语
37993 工时记录页,日期、工作内容、消耗、剩余增加必填项校验
37994 工时记录页,日期的icon点击后也展开日期框
37997 多人串行任务,用户打开工时填写页,默认打开我的日志页
37998 多人串行任务中工时记录页,日志默认按照工序排列
37999 工时记录页,日期列和工序列增加排序按钮
38001 工时记录页样式优化
38002 多人串行任务中,团队日志页去掉操作区域
38006 多人串行任务开始任务的弹窗,总计消耗改名为我的总消耗
38008 列表中名称字段样式优化
38010 产品列表名称字段内容样式优化
38011 团队的填写工时页面ui优化
38167 计划列表执行字段展示信息优化
38186 项目列表删除类型标签,鼠标悬停显示
38227 产品列表删除产品名称前的图标
38240 项目集列表中,鼠标悬停到项目名称时支持显示项目类型
38241 项目和执行列表中延期标签位置调整
38280 产品计划列表中对父子计划展开和收起的状态做记录
38282 看板全屏时,颜色调整
38283 执行列表中字段顺序调整
38285 执行列表下方增加统计信息
38286 执行列表默认显示字段删除执行代号
38288 执行列表中预计、消耗、剩余字段表头和内容居右对齐
38290 地盘项目列表字段顺序调整
38291 修改地盘执行中“未结束”的检索标签为“未完成”
38292 地盘执行列表字段顺序调整
38293 地盘执行列表中工时/天居右显示
38297 地盘待处理的用例列表中,调整优先级字段的位置
38299 测试单列表中字段调整
38300 执行列表中批量编辑增加开关
38302 地盘待处理的测试单列表字段顺序调整
38303 测试单列表下方增加统计信息
38305 地盘待办列表字段顺序调整
38306 地盘待办列表增加统计信息
38307 发布列表中字段顺序调整
38308 发布列表下方增加统计信息
38311 用例列表字段顺序调整
38313 地盘测试单列表字段顺序调整
38315 地盘贡献中的文档列表增加最后更新者字段
38316 瀑布项目的设计列表字段调整
38348 项目集的可访问人员列表中字段顺序调整
38354 执行任务列表字段顺序调整
38355 列表中父子层级关系的样式优化
38375 看板列宽设置的功能优化
38385 测试套件列表下方增加统计信息
38393 地盘中的任务列表字段顺序调整
38395 地盘贡献的任务列表字段顺序调整
38396 地盘待处理的研发需求列表字段调整
38397 地盘待处理的用户需求列表字段调整
38398 地盘待处理的bug列表的字段顺序调整
38423 调整计划需求列表勾选后的统计内容
38428 列表中数据延期的样式调整
38430 项目列表下方增加统计信息
38431 产品项目列表增加分页栏的显示
38493 编辑任务时,团队维护的弹窗风格调整
38533 地盘执行列表中我的任务居中显示
38545 会议创建表单中,参会人员的下拉菜单修改为批量选择的组件
38629 项目发布列表增加分页功能
38736 版本列表中字段顺序调整
38778 创建项目时,访问控制默认勾选公开
企业版:
37608 反馈模块增加1.5级产品导航
38764 无产品瀑布项目设计功能去掉产品相关信息
38644 反馈的优先级自定义
37605 反馈创建增加来源公司和优先级字段
37601 反馈分类支持同步单个产品的所属产品模块
37597 反馈模块同步产品模块后,可以创建反馈自己的模块
37478 实现工单列表的产品模块功能
37473 在反馈视图的二级菜单里打印工单菜单
37474 实现工单的添加功能
37475 实现工单的编辑功能
37476 实现工单的详情查看功能
37477 实现工单的列表页面
37480 实现工单的所有检索标签
37481 实现工单的待关闭检索标签
37482 实现工单的指派给的标签
37483 实现工单的由我解决的检索标签
37484 实现工单的由我创建的检索标签
37485 在工单的列表页面打印操作菜单
37486 在工单的详情页面打印操作按钮
37487 实现工单的指派功能
37488 实现工单的完成功能
37489 实现工单的激活功能
37490 实现工单的关闭功能
37491 实现工单的开始操作
37494 提交工单中影响版本的取值逻辑
37495 实现从工单提需求的功能
37498 实现从反馈创建工单的功能
37554 实现反馈工单默认指派给的逻辑
37555 实现反馈类型与工单类型的自定义
37558 工单的优先级自定义
37568 实现工单的权限
37609 地盘待处理与待处理区块的反馈后增加工单数据
37610 日志中增加工单日志
37650 通用看板支持导入工单
37823 实现工单的批量编辑功能
37824 列表增加批量完成
37825 列表增加批量激活
37826 列表增加批量指派
37995 实现工单列表搜索功能
37996 实现工单的等待与处理中检索标签
38198 实现工单的删除功能
38199 实现工单的日志功能
38487 实现工单相关动态的查看权限的设置
38789 所属产品删除对工单的影响
旗舰版:
38673 地盘问题列表的字段顺序调整
38676 指派给我检索标签下的问题列表中,指派给字段修改为由谁指派
38680 地盘待处理的问题列表中删除指派给字段
38687 地盘日志列表字段顺序调整
38692 风险列表中字段顺序调整
38694 风险列表中操作列按钮增加分组显示
38695 问题列表中操作列按钮增加分组显示
38728 QA不符合项列表的字段顺序调整
38729 地盘QA列表中字段顺序调整
38730 会议列表字段顺序调整
38738 需求库中的需求列表字段顺序调整
38739 用例库中的用例列表字段顺序调整
38741 问题库中的问题列表字段顺序调整
38743 风险库中的风险列表字段顺序调整
38745 机会库中的机会列表字段顺序调整
38746 资产库中的审批字段居左对齐
禅道客户端:
36365 提供修改讨论组图标功能,支持设置图标的背景颜色及填充文字。
36366 支持上传讨论组图标,提供图标裁剪、预览功能。
36622 提升首次登录喧喧历史消息的加载速度。
22468 实现文件重传入口,未完成传输的文件可以一键重传。
36879 实现搜索人员时可以显示其当前状态的功能。
37105 实现管理员删除用户时同步从群组中移除该用户的功能。
36928 优化会话中图片预览缩放功能。
36931 优化启动喧喧时音视频初检频次。
36932 优化忽略会议时会话列表中图标的干扰。
修复的Bug
26082 修复了初始化会议时,可能展示会议窗口或进行通知的问题。
27458 修复了加入或转让讨论组时,未读消息数目不正确的问题。
23066 修复安装xxb设置管理员保存后报错的问题。
23067 修复安装xxb成功时页面报错的问题。
27311 修复了客户端打开链接时会出错的问题。
26801 修复消息输入框内的图片无法另存的问题。
26805 修复了合并会话不生效的问题。
26106 修复下载失败的图片没有重新下载的按钮的问题。
26453 修复了回复通知类消息时,所引用的消息的发送者名称展示错误的问题。
2022-09-23 17.6.2
完成的需求
开源版:
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

+1 -1
View File
@@ -291,7 +291,7 @@
</tbody>
<tfoot>
<tr>
<td colspan='3' class='text-center'><?php echo html::a('javascript:void(0)', $lang->confirm, '', "class='btn btn-primary'");?></td>
<td colspan='4' class='text-center'><?php echo html::a('javascript:void(0)', $lang->confirm, '', "class='btn btn-primary'");?></td>
</tr>
</tfoot>
</table>
+2
View File
@@ -18,6 +18,8 @@ class entry extends baseEntry
{
parent::__construct();
if($this->app->action == 'options') return $this->send(204);
if(!isset($this->app->user) or $this->app->user->account == 'guest') $this->sendError(401, 'Unauthorized');
$this->dao = $this->loadModel('common')->dao;
+2 -2
View File
@@ -1004,6 +1004,7 @@ class baseRouter
array($ztSessionHandler, "destroy"),
array($ztSessionHandler, "gc")
);
register_shutdown_function('session_write_close');
}
}
@@ -1014,7 +1015,7 @@ class baseRouter
session_name($sessionName);
session_set_cookie_params(0, $this->config->webRoot, '', $this->config->cookieSecure, true);
if($this->config->customSession) session_save_path($this->getTmpRoot() . 'session');
session_start();
if(!session_id()) session_start();
$this->sessionID = isset($ztSessionHandler) ? $ztSessionHandler->getSessionID() : session_id();
@@ -3167,7 +3168,6 @@ class ztSessionHandler
{
$this->tagID = $tagID;
ini_set('session.save_handler', 'files');
register_shutdown_function('session_write_close');
}
/**
+2 -2
View File
@@ -521,8 +521,8 @@ class baseHTML
/* If the link of the referer is not the link of the current page or the link of the index, the cookie and gobackLink will be updated. */
if(!preg_match("/(m=|\/)(index|search|$currentModule)(&f=|-)(index|buildquery|$currentMethod)(&|-|\.)?/", strtolower($refererLink)))
{
$gobackList[$tab] = $referer;
$gobackLink = $referer;
$gobackList[$tab] = $referer . "#app=$tab";
$gobackLink = $referer . "#app=$tab";
setcookie('goback', json_encode($gobackList), $config->cookieLife, $config->webRoot, '', $config->cookieSecure, false);
}
+3
View File
@@ -215,6 +215,7 @@ $lang->action->desc->importedproductplan = '$date, imported to <strong>$extra</
$lang->action->desc->importedrelease = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedexecution = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedbuild = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedticket = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->fromsonarqube = '$date, created by <strong>$actor</strong> from <strong>SonarQube Issue</strong>.' . "\n";
$lang->action->desc->tolib = '$date, imported by <strong>$actor</strong> .' . "\n";
$lang->action->desc->updatetolib = '$date, updated to ' . $lang->testcase->common . ' by <strong>$actor</strong>.' . "\n";
@@ -381,6 +382,7 @@ $lang->action->label->importedproductplan = 'imported';
$lang->action->label->importedrelease = 'imported';
$lang->action->label->importedexecution = 'imported';
$lang->action->label->importedbuild = 'imported';
$lang->action->label->importedticket = 'imported';
$lang->action->label->fromsonarqube = 'created a bug from SonarQube Issue named:';
$lang->action->label->bind = 'bound';
$lang->action->label->unbind = 'unbound';
@@ -717,6 +719,7 @@ $lang->action->label->mr = 'Merge Request|mr|view|id=%s';
$lang->action->label->gitlab = 'GitLab Server|gitlab|view|id=%s';
$lang->action->label->stage = 'Stage|stage|browse|';
$lang->action->label->module = 'Module|tree|browse|productid=%s&type=story&currentModuleID=0&branch=all';
$lang->action->label->ticket = 'Ticket|ticket|view|id=%s';
/* Object type. */
$lang->action->search = new stdclass();
+3
View File
@@ -215,6 +215,7 @@ $lang->action->desc->importedproductplan = '$date, imported to <strong>$extra</
$lang->action->desc->importedrelease = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedexecution = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedbuild = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedticket = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->fromsonarqube = '$date, created by <strong>$actor</strong> from <strong>SonarQube Issue</strong>.' . "\n";
$lang->action->desc->tolib = '$date, imported by <strong>$actor</strong> .' . "\n";
$lang->action->desc->updatetolib = '$date, updated to ' . $lang->testcase->common . ' by <strong>$actor</strong>.' . "\n";
@@ -381,6 +382,7 @@ $lang->action->label->importedproductplan = 'imported';
$lang->action->label->importedrelease = 'imported';
$lang->action->label->importedexecution = 'imported';
$lang->action->label->importedbuild = 'imported';
$lang->action->label->importedticket = 'imported';
$lang->action->label->fromsonarqube = 'created a bug from SonarQube Issue named:';
$lang->action->label->bind = 'bound';
$lang->action->label->unbind = 'unbound';
@@ -717,6 +719,7 @@ $lang->action->label->mr = 'Merge Request|mr|view|id=%s';
$lang->action->label->gitlab = 'GitLab Server|gitlab|view|id=%s';
$lang->action->label->stage = 'Stage|stage|browse|';
$lang->action->label->module = 'Module|tree|browse|productid=%s&type=story&currentModuleID=0&branch=all';
$lang->action->label->ticket = 'Ticket|ticket|view|id=%s';
/* Object type. */
$lang->action->search = new stdclass();
+3
View File
@@ -215,6 +215,7 @@ $lang->action->desc->importedproductplan = '$date, imported to <strong>$extra</
$lang->action->desc->importedrelease = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedexecution = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedbuild = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->importedticket = '$date, imported to <strong>$extra</strong> by <strong>$actor</strong>.' . "\n";
$lang->action->desc->fromsonarqube = '$date, created by <strong>$actor</strong> from <strong>SonarQube Issue</strong>.' . "\n";
$lang->action->desc->tolib = '$date, Importé par <strong>$actor</strong> .' . "\n";
$lang->action->desc->updatetolib = '$date, MàJ de ' . $lang->testcase->common . ' par <strong>$actor</strong>.' . "\n";
@@ -381,6 +382,7 @@ $lang->action->label->importedproductplan = 'imported';
$lang->action->label->importedrelease = 'imported';
$lang->action->label->importedexecution = 'imported';
$lang->action->label->importedbuild = 'imported';
$lang->action->label->importedticket = 'imported';
$lang->action->label->fromsonarqube = 'created a bug from SonarQube Issue named:';
$lang->action->label->bind = 'bound';
$lang->action->label->unbind = 'unbound';
@@ -717,6 +719,7 @@ $lang->action->label->mr = 'Merge Request|mr|view|id=%s';
$lang->action->label->gitlab = 'GitLab Server|gitlab|view|id=%s';
$lang->action->label->stage = 'Stage|stage|browse|';
$lang->action->label->module = 'Module|tree|browse|productid=%s&type=story&currentModuleID=0&branch=all';
$lang->action->label->ticket = 'Ticket|ticket|view|id=%s';
/* Object type. */
$lang->action->search = new stdclass();
+58 -55
View File
@@ -215,6 +215,7 @@ $lang->action->desc->importedproductplan = '$date, 由 <strong>$actor</strong>
$lang->action->desc->importedrelease = '$date, 由 <strong>$actor</strong> 从产品发布 <strong>$extra</strong> 导入。' . "\n";
$lang->action->desc->importedexecution = '$date, 由 <strong>$actor</strong> 从项目执行 <strong>$extra</strong> 导入。' . "\n";
$lang->action->desc->importedbuild = '$date, 由 <strong>$actor</strong> 从项目版本 <strong>$extra</strong> 导入。' . "\n";
$lang->action->desc->importedticket = '$date, 由 <strong>$actor</strong> 从反馈工单 <strong>$extra</strong> 导入。' . "\n";
$lang->action->desc->fromsonarqube = '$date, 由 <strong>$actor</strong> 从<strong>SonarQube问题</strong>转化而来。' . "\n";
$lang->action->desc->tolib = '$date, 由 <strong>$actor</strong> 导入。' . "\n";
$lang->action->desc->updatetolib = '$date, 由 <strong>$actor</strong> 从' . $lang->testcase->common . '更新。' . "\n";
@@ -254,20 +255,20 @@ $lang->action->desc->unlinkbug = '$date, 由 <strong>$actor</strong> 从计划
/* 用来显示动态信息。*/
$lang->action->label = new stdclass();
$lang->action->label->install = '安装';
$lang->action->label->revert = '还原';
$lang->action->label->created = '创建';
$lang->action->label->opened = '创建';
$lang->action->label->openedbysystem = '系统创建';
$lang->action->label->closedbysystem = '系统关闭';
$lang->action->label->added = '添加';
$lang->action->label->install = '安装了';
$lang->action->label->revert = '还原了';
$lang->action->label->created = '创建了';
$lang->action->label->opened = '创建了';
$lang->action->label->openedbysystem = '系统创建了';
$lang->action->label->closedbysystem = '系统关闭了';
$lang->action->label->added = '添加了';
$lang->action->label->changed = '变更了';
$lang->action->label->edited = '编辑了';
$lang->action->label->assigned = '指派了';
$lang->action->label->closed = '关闭了';
$lang->action->label->deleted = '删除了';
$lang->action->label->deletedfile = '删除附件';
$lang->action->label->editfile = '编辑附件';
$lang->action->label->deletedfile = '删除了附件';
$lang->action->label->editfile = '编辑了附件';
$lang->action->label->erased = '删除了';
$lang->action->label->undeleted = '还原了';
$lang->action->label->hidden = '隐藏了';
@@ -277,30 +278,30 @@ $lang->action->label->activated = '激活了';
$lang->action->label->blocked = '阻塞了';
$lang->action->label->resolved = '解决了';
$lang->action->label->reviewed = '评审了';
$lang->action->label->recalled = '撤销评审';
$lang->action->label->recalledchange = '撤销变更';
$lang->action->label->recalled = '撤销了评审';
$lang->action->label->recalledchange = '撤销了变更';
$lang->action->label->moved = '移动了';
$lang->action->label->confirmed = "确认了{$lang->SRCommon}";
$lang->action->label->bugconfirmed = '确认了';
$lang->action->label->tostory = "转{$lang->SRCommon}";
$lang->action->label->frombug = "转{$lang->SRCommon}";
$lang->action->label->tostory = "转了{$lang->SRCommon}";
$lang->action->label->frombug = "转了{$lang->SRCommon}";
$lang->action->label->fromlib = '从用例库导入';
$lang->action->label->totask = '转任务';
$lang->action->label->converttotask = '转任务';
$lang->action->label->svncommited = '提交代码';
$lang->action->label->gitcommited = '提交代码';
$lang->action->label->linked2plan = "关联计划";
$lang->action->label->unlinkedfromplan = "移除计划";
$lang->action->label->changestatus = '修改状态';
$lang->action->label->totask = '转了任务';
$lang->action->label->converttotask = '转了任务';
$lang->action->label->svncommited = '提交了代码';
$lang->action->label->gitcommited = '提交了代码';
$lang->action->label->linked2plan = "关联了计划";
$lang->action->label->unlinkedfromplan = "移除了计划";
$lang->action->label->changestatus = '修改了状态';
$lang->action->label->marked = '编辑了';
$lang->action->label->linked2execution = "关联{$lang->executionCommon}";
$lang->action->label->unlinkedfromexecution = "移除{$lang->executionCommon}";
$lang->action->label->linked2kanban = '关联看板';
$lang->action->label->linked2project = "关联项目";
$lang->action->label->unlinkedfromproject = "移除项目";
$lang->action->label->unlinkedfrombuild = "移除版本";
$lang->action->label->linked2release = "关联发布";
$lang->action->label->unlinkedfromrelease = "移除发布";
$lang->action->label->linked2execution = "关联了{$lang->executionCommon}";
$lang->action->label->unlinkedfromexecution = "移除了{$lang->executionCommon}";
$lang->action->label->linked2kanban = '关联了看板';
$lang->action->label->linked2project = "关联了项目";
$lang->action->label->unlinkedfromproject = "移除了项目";
$lang->action->label->unlinkedfrombuild = "移除了版本";
$lang->action->label->linked2release = "关联了发布";
$lang->action->label->unlinkedfromrelease = "移除了发布";
$lang->action->label->linkrelatedbug = "关联了相关Bug";
$lang->action->label->unlinkrelatedbug = "移除了相关Bug";
$lang->action->label->linkrelatedcase = "关联了相关用例";
@@ -317,8 +318,8 @@ $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->delayed = '延期了';
$lang->action->label->suspended = '挂起了';
$lang->action->label->login = '登录系统';
$lang->action->label->logout = "退出登录";
$lang->action->label->notified = "通知了";
@@ -327,31 +328,31 @@ $lang->action->label->linked2build = "关联了";
$lang->action->label->linked2bug = "关联了";
$lang->action->label->linked2testtask = "关联了";
$lang->action->label->unlinkedfromtesttask = "移除了";
$lang->action->label->linkchildtask = "关联子任务";
$lang->action->label->unlinkchildrentask = "取消关联子任务";
$lang->action->label->linkparenttask = "关联到父任务";
$lang->action->label->unlinkparenttask = "从父任务取消关联";
$lang->action->label->batchcreate = "批量创建任务";
$lang->action->label->createchildren = "创建子任务";
$lang->action->label->managed = "维护";
$lang->action->label->linkchildtask = "关联了子任务";
$lang->action->label->unlinkchildrentask = "取消关联了子任务";
$lang->action->label->linkparenttask = "关联到了父任务";
$lang->action->label->unlinkparenttask = "从父任务取消关联了";
$lang->action->label->batchcreate = "批量创建了任务";
$lang->action->label->createchildren = "创建了子任务";
$lang->action->label->managed = "维护了";
$lang->action->label->managedteam = "维护了";
$lang->action->label->managedwhitelist = "维护了";
$lang->action->label->deletechildrentask = "删除子任务";
$lang->action->label->createchildrenstory = "创建子需求";
$lang->action->label->linkchildstory = "关联子需求";
$lang->action->label->unlinkchildrenstory = "取消关联子需求";
$lang->action->label->linkparentstory = "关联到父需求";
$lang->action->label->unlinkparentstory = "从父需求取消关联";
$lang->action->label->deletechildrenstory = "删除子需求";
$lang->action->label->deletechildrentask = "删除了子任务";
$lang->action->label->createchildrenstory = "创建了子需求";
$lang->action->label->linkchildstory = "关联了子需求";
$lang->action->label->unlinkchildrenstory = "取消关联了子需求";
$lang->action->label->linkparentstory = "关联到了父需求";
$lang->action->label->unlinkparentstory = "从父需求取消关联了";
$lang->action->label->deletechildrenstory = "删除了子需求";
$lang->action->label->tracked = '跟踪了';
$lang->action->label->hangup = '挂起了';
$lang->action->label->run = '执行了';
$lang->action->label->estimated = '估算了';
$lang->action->label->reviewpassed = '确认通过';
$lang->action->label->reviewrejected = '拒绝';
$lang->action->label->reviewpassed = '确认了通过';
$lang->action->label->reviewrejected = '拒绝了';
$lang->action->label->reviewclarified = '有待明确';
$lang->action->label->commitsummary = '提交培训总结';
$lang->action->label->updatetrainee = '更新培训人员';
$lang->action->label->commitsummary = '提交了培训总结';
$lang->action->label->updatetrainee = '更新了培训人员';
$lang->action->label->setdefaultbranch = '设置了默认分支';
$lang->action->label->syncprogram = '开始了';
$lang->action->label->syncproject = '开始了';
@@ -363,13 +364,13 @@ $lang->action->label->deletemr = '合并请求取消了';
$lang->action->label->mergedmr = '合并请求合并了';
$lang->action->label->compilepass = '构建成功';
$lang->action->label->compilefail = '构建失败';
$lang->action->label->reopen = '重新打开';
$lang->action->label->reopen = '重新打开了';
$lang->action->label->approve = '通过了';
$lang->action->label->reject = '拒绝了';
$lang->action->label->importfromgitlab = '从Gitlab关联创建了';
$lang->action->label->archived = '归档了';
$lang->action->label->restore = '还原了';
$lang->action->label->mergedbranch = '合并分支';
$lang->action->label->mergedbranch = '合并了分支';
$lang->action->label->startedbychild = '开始了';
$lang->action->label->finishedbychild = '完成了';
$lang->action->label->closedbychild = '关闭了';
@@ -381,13 +382,14 @@ $lang->action->label->importedproductplan = '导入了';
$lang->action->label->importedrelease = '导入了';
$lang->action->label->importedexecution = '导入了';
$lang->action->label->importedbuild = '导入了';
$lang->action->label->fromsonarqube = '由SonarQube问题创建';
$lang->action->label->importedticket = '导入了';
$lang->action->label->fromsonarqube = '由SonarQube问题创建了';
$lang->action->label->bind = '绑定了';
$lang->action->label->unbind = '取消绑定了';
$lang->action->label->linkstory = '关联需求到';
$lang->action->label->linkbug = '关联BUG到';
$lang->action->label->unlinkstory = '移除需求从';
$lang->action->label->unlinkbug = '移除BUG从';
$lang->action->label->linkstory = '关联需求到了';
$lang->action->label->linkbug = '关联BUG到了';
$lang->action->label->unlinkstory = '移除了需求从';
$lang->action->label->unlinkbug = '移除了BUG从';
$lang->action->label->tolib = '导入了';
$lang->action->label->updatetolib = '更新了';
$lang->action->label->ganttmove = '排序了';
@@ -717,6 +719,7 @@ $lang->action->label->mr = '合并请求|mr|view|id=%s';
$lang->action->label->gitlab = 'GitLab服务器|gitlab|view|id=%s';
$lang->action->label->stage = '瀑布模型的阶段|stage|browse|';
$lang->action->label->module = '模块|tree|browse|productid=%s&type=story&currentModuleID=0&branch=all';
$lang->action->label->ticket = '工单|ticket|view|id=%s';
/* Object type. */
$lang->action->search = new stdclass();
+2 -2
View File
@@ -575,7 +575,7 @@ class actionModel extends model
if($history->field == 'git') $history->diff = str_replace('+', '%2B', $history->diff);
}
}
elseif($actionName == 'linkstory' or $actionName == 'unlinkstory')
elseif(strpos('linkstory,unlinkstory,createchildrenstory', $actionName) !== false)
{
$extra = '';
foreach(explode(',', $action->extra) as $id) $extra .= common::hasPriv('story', 'view') ? html::a(helper::createLink('story', 'view', "storyID=$id"), "#$id ") . ', ' : "#$id, ";
@@ -1280,7 +1280,7 @@ class actionModel extends model
{
$objectType = str_replace('imported', '', $action->action);
$objectTable = zget($this->config->objectTables, $objectType);
$objectName = $objectType == 'productplan' ? 'title' : 'name';
$objectName = ($objectType == 'productplan' or $objectType == 'ticket') ? 'title' : 'name';
$action->objectName = $this->dao->select($objectName)->from($objectTable)->where('id')->eq($action->extra)->fetch($objectName);
}
elseif($action->objectType == 'module' and !empty($action->extra) and $action->action != 'deleted')
+3 -1
View File
@@ -787,7 +787,9 @@ EOT;
*/
public function debug($filePath, $action)
{
$filePath = helper::safe64Decode($filePath);
$filePath = helper::safe64Decode($filePath);
$fileDirPath = realpath(dirname($filePath));
if(strpos($fileDirPath, $this->app->getModuleRoot()) !== 0 and strpos($fileDirPath, $this->app->getExtensionRoot()) !== 0) return;
if($action == 'extendModel')
{
$method = $this->api->getMethod($filePath, 'Model');
+11 -6
View File
@@ -488,7 +488,8 @@ class block extends control
return true;
}
$blocks = json_decode($blocks, true);
$blocks = json_decode($blocks, true);
if(empty($blocks)) $blocks = array();
$blockPairs = array('' => '') + $blocks;
echo '<div class="form-group">';
@@ -1766,6 +1767,7 @@ class block extends control
if(common::hasPriv('issue', 'view') and $this->config->edition == 'max' and $this->config->vision != 'lite' && $hasIssue) $hasViewPriv['issue'] = true;
if(common::hasPriv('meeting', 'view') and $this->config->edition == 'max' and $this->config->vision != 'lite' && $hasMeeting) $hasViewPriv['meeting'] = true;
if(common::hasPriv('feedback', 'view') and in_array($this->config->edition, array('max', 'biz'))) $hasViewPriv['feedback'] = true;
if(common::hasPriv('ticket', 'view') and in_array($this->config->edition, array('max', 'biz'))) $hasViewPriv['ticket'] = true;
$params = $this->get->param;
$params = json_decode(base64_decode($params));
@@ -1786,14 +1788,14 @@ class block extends control
$objectCountList += array('issue' => 'issueCount');
}
$objectList += array('feedback' => 'feedbacks');
$objectCountList += array('feedback' => 'feedbackCount');
$objectList += array('feedback' => 'feedbacks', 'ticket' => 'tickets');
$objectCountList += array('feedback' => 'feedbackCount', 'ticket' => 'ticketCount');
}
if($this->config->edition == 'biz')
{
$objectList += array('feedback' => 'feedbacks');
$objectCountList += array('feedback' => 'feedbackCount');
$objectList += array('feedback' => 'feedbacks', 'ticket' => 'tickets');
$objectCountList += array('feedback' => 'feedbackCount', 'ticket' => 'ticketCount');
}
$tasks = $this->loadModel('task')->getUserSuspendedTasks($this->app->user->account);
@@ -1809,6 +1811,7 @@ class block extends control
->beginIF($objectType == 'bug')->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id')->fi()
->beginIF($objectType == 'task')->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.execution=t2.id')->fi()
->beginIF($objectType == 'issue' or $objectType == 'risk')->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project=t2.id')->fi()
->beginIF($objectType == 'ticket')->leftJoin(TABLE_USER)->alias('t2')->on('t1.openedBy = t2.account')->fi()
->where('t1.deleted')->eq(0)
->andWhere('t1.assignedTo')->eq($this->app->user->account)->fi()
->beginIF($objectType == 'story')->andWhere('t1.type')->eq('story')->andWhere('t2.deleted')->eq('0')->fi()
@@ -1819,6 +1822,7 @@ class block extends control
->beginIF($objectType != 'todo')->andWhere('t1.status')->ne('closed')->fi()
->beginIF($objectType == 'feedback')->andWhere('t1.status')->in('wait, noreview')->fi()
->beginIF($objectType == 'issue' or $objectType == 'risk')->andWhere('t2.deleted')->eq(0)->fi()
->beginIF($objectType == 'ticket')->andWhere('t1.status')->in('wait,doing,done')->fi()
->orderBy($orderBy)
->beginIF($limitCount)->limit($limitCount)->fi()
->fetchAll();
@@ -1863,9 +1867,10 @@ class block extends control
if($objectType == 'risk') $this->app->loadLang('risk');
if($objectType == 'issue') $this->app->loadLang('issue');
if($objectType == 'feedback')
if($objectType == 'feedback' or $objectType == 'ticket')
{
$this->app->loadLang('feedback');
$this->app->loadLang('ticket');
$this->view->users = $this->loadModel('user')->getPairs('all,noletter');
$this->view->products = $this->dao->select('id, name')->from(TABLE_PRODUCT)->where('deleted')->eq('0')->fetchPairs('id', 'name');
}
+4 -2
View File
@@ -94,8 +94,8 @@ $lang->block->remove = 'Entfernen';
$lang->block->refresh = 'Aktualisieren';
$lang->block->nbsp = '';
$lang->block->hidden = 'Verstecken';
$lang->block->dynamicInfo = "<span class='timeline-tag'>%s</span> <span class='timeline-text'>%s<em class='label-action'>%s</em>%s<a href='%s' title='%s'>%s</a></span>";
$lang->block->noLinkDynamic = "<span class='timeline-tag'>%s</span> <span class='timeline-text' title='%s'>%s<em class='label-action'>%s</em>%s<span class='label-name'>%s</span></span>";
$lang->block->dynamicInfo = "<span class='timeline-tag'>%s</span> <span class='timeline-text'>%s<span class='label-action'>%s</span>%s<a href='%s' title='%s'>%s</a></span>";
$lang->block->noLinkDynamic = "<span class='timeline-tag'>%s</span> <span class='timeline-text' title='%s'>%s<span class='label-action'>%s</span>%s<span class='label-name'>%s</span></span>";
$lang->block->cannotPlaceInLeft = 'Kann den Block nicht auf der linken Seite platzieren.';
$lang->block->cannotPlaceInRight = 'Kann den Block nicht auf der rechten Seite platzieren.';
@@ -349,6 +349,7 @@ $lang->block->availableBlocks->risk = 'My Risks';
$lang->block->availableBlocks->issue = 'My Issues';
$lang->block->availableBlocks->meeting = 'My Meetings';
$lang->block->availableBlocks->feedback = 'My Feedbacks';
$lang->block->availableBlocks->ticket = 'Ticket';
$lang->block->moduleList['product'] = $lang->productCommon;
$lang->block->moduleList['project'] = 'Project';
@@ -470,6 +471,7 @@ $lang->block->storyCount = 'Stories';
$lang->block->reviewCount = 'Reviews';
$lang->block->meetingCount = 'Meetings';
$lang->block->feedbackCount = 'Feedbacks';
$lang->block->ticketCount = 'Tickets';
$lang->block->typeList = new stdclass();
+4 -2
View File
@@ -94,8 +94,8 @@ $lang->block->remove = 'Remove';
$lang->block->refresh = 'Refresh';
$lang->block->nbsp = ' ';
$lang->block->hidden = 'Hide';
$lang->block->dynamicInfo = "<span class='timeline-tag'>%s</span> <span class='timeline-text'>%s<em class='label-action'>%s</em>%s<a href='%s' title='%s'>%s</a></span>";
$lang->block->noLinkDynamic = "<span class='timeline-tag'>%s</span> <span class='timeline-text' title='%s'>%s<em class='label-action'>%s</em>%s<span class='label-name'>%s</span></span>";
$lang->block->dynamicInfo = "<span class='timeline-tag'>%s</span> <span class='timeline-text'>%s<span class='label-action'>%s</span>%s<a href='%s' title='%s'>%s</a></span>";
$lang->block->noLinkDynamic = "<span class='timeline-tag'>%s</span> <span class='timeline-text' title='%s'>%s<span class='label-action'>%s</span>%s<span class='label-name'>%s</span></span>";
$lang->block->cannotPlaceInLeft = 'Cannot place the block at left side.';
$lang->block->cannotPlaceInRight = 'Cannot place the block at right side.';
@@ -349,6 +349,7 @@ $lang->block->availableBlocks->risk = 'Risks';
$lang->block->availableBlocks->issue = 'Issues';
$lang->block->availableBlocks->meeting = 'Meetings';
$lang->block->availableBlocks->feedback = 'My Feedbacks';
$lang->block->availableBlocks->ticket = 'Ticket';
$lang->block->moduleList['product'] = $lang->productCommon;
$lang->block->moduleList['project'] = 'Project';
@@ -470,6 +471,7 @@ $lang->block->storyCount = 'Stories';
$lang->block->reviewCount = 'Reviews';
$lang->block->meetingCount = 'Meetings';
$lang->block->feedbackCount = 'Feedbacks';
$lang->block->ticketCount = 'Tickets';
$lang->block->typeList = new stdclass();
+4 -2
View File
@@ -94,8 +94,8 @@ $lang->block->remove = 'Supprimer';
$lang->block->refresh = 'Rafraichir';
$lang->block->nbsp = ' ';
$lang->block->hidden = 'Masquer';
$lang->block->dynamicInfo = "<span class='timeline-tag'>%s</span> <span class='timeline-text'>%s<em class='label-action'>%s</em>%s<a href='%s' title='%s'>%s</a></span>";
$lang->block->noLinkDynamic = "<span class='timeline-tag'>%s</span> <span class='timeline-text' title='%s'>%s<em class='label-action'>%s</em>%s<span class='label-name'>%s</span></span>";
$lang->block->dynamicInfo = "<span class='timeline-tag'>%s</span> <span class='timeline-text'>%s<span class='label-action'>%s</span>%s<a href='%s' title='%s'>%s</a></span>";
$lang->block->noLinkDynamic = "<span class='timeline-tag'>%s</span> <span class='timeline-text' title='%s'>%s<span class='label-action'>%s</span>%s<span class='label-name'>%s</span></span>";
$lang->block->cannotPlaceInLeft = 'Impossible de placer le bloc à gauche.';
$lang->block->cannotPlaceInRight = 'Impossible de placer le bloc à droite.';
@@ -349,6 +349,7 @@ $lang->block->availableBlocks->risk = 'My Risks';
$lang->block->availableBlocks->issue = 'My Issues';
$lang->block->availableBlocks->meeting = 'My Meetings';
$lang->block->availableBlocks->feedback = 'My Feedbacks';
$lang->block->availableBlocks->ticket = 'Ticket';
$lang->block->moduleList['product'] = $lang->productCommon;
$lang->block->moduleList['project'] = 'Project';
@@ -470,6 +471,7 @@ $lang->block->storyCount = 'Stories';
$lang->block->reviewCount = 'Reviews';
$lang->block->meetingCount = 'Meetings';
$lang->block->feedbackCount = 'Feedbacks';
$lang->block->ticketCount = 'Tickets';
$lang->block->typeList = new stdclass();
+5 -3
View File
@@ -94,8 +94,8 @@ $lang->block->remove = '移除';
$lang->block->refresh = '刷新';
$lang->block->nbsp = '';
$lang->block->hidden = '隐藏';
$lang->block->dynamicInfo = "<span class='timeline-tag'>%s</span> <span class='timeline-text'>%s<em class='label-action'>%s</em>%s<a href='%s' title='%s'>%s</a></span>";
$lang->block->noLinkDynamic = "<span class='timeline-tag'>%s</span> <span class='timeline-text' title='%s'>%s<em class='label-action'>%s</em>%s<span class='label-name'>%s</span></span>";
$lang->block->dynamicInfo = "<span class='timeline-tag'>%s</span> <span class='timeline-text'>%s<span class='label-action'>%s</span>%s<a href='%s' title='%s'>%s</a></span>";
$lang->block->noLinkDynamic = "<span class='timeline-tag'>%s</span> <span class='timeline-text' title='%s'>%s<span class='label-action'>%s</span>%s<span class='label-name'>%s</span></span>";
$lang->block->cannotPlaceInLeft = '此区块无法放置在左侧。';
$lang->block->cannotPlaceInRight = '此区块无法放置在右侧。';
@@ -300,7 +300,7 @@ $lang->block->default['full']['my']['7']['block'] = 'recentproject';
$lang->block->default['full']['my']['7']['source'] = 'project';
$lang->block->default['full']['my']['7']['grid'] = 8;
$lang->block->default['full']['my']['8']['title'] = '待处理';
$lang->block->default['full']['my']['8']['title'] = '我的待处理';
$lang->block->default['full']['my']['8']['block'] = 'assigntome';
$lang->block->default['full']['my']['8']['source'] = '';
$lang->block->default['full']['my']['8']['grid'] = 8;
@@ -349,6 +349,7 @@ $lang->block->availableBlocks->risk = '风险';
$lang->block->availableBlocks->issue = '问题';
$lang->block->availableBlocks->meeting = '会议';
$lang->block->availableBlocks->feedback = '反馈';
$lang->block->availableBlocks->ticket = '工单';
$lang->block->moduleList['product'] = $lang->productCommon;
$lang->block->moduleList['project'] = '项目';
@@ -470,6 +471,7 @@ $lang->block->storyCount = '需求数';
$lang->block->reviewCount = '审批数';
$lang->block->meetingCount = '会议数';
$lang->block->feedbackCount = '反馈数';
$lang->block->ticketCount = '工单数';
$lang->block->typeList = new stdclass();
+2 -2
View File
@@ -18,11 +18,11 @@
<thead>
<tr>
<th class='c-id text-center'><?php echo $lang->idAB?></th>
<th><?php echo $lang->build->name;?></th>
<?php if($longBlock):?>
<th><?php echo $lang->build->product;?></th>
<th><?php echo $lang->build->project;?></th>
<?php endif;?>
<th><?php echo $lang->build->name;?></th>
<th class='c-date'><?php echo $lang->build->date;?></th>
</tr>
</thead>
@@ -36,11 +36,11 @@
?>
<tr <?php echo $appid?>>
<td class='text-center'><?php echo sprintf('%03d', $build->id);?></td>
<td title='<?php echo $build->name?>'><?php echo html::a($buildViewLink, $build->name);?></td>
<?php if($longBlock):?>
<td title='<?php echo $build->productName?>'><?php echo html::a($build->shadow ? $projectViewLink : $productViewLink, $build->productName);?></td>
<td title='<?php echo $build->projectName?>'><?php echo html::a($projectViewLink, $build->projectName);?></td>
<?php endif;?>
<td title='<?php echo $build->name?>'><?php echo html::a($buildViewLink, $build->name);?></td>
<td><?php echo $build->date?></td>
</tr>
<?php endforeach;?>
+2 -2
View File
@@ -38,7 +38,7 @@ $useGuest = $this->app->user->account == 'guest';
<div class='panel-title'><?php echo $block->title;?></div>
<?php endif;?>
<nav class='panel-actions nav nav-default'>
<?php if(!empty($block->moreLink)) echo '<li>' . html::a($block->moreLink, '<i class="icon icon-more"></i>', '', "title='{$lang->more}'") . '</li>'; ?>
<?php if(!empty($block->moreLink)) echo '<li>' . html::a($block->moreLink, strtoupper($lang->more), '', "title='{$lang->more}'") . '</li>'; ?>
<li class='dropdown'>
<a href='javascript:;' data-toggle='dropdown' class='panel-action'><i class='icon icon-ellipsis-v'></i></a>
<ul class='dropdown-menu pull-right'>
@@ -73,7 +73,7 @@ $useGuest = $this->app->user->account == 'guest';
<div class='panel-title'><?php echo $block->title;?></div>
<?php endif;?>
<nav class='panel-actions nav nav-default'>
<?php if(!empty($block->moreLink)) echo '<li>' . html::a($block->moreLink, '<i class="icon icon-more"></i>', '', "title='{$lang->more}'") . '</li>';?>
<?php if(!empty($block->moreLink)) echo '<li>' . html::a($block->moreLink, strtoupper($lang->more), '', "title='{$lang->more}'") . '</li>';?>
<li class='dropdown'>
<a href='javascript:;' data-toggle='dropdown' class='panel-action'><i class='icon icon-ellipsis-v'></i></a>
<ul class='dropdown-menu pull-right'>
+6 -4
View File
@@ -4,13 +4,15 @@
<style>
.block-dynamic .timeline > li .timeline-text {max-width: 600px; display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-height: 20px;}
.block-dynamic .panel-body {padding-top: 0;}
.timeline>li:before {left: -26px;}
.timeline>li+li:after {left: -23px;}
.timeline > li:before {left: -26px;}
.timeline > li + li:after {left: -23px;}
.timeline-text {margin-left: -18px;}
.block-dynamic .label-action {padding: 0 6px;}
.block-dynamic .label-action + a {padding-left: 6px;}
.timeline>li.active:before {left: -30px;}
.timeline>li>div:after {left: -27px;}
.timeline > li.active:before {left: -30px;}
.timeline > li > div:after {left: -27px;}
.timeline > li > div > .timeline-tag, .timeline > li > div > .timeline-text > .label-action {color: #838A9D;}
.timeline > li > div > .timeline-text > a {color: #313C52;}
</style>
<div class='panel-body scrollbar-hover'>
<ul class="timeline timeline-tag-left no-margin">
@@ -11,7 +11,7 @@
*/
?>
<style>
#assigntomeBlock .nav>li>a {padding: 8px 12px;}
#assigntomeBlock .nav > li:not(.active) > a {padding: 8px 12px; color: #838A9D;}
</style>
<div id='assigntomeBlock'>
<ul class="nav nav-secondary">
@@ -11,12 +11,12 @@
*/
?>
<style>
.block-overview .status-list li + li {margin-top: 5px;}
.block-overview .status-list li > strong {font-size: 16px;}
.progress-pie {position: relative;}
.progress-pie .progress-info {position: absolute; width: 100%; height: 100%; left: 0; top: 0; text-align: center; padding-top: 25px;}
.progress-pie .progress-info > small {display: block; color: #A6AAB8; line-height: 14px;}
.progress-pie .progress-info > strong {display: block; font-size: 36px; line-height: 40px;}
.block-overview .status-list li + li {margin-top: 5px;}
.block-overview .status-list li > strong {font-size: 16px;}
.progress-pie {position: relative;}
.progress-pie .progress-info {position: absolute; width: 100%; height: 100%; left: 0; top: 0; text-align: center; padding-top: 25px;}
.progress-pie .progress-info > small {display: block; color: #A6AAB8; line-height: 14px;}
.progress-pie .progress-info > strong {display: block; font-size: 32px; line-height: 40px;}
</style>
<div class="panel-body table-row">
<div class="col-6 text-middle text-center">
@@ -24,14 +24,14 @@
<canvas width="100" height="100" style="width: 100px; height: 100px;"></canvas>
<div class="progress-info">
<small><?php echo $lang->product->all;?></small>
<strong><?php echo empty($total) ? 0 : html::a($this->createLink('product', 'all', "browseType=all"), $total);?></strong>
<strong class='text-primary'><?php echo empty($total) ? 0 : html::a($this->createLink('product', 'all', "browseType=all"), $total, '', "class='text-primary'");?></strong>
</div>
</div>
</div>
<div class="col-6 text-middle">
<ul class="list-unstyled status-list">
<li><span class="status-product status-unclosed"><?php echo $lang->product->statusList['normal'];?></span> &nbsp; <strong><?php echo empty($normal) ? 0 : html::a($this->createLink('product', 'all', "browseType=noclosed"), $normal);?></strong></li>
<li><span class="status-product status-closed"><?php echo $lang->product->statusList['closed'];?></span> &nbsp; <strong><?php echo empty($closed) ? 0 : html::a($this->createLink('product', 'all', "browseType=closed"), $closed);?></strong></li>
<li><span class="status-product status-unclosed"><?php echo $lang->product->statusList['normal'];?></span> &nbsp; <strong class='text-primary'><?php echo empty($normal) ? 0 : html::a($this->createLink('product', 'all', "browseType=noclosed"), $normal, '', "class='text-primary'");?></strong></li>
<li><span class="status-product status-closed"><?php echo $lang->product->statusList['closed'];?></span> &nbsp; <strong class='text-primary'><?php echo empty($closed) ? 0 : html::a($this->createLink('product', 'all', "browseType=closed"), $closed, '', "class='text-primary'");?></strong></li>
</ul>
</div>
</div>
@@ -33,8 +33,8 @@ html[lang="en"] .product-info .type-info {color: #A6AAB8; text-align: center; po
.block-statistic .panel-body {padding-top: 0;}
.block-statistic .panel-body {padding-top: 0;}
.block-statistic .tile {margin-bottom: 30px;}
.block-statistic .tile-title {font-size: 18px; color: #A6AAB8;}
.block-statistic .tile-amount {font-size: 48px; margin-bottom: 10px;}
.block-statistic .tile-title {font-size: 18px; margin-bottom: 10px;}
.block-statistic .tile-amount {font-size: 44px; margin-bottom: 10px;}
.block-statistic .col-nav {border-right: 1px solid #EBF2FB; width: 220px; padding: 0;}
.block-statistic .nav-secondary > li {position: relative}
.block-statistic .nav-secondary > li:hover {background: #f5f5f5;}
@@ -126,10 +126,10 @@ $(function()
<div class="tile">
<div class="tile-title"><?php echo $lang->SRCommon;?></div>
<?php if($product->stories):?>
<div class="tile-amount"><?php echo array_sum($product->stories);?></div>
<div class="tile-amount text-primary"><?php echo array_sum($product->stories);?></div>
<?php common::printLink('product', 'browse', "productID={$product->id}&branch=&type=allstory", $lang->story->viewAll . '<span class="label label-badge label-icon"><i class="icon icon-arrow-right"></i></span>', '', 'class="btn btn-primary btn-circle btn-icon-right btn-sm" data-app="product"');?>
<?php else:?>
<div class="tile-amount">0</div>
<div class="tile-amount text-primary">0</div>
<?php common::printLink('story', 'create', "productID={$product->id}", '<span class="label label-badge label-icon"><i class="icon icon-plus"></i></span>' . $lang->story->create, '', 'class="btn btn-primary btn-circle btn-icon-left btn-sm" data-app="product"');?>
<?php endif;?>
</div>
@@ -5,14 +5,16 @@
.timeline > li .timeline-text {display: block; overflow: hidden; text-overflow: ellipsis; max-height: 20px; -webkit-line-clamp: 1; -webkit-box-orient: vertical; }
.panel-body {padding-top: 0;}
.timeline>li:before {left: -26px;}
.timeline>li+li:after {left: -23px;}
.timeline >li:before {left: -26px;}
.timeline >li + li:after {left: -23px;}
.timeline-text {margin-left: -18px;}
.block-projectdynamic .label-action {padding: 0 6px;}
.block-projectdynamic .label-action + a {padding-left: 6px;}
.timeline>li.active:before {left: -30px;}
.timeline>li>div:after {left: -27px;}
.timeline > li.active:before {left: -30px;}
.timeline > li > div:after {left: -27px;}
.timeline .timeline-text {display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
.timeline > li > div > .timeline-tag, .timeline > li > div > .timeline-text > .label-action {color: #838A9D;}
.timeline > li > div > .timeline-text > a {color: #313C52;}
</style>
<div class='panel-body scrollbar-hover'>
<ul class="timeline timeline-tag-left no-margin">
@@ -102,11 +102,11 @@ $(function()
e.preventDefault();
});
var $projectLi = $('#activeProject');
if($projectLi.length)
var $projectList = $('#activeProject');
if($projectList.length)
{
var projectLi = $projectLi[0];
$(".col ul.nav").animate({scrollTop: projectLi.offsetTop}, "slow");
var projectList = $projectList[0];
$(".col ul.nav").animate({scrollTop: projectList.offsetTop}, "slow");
}
});
</script>
@@ -123,7 +123,7 @@ $(function()
<?php $selected = key($projects);?>
<?php foreach($projects as $project):?>
<li <?php if($project->id == $selected) echo "class='active' id='activeProject'";?> projectID='<?php echo $project->id;?>'>
<a href="###" title="<?php echo $project->name?>" data-target="#tab3Content<?php echo $project->id;?>" data-toggle="tab"><?php echo $project->name;?></a>
<a href="###" title="<?php echo $project->name?>" data-target='<?php echo "#tab3{$blockNavId}Content{$project->id}";?>' data-toggle="tab"><?php echo $project->name;?></a>
<?php echo html::a(helper::createLink('project', 'index', "projectID=$project->id"), "<i class='icon-arrow-right text-primary'></i>", '', "class='btn-view' title={$lang->project->index}");?>
</li>
<?php endforeach;?>
@@ -132,7 +132,7 @@ $(function()
</div>
<div class="col tab-content">
<?php foreach($projects as $project):?>
<div class="tab-pane fade<?php if($project->id == $selected) echo ' active in';?>" id="tab3Content<?php echo $project->id;?>">
<div class="tab-pane fade<?php if($project->id == $selected) echo ' active in';?>" id='<?php echo "tab3{$blockNavId}Content{$project->id}";?>'>
<div class="table-row">
<?php if($project->model == 'scrum' or $project->model == 'kanban'):?>
<div class='table-row'>
+5 -4
View File
@@ -28,12 +28,13 @@
<table class='table table-borderless table-hover table-fixed table-fixed-head tablesorter block-stories <?php if(!$longBlock) echo 'block-sm'?>'>
<thead>
<tr>
<?php $title = str_replace($lang->SRCommon, $lang->URCommon, $lang->story->title);?>
<th class="c-id"><?php echo $lang->idAB?></th>
<th class="c-name"><?php echo $title;?></th>
<th class="c-pri"><?php echo $lang->priAB?></th>
<th class="c-name"><?php echo $lang->URCommon;?></th>
<?php if($longBlock):?>
<th class='c-estimate'><?php echo $lang->story->estimateAB;?></th>
<th class="c-status"><?php echo $lang->statusAB;?></th>
<th class='c-estimate'><?php echo $lang->story->estimateAB;?></th>
<th class='c-stage'><?php echo $lang->story->stageAB;?></th>
<?php endif;?>
</tr>
@@ -46,14 +47,14 @@
?>
<tr <?php echo $appid?>>
<td class="c-id-xs"><?php echo sprintf('%03d', $story->id);?></td>
<td class="c-pri"><span class="label-pri label-pri-<?php echo $story->pri?>" title="<?php echo zget($lang->story->priList, $story->pri, $story->pri);?>"><?php echo zget($lang->story->priList, $story->pri, $story->pri)?></span></td>
<td class="c-name" style='color: <?php echo $story->color?>' title='<?php echo $story->title?>'><?php echo html::a($viewLink, $story->title);?></td>
<td class="c-pri"><span class="label-pri label-pri-<?php echo $story->pri?>" title="<?php echo zget($lang->story->priList, $story->pri, $story->pri);?>"><?php echo zget($lang->story->priList, $story->pri, $story->pri)?></span></td>
<?php if($longBlock):?>
<td class='c-estimate text-center' title="<?php echo $story->estimate . ' ' . $lang->hourCommon;?>"><?php echo $story->estimate . $config->hourUnit?></td>
<?php $status = $this->processStatus('story', $story);?>
<td class='c-status' title='<?php echo $status;?>'>
<span class="status-story status-<?php echo $story->status?>"><?php echo $status;?></span>
</td>
<td class='c-estimate text-center' title="<?php echo $story->estimate . ' ' . $lang->hourCommon;?>"><?php echo $story->estimate . $config->hourUnit?></td>
<td class='c-stage'>
<span class='story-stage-<?php echo $story->stage?>'>
<?php echo zget($lang->story->stageList, $story->stage, $story->stage);?>
+4 -4
View File
@@ -29,11 +29,11 @@
<thead>
<tr>
<th class="c-id"><?php echo $lang->idAB?></th>
<th class="c-name"><?php echo $lang->story->title;?></th>
<th class="c-pri"><?php echo $lang->priAB?></th>
<th class="c-name"><?php echo $lang->SRCommon;?></th>
<?php if($longBlock):?>
<th class='c-estimate'><?php echo $lang->story->estimateAB;?></th>
<th class="c-status"><?php echo $lang->statusAB;?></th>
<th class='c-estimate'><?php echo $lang->story->estimateAB;?></th>
<th class='c-stage'><?php echo $lang->story->stageAB;?></th>
<?php endif;?>
</tr>
@@ -46,14 +46,14 @@
?>
<tr <?php echo $appid?>>
<td class="c-id-xs"><?php echo sprintf('%03d', $story->id);?></td>
<td class="c-pri"><span class="label-pri label-pri-<?php echo $story->pri?>" title="<?php echo zget($lang->story->priList, $story->pri, $story->pri);?>"><?php echo zget($lang->story->priList, $story->pri, $story->pri)?></span></td>
<td class="c-name" style='color: <?php echo $story->color?>' title='<?php echo $story->title?>'><?php echo html::a($viewLink, $story->title);?></td>
<td class="c-pri"><span class="label-pri label-pri-<?php echo $story->pri?>" title="<?php echo zget($lang->story->priList, $story->pri, $story->pri);?>"><?php echo zget($lang->story->priList, $story->pri, $story->pri)?></span></td>
<?php if($longBlock):?>
<td class='c-estimate text-center' title="<?php echo $story->estimate . ' ' . $lang->hourCommon;?>"><?php echo $story->estimate . $config->hourUnit?></td>
<?php $status = $this->processStatus('story', $story);?>
<td class='c-status' title='<?php echo $status;?>'>
<span class="status-story status-<?php echo $story->status?>"><?php echo $status;?></span>
</td>
<td class='c-estimate text-center' title="<?php echo $story->estimate . ' ' . $lang->hourCommon;?>"><?php echo $story->estimate . $config->hourUnit?></td>
<td class='c-stage'>
<span class='story-stage-<?php echo $story->stage?>'>
<?php echo zget($lang->story->stageList, $story->stage, $story->stage);?>
+8 -8
View File
@@ -27,13 +27,13 @@
<thead>
<tr>
<th class='c-id'><?php echo $lang->idAB;?></th>
<th class='c-pri <?php if($longBlock) echo "c-pri-long"?>'><?php echo $lang->priAB?></th>
<th class='c-name'> <?php echo $lang->task->name;?></th>
<th class='c-pri <?php if($longBlock) echo "c-pri-long"?>'><?php echo $lang->priAB?></th>
<th class='c-status'><?php echo $lang->statusAB;?></th>
<?php if($longBlock):?>
<th class='c-deadline'><?php echo $lang->task->deadlineAB;?></th>
<th class='c-estimate'><?php echo $lang->task->estimateAB;?></th>
<th class='c-deadline'><?php echo $lang->task->deadline;?></th>
<?php endif;?>
<th class='c-status text-center'><?php echo $lang->statusAB;?></th>
</tr>
</thead>
<tbody>
@@ -43,20 +43,20 @@
?>
<tr>
<td class='c-id-xs'><?php echo sprintf('%03d', $task->id);?></td>
<td class='c-pri <?php if($longBlock) echo "c-pri-long"?>'><span class='label-pri label-pri-<?php echo $task->pri;?>' title='<?php echo zget($lang->task->priList, $task->pri, $task->pri)?>'><?php echo zget($lang->task->priList, $task->pri, $task->pri)?></span></td>
<?php
$onlybody = $task->executionType == 'kanban' ? true : '';
$class = $task->executionType == 'kanban' ? "class='iframe' data-toggle='modal'" : '';
?>
<td class='c-name' style='color: <?php echo $task->color?>' title='<?php echo $task->name?>'><?php echo html::a($this->createLink('task', 'view', "taskID=$task->id", '', $onlybody, $task->project), $task->name, null, "$class data-width='80%'")?></td>
<?php if($longBlock):?>
<td class='c-estimate text-center' title="<?php echo $task->estimate . ' ' . $lang->execution->workHour;?>"><?php echo $task->estimate . $lang->execution->workHourUnit;?></td>
<td class='c-deadline'><?php if(substr($task->deadline, 0, 4) > 0) echo $task->deadline;?></td>
<?php endif;?>
<td class='c-pri <?php if($longBlock) echo "c-pri-long"?>'><span class='label-pri label-pri-<?php echo $task->pri;?>' title='<?php echo zget($lang->task->priList, $task->pri)?>'><?php echo zget($lang->task->priList, $task->pri)?></span></td>
<?php $status = $this->processStatus('task', $task);?>
<td class='c-status' title='<?php echo $status;?>'>
<span class="status-task status-<?php echo $task->status?>"><?php echo $status;?></span>
</td>
<?php if($longBlock):?>
<td class='c-deadline'><?php if(substr($task->deadline, 0, 4) > 0) echo $task->deadline;?></td>
<td class='c-estimate text-center' title="<?php echo $task->estimate . ' ' . $lang->execution->workHour;?>"><?php echo $task->estimate . $lang->execution->workHourUnit;?></td>
<?php endif;?>
</tr>
<?php endforeach;?>
</tbody>
+36
View File
@@ -0,0 +1,36 @@
<?php if(empty($tickets)): ?>
<div class='empty-tip'><?php echo $lang->block->emptyTip;?></div>
<?php else:?>
<style>
.block-tickets .c-id {width: 50px;}
</style>
<div class='panel-body has-table scrollbar-hover'>
<table class='table table-borderless table-fixed table-fixed-head table-hover tablesorter block-tickets <?php if(!$longBlock) echo 'block-sm'?>'>
<thead>
<tr>
<th class='c-id'><?php echo $lang->idAB?></th>
<th class='c-product'><?php echo $lang->ticket->product;?></th>
<th class='c-title'><?php echo $lang->ticket->title?></th>
<th class='c-type'><?php echo $lang->ticket->type;?></th>
<th class='c-openedBy'><?php echo $lang->ticket->createdBy;?></th>
<th class='c-openedDate'><?php echo $lang->ticket->createdDate;?></th>
</tr>
</thead>
<tbody>
<?php foreach($tickets as $ticket):?>
<?php
$appid = isset($_GET['entry']) ? "class='app-btn' data-id='{$this->get->entry}'" : '';
?>
<tr>
<td><?php echo sprintf('%03d', $ticket->id);?></td>
<td><?php echo zget($products, $ticket->product);?></td>
<td class='c-title' title='<?php echo $ticket->title?>'><?php echo html::a($this->createLink('ticket', 'view', "ticketID=$ticket->id"), $ticket->title, '', "data-app='my'")?></td>
<td><?php echo zget($lang->ticket->typeList, $ticket->type)?></td>
<td><?php echo zget($users, $ticket->openedBy)?></td>
<td><?php echo $ticket->openedDate;?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
<?php endif;?>
+4 -1
View File
@@ -39,11 +39,14 @@ if(!$selfCall) die(include('./todolist.html.php'));
.block-todoes .label-todo {width: 50px; min-width: 50px!important; border: none; color: #43A047;}
.block-todoes .todo-title.text-ellipsis {text-overflow: unset;}
[lang^='en'] .block-todoes .todo-pri {width: 60px; min-width: 60px;}
.block-todoes .todoes-input .todo-form-trigger > .btn-info {width: 100%; opacity: 0.8; margin-left: 10px;}
</style>
<div class='block-todoes'>
<div class='panel-body'>
<div class="todoes-input">
<div class="todo-form-trigger"><input type="text" placeholder="<?php echo $lang->todo->lblClickCreate?>" autocomplete="off" class="form-control"></div>
<div class="todo-form-trigger">
<button class='btn btn-info'><i class='icon icon-plus'></i> <?php echo $lang->todo->create;?></button>
</div>
<form class="form-horizontal todoes-form layer not-watch" method='post' target='hiddenwin' action='<?php echo $this->createLink('todo', 'create', 'date=today&userID=&from=block');?>'>
<h3><?php echo $lang->todo->create;?></h3>
<?php $leftWidth = common::checkNotCN() ? 'col-sm-3' : 'col-sm-2';?>
+3 -3
View File
@@ -59,7 +59,7 @@
<div class="row tiles">
<div class="col tile">
<div class="tile-title"><?php echo $lang->block->myTask?></div>
<div class="tile-amount"><?php echo empty($tasks) ? 0 : html::a($this->createLink('my', 'work', 'mode=task'), (int)$tasks);?></div>
<div class="tile-amount text-primary"><?php echo empty($tasks) ? 0 : html::a($this->createLink('my', 'work', 'mode=task'), (int)$tasks, '', "class='text-primary'");?></div>
<?php if(!empty($delay['task'])):?>
<div class="tile-info">
<span class="label label-danger label-outline welcome-label"><?php echo $lang->block->delayed . ' ' . $delay['task']?></span>
@@ -68,7 +68,7 @@
</div>
<div class="col tile">
<div class="tile-title"><?php echo $lang->block->myBug?></div>
<div class="tile-amount"><?php echo empty($bugs) ? 0 : html::a($this->createLink('my', 'work', 'mode=bug'), (int)$bugs);?></div>
<div class="tile-amount text-primary"><?php echo empty($bugs) ? 0 : html::a($this->createLink('my', 'work', 'mode=bug'), (int)$bugs, '', "class='text-primary'");?></div>
<?php if(!empty($delay['bug'])):?>
<div class="tile-info">
<span class="label label-danger label-outline welcome-label"><?php echo $lang->block->delayed . ' ' . $delay['bug']?></span>
@@ -77,7 +77,7 @@
</div>
<div class="col tile">
<div class="tile-title"><?php echo $lang->block->myStory?></div>
<div class="tile-amount"><?php echo empty($stories) ? 0 : html::a($this->createLink('my', 'work', 'mode=story'), (int)$stories);?></div>
<div class="tile-amount text-primary"><?php echo empty($stories) ? 0 : html::a($this->createLink('my', 'work', 'mode=story'), (int)$stories, '', "class='text-primary'");?></div>
</div>
</div>
</div>
+74 -63
View File
@@ -24,7 +24,7 @@ $config->bug->list->allFields = 'id, module, execution, story, task,
lastEditedBy,
lastEditedDate';
$config->bug->list->defaultFields = 'id,severity,pri,title,openedBy,assignedTo,resolvedBy,resolution';
$config->bug->list->defaultFields = 'id,title,severity,pri,openedBy,assignedTo,resolvedBy,resolution';
$config->bug->exportFields = 'id, product, branch, module, project, execution, story, task,
title, keywords, severity, pri, type, os, browser,
@@ -151,7 +151,7 @@ $config->bug->search['params']['deadline'] = array('operator' => '=',
$config->bug->search['params']['activatedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
$config->bug->datatable = new stdclass();
$config->bug->datatable->defaultField = array('id', 'severity', 'pri', 'confirmed', 'title', 'status', 'openedBy', 'openedDate', 'assignedTo', 'resolution', 'actions');
$config->bug->datatable->defaultField = array('id', 'title', 'severity', 'pri', 'status', 'openedBy', 'openedDate', 'confirmed', 'assignedTo', 'resolution', 'actions');
$config->bug->datatable->fieldList['id']['title'] = 'idAB';
$config->bug->datatable->fieldList['id']['fixed'] = 'left';
@@ -166,6 +166,12 @@ $config->bug->datatable->fieldList['module']['control'] = 'select';
$config->bug->datatable->fieldList['module']['title'] = 'module';
$config->bug->datatable->fieldList['module']['dataSource'] = array('module' => 'tree', 'method' => 'getOptionMenu', 'params' => '$productID&bug');
$config->bug->datatable->fieldList['title']['title'] = 'title';
$config->bug->datatable->fieldList['title']['fixed'] = 'left';
$config->bug->datatable->fieldList['title']['width'] = 'auto';
$config->bug->datatable->fieldList['title']['required'] = 'yes';
$config->bug->datatable->fieldList['title']['minWidth'] = '200';
$config->bug->datatable->fieldList['severity']['title'] = 'severityAB';
$config->bug->datatable->fieldList['severity']['fixed'] = 'left';
$config->bug->datatable->fieldList['severity']['width'] = '50';
@@ -189,6 +195,11 @@ $config->bug->datatable->fieldList['title']['width'] = 'auto';
$config->bug->datatable->fieldList['title']['required'] = 'yes';
$config->bug->datatable->fieldList['title']['minWidth'] = '200';
$config->bug->datatable->fieldList['status']['title'] = 'statusAB';
$config->bug->datatable->fieldList['status']['fixed'] = 'left';
$config->bug->datatable->fieldList['status']['width'] = '80';
$config->bug->datatable->fieldList['status']['required'] = 'no';
$config->bug->datatable->fieldList['branch']['title'] = 'branch';
$config->bug->datatable->fieldList['branch']['fixed'] = 'left';
$config->bug->datatable->fieldList['branch']['width'] = '100';
@@ -219,10 +230,66 @@ $config->bug->datatable->fieldList['plan']['fixed'] = 'no';
$config->bug->datatable->fieldList['plan']['width'] = '120';
$config->bug->datatable->fieldList['plan']['required'] = 'no';
$config->bug->datatable->fieldList['status']['title'] = 'statusAB';
$config->bug->datatable->fieldList['status']['fixed'] = 'no';
$config->bug->datatable->fieldList['status']['width'] = '80';
$config->bug->datatable->fieldList['status']['required'] = 'no';
$config->bug->datatable->fieldList['openedBy']['title'] = 'openedByAB';
$config->bug->datatable->fieldList['openedBy']['fixed'] = 'no';
$config->bug->datatable->fieldList['openedBy']['width'] = '80';
$config->bug->datatable->fieldList['openedBy']['required'] = 'no';
$config->bug->datatable->fieldList['openedDate']['title'] = 'openedDateAB';
$config->bug->datatable->fieldList['openedDate']['fixed'] = 'no';
$config->bug->datatable->fieldList['openedDate']['width'] = '90';
$config->bug->datatable->fieldList['openedDate']['required'] = 'no';
$config->bug->datatable->fieldList['openedBuild']['title'] = 'openedBuild';
$config->bug->datatable->fieldList['openedBuild']['fixed'] = 'no';
$config->bug->datatable->fieldList['openedBuild']['width'] = '120';
$config->bug->datatable->fieldList['openedBuild']['required'] = 'no';
$config->bug->datatable->fieldList['openedBuild']['control'] = 'multiple';
$config->bug->datatable->fieldList['openedBuild']['dataSource'] = array('module' => 'build', 'method' =>'getBuildPairs', 'params' => '$productID&$branch&noempty,noterminate,nodone,withbranch');
$config->bug->datatable->fieldList['confirmed']['title'] = 'confirmedAB';
$config->bug->datatable->fieldList['confirmed']['fixed'] = 'no';
$config->bug->datatable->fieldList['confirmed']['width'] = '100';
$config->bug->datatable->fieldList['confirmed']['required'] = 'no';
$config->bug->datatable->fieldList['assignedTo']['title'] = 'assignedToAB';
$config->bug->datatable->fieldList['assignedTo']['fixed'] = 'no';
$config->bug->datatable->fieldList['assignedTo']['width'] = '120';
$config->bug->datatable->fieldList['assignedTo']['required'] = 'no';
$config->bug->datatable->fieldList['assignedTo']['dataSource'] = array('module' => 'user', 'method' =>'getPairs', 'params' => 'noclosed|noletter');
$config->bug->datatable->fieldList['assignedDate']['title'] = 'assignedDate';
$config->bug->datatable->fieldList['assignedDate']['fixed'] = 'no';
$config->bug->datatable->fieldList['assignedDate']['width'] = '90';
$config->bug->datatable->fieldList['assignedDate']['required'] = 'no';
$config->bug->datatable->fieldList['deadline']['title'] = 'deadline';
$config->bug->datatable->fieldList['deadline']['fixed'] = 'no';
$config->bug->datatable->fieldList['deadline']['width'] = '90';
$config->bug->datatable->fieldList['deadline']['required'] = 'no';
$config->bug->datatable->fieldList['deadline']['control'] = 'date';
$config->bug->datatable->fieldList['resolvedBy']['title'] = 'resolvedBy';
$config->bug->datatable->fieldList['resolvedBy']['fixed'] = 'no';
$config->bug->datatable->fieldList['resolvedBy']['width'] = '100';
$config->bug->datatable->fieldList['resolvedBy']['required'] = 'no';
$config->bug->datatable->fieldList['resolution']['title'] = 'resolutionAB';
$config->bug->datatable->fieldList['resolution']['fixed'] = 'no';
$config->bug->datatable->fieldList['resolution']['width'] = '110';
$config->bug->datatable->fieldList['resolution']['required'] = 'no';
$config->bug->datatable->fieldList['resolvedDate']['title'] = 'resolvedDateAB';
$config->bug->datatable->fieldList['resolvedDate']['fixed'] = 'no';
$config->bug->datatable->fieldList['resolvedDate']['width'] = '120';
$config->bug->datatable->fieldList['resolvedDate']['required'] = 'no';
$config->bug->datatable->fieldList['resolvedBuild']['title'] = 'resolvedBuild';
$config->bug->datatable->fieldList['resolvedBuild']['fixed'] = 'no';
$config->bug->datatable->fieldList['resolvedBuild']['width'] = '120';
$config->bug->datatable->fieldList['resolvedBuild']['required'] = 'no';
$config->bug->datatable->fieldList['resolvedBuild']['control'] = 'select';
$config->bug->datatable->fieldList['resolvedBuild']['dataSource'] = array('module' => 'bug', 'method' =>'getRelatedObjects', 'params' => 'resolvedBuild&id,name');
$config->bug->datatable->fieldList['activatedCount']['title'] = 'activatedCountAB';
$config->bug->datatable->fieldList['activatedCount']['fixed'] = 'no';
@@ -239,7 +306,7 @@ $config->bug->datatable->fieldList['story']['fixed'] = 'no';
$config->bug->datatable->fieldList['story']['width'] = '120';
$config->bug->datatable->fieldList['story']['required'] = 'no';
$config->bug->datatable->fieldList['story']['control'] = 'select';
$config->bug->datatable->fieldList['story']['dataSource'] = array('module' => 'bug', 'method' =>'getRelatedObjects', 'params' => 'story&id,title');
$config->bug->datatable->fieldList['story']['dataSource'] = array('module' => 'story', 'method' =>'getProductStoryPairs', 'params' => '$productID');
$config->bug->datatable->fieldList['task']['title'] = 'task';
$config->bug->datatable->fieldList['task']['fixed'] = 'no';
@@ -272,62 +339,6 @@ $config->bug->datatable->fieldList['mailto']['fixed'] = 'no';
$config->bug->datatable->fieldList['mailto']['width'] = '100';
$config->bug->datatable->fieldList['mailto']['required'] = 'no';
$config->bug->datatable->fieldList['openedBy']['title'] = 'openedByAB';
$config->bug->datatable->fieldList['openedBy']['fixed'] = 'no';
$config->bug->datatable->fieldList['openedBy']['width'] = '80';
$config->bug->datatable->fieldList['openedBy']['required'] = 'no';
$config->bug->datatable->fieldList['openedDate']['title'] = 'openedDateAB';
$config->bug->datatable->fieldList['openedDate']['fixed'] = 'no';
$config->bug->datatable->fieldList['openedDate']['width'] = '90';
$config->bug->datatable->fieldList['openedDate']['required'] = 'no';
$config->bug->datatable->fieldList['openedBuild']['title'] = 'openedBuild';
$config->bug->datatable->fieldList['openedBuild']['fixed'] = 'no';
$config->bug->datatable->fieldList['openedBuild']['width'] = '120';
$config->bug->datatable->fieldList['openedBuild']['required'] = 'no';
$config->bug->datatable->fieldList['openedBuild']['control'] = 'multiple';
$config->bug->datatable->fieldList['openedBuild']['dataSource'] = array('module' => 'build', 'method' =>'getBuildPairs', 'params' => '$productID&$branch&noempty,noterminate,nodone,withbranch');
$config->bug->datatable->fieldList['assignedTo']['title'] = 'assignedToAB';
$config->bug->datatable->fieldList['assignedTo']['fixed'] = 'no';
$config->bug->datatable->fieldList['assignedTo']['width'] = '120';
$config->bug->datatable->fieldList['assignedTo']['required'] = 'no';
$config->bug->datatable->fieldList['assignedTo']['dataSource'] = array('module' => 'user', 'method' =>'getPairs', 'params' => 'noclosed|noletter');
$config->bug->datatable->fieldList['assignedDate']['title'] = 'assignedDate';
$config->bug->datatable->fieldList['assignedDate']['fixed'] = 'no';
$config->bug->datatable->fieldList['assignedDate']['width'] = '90';
$config->bug->datatable->fieldList['assignedDate']['required'] = 'no';
$config->bug->datatable->fieldList['deadline']['title'] = 'deadline';
$config->bug->datatable->fieldList['deadline']['fixed'] = 'no';
$config->bug->datatable->fieldList['deadline']['width'] = '90';
$config->bug->datatable->fieldList['deadline']['required'] = 'no';
$config->bug->datatable->fieldList['deadline']['control'] = 'date';
$config->bug->datatable->fieldList['resolvedBy']['title'] = 'resolvedByAB';
$config->bug->datatable->fieldList['resolvedBy']['fixed'] = 'no';
$config->bug->datatable->fieldList['resolvedBy']['width'] = '100';
$config->bug->datatable->fieldList['resolvedBy']['required'] = 'no';
$config->bug->datatable->fieldList['resolution']['title'] = 'resolutionAB';
$config->bug->datatable->fieldList['resolution']['fixed'] = 'no';
$config->bug->datatable->fieldList['resolution']['width'] = '110';
$config->bug->datatable->fieldList['resolution']['required'] = 'no';
$config->bug->datatable->fieldList['resolvedDate']['title'] = 'resolvedDateAB';
$config->bug->datatable->fieldList['resolvedDate']['fixed'] = 'no';
$config->bug->datatable->fieldList['resolvedDate']['width'] = '120';
$config->bug->datatable->fieldList['resolvedDate']['required'] = 'no';
$config->bug->datatable->fieldList['resolvedBuild']['title'] = 'resolvedBuild';
$config->bug->datatable->fieldList['resolvedBuild']['fixed'] = 'no';
$config->bug->datatable->fieldList['resolvedBuild']['width'] = '120';
$config->bug->datatable->fieldList['resolvedBuild']['required'] = 'no';
$config->bug->datatable->fieldList['resolvedBuild']['control'] = 'select';
$config->bug->datatable->fieldList['resolvedBuild']['dataSource'] = array('module' => 'bug', 'method' =>'getRelatedObjects', 'params' => 'resolvedBuild&id,name');
$config->bug->datatable->fieldList['closedBy']['title'] = 'closedBy';
$config->bug->datatable->fieldList['closedBy']['fixed'] = 'no';
$config->bug->datatable->fieldList['closedBy']['width'] = '80';
+9 -9
View File
@@ -959,14 +959,8 @@ class bug extends control
$changes = $this->bug->update($bugID);
if(dao::isError())
{
if(defined('RUN_MODE') && RUN_MODE == 'api')
{
return $this->send(array('status' => 'error', 'message' => dao::getError()));
}
else
{
return print(js::error(dao::getError()));
}
if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'error', 'message' => dao::getError()));
return print(js::error(dao::getError()));
}
}
@@ -1151,6 +1145,12 @@ class bug extends control
$assignedToList = array_filter($assignedToList);
if(empty($assignedToList)) $assignedToList = $this->user->getPairs('devfirst|noclosed');
}
if($bug->assignedTo and !isset($assignedToList[$bug->assignedTo]))
{
/* Fix bug #28378. */
$assignedTo = $this->user->getById($bug->assignedTo);
$assignedToList[$bug->assignedTo] = $assignedTo->realname;
}
if($bug->status == 'closed') $assignedToList['closed'] = 'Closed';
$branch = $product->type == 'branch' ? ($bug->branch > 0 ? $bug->branch . ',0' : '0') : '';
@@ -1826,7 +1826,7 @@ class bug extends control
$this->view->users = $users;
$this->view->assignedTo = $assignedTo;
$this->view->productBugs = $productBugs;
$this->view->executions = $this->loadModel('product')->getExecutionPairsByProduct($productID, $bug->branch ? "0,{$bug->branch}" : 0, 'id_desc', $projectID);
$this->view->executions = $this->loadModel('product')->getExecutionPairsByProduct($productID, $bug->branch ? "0,{$bug->branch}" : 0, 'id_desc', $projectID, 'stagefilter');
$this->view->builds = $this->loadModel('build')->getBuildPairs($productID, $bug->branch, 'withbranch');
$this->view->actions = $this->action->getList('bug', $bugID);
$this->view->execution = isset($execution) ? $execution : '';
-1
View File
@@ -2,7 +2,6 @@
.closed, .closed a {color: gray; text-decoration:line-through;}
.resolved, .resolved a {color: #8EC21F; text-decoration: none;}
.tree .closed, .tree .closed a {color: #003366; text-decoration: none;}
td.delayed {color: #fff; background: #e84e0f !important;}
#bugForm .setting {height: 25px;}
.datatable-wrapper .table-datatable .datatable-row td {height: 37px;}
+7 -3
View File
@@ -78,7 +78,7 @@ class bugModel extends model
->join('mailto', ',')
->join('os', ',')
->join('browser', ',')
->remove('files,labels,uid,oldTaskID,contactListMenu,region,lane')
->remove('files,labels,uid,oldTaskID,contactListMenu,region,lane,ticket')
->get();
if($bug->execution != 0) $bug->project = $this->dao->select('project')->from(TABLE_EXECUTION)->where('id')->eq($bug->execution)->fetch('project');
@@ -752,7 +752,7 @@ class bugModel extends model
/* Link bug to build and release. */
if($bug->resolution == 'fixed' and !empty($bug->resolvedBuild) and $oldBug->resolvedBuild != $bug->resolvedBuild)
{
if(!empty($oldBug->resolvedBuild)) $this->loadModel('build')->unlinkBug((int)$oldBug->resolvedBuild, (int)$bugID);
if(!empty($oldBug->resolvedBuild)) $this->loadModel('build')->unlinkBug($oldBug->resolvedBuild, (int)$bugID);
$this->linkBugToBuild($bugID, $bug->resolvedBuild);
}
@@ -2211,6 +2211,7 @@ class bugModel extends model
if(!empty($run->task)) $testtask = $this->loadModel('testtask')->getById($run->task);
$executionID = isset($testtask->execution) ? $testtask->execution : 0;
if(!$executionID and $caseID > 0) $executionID = isset($run->case->execution) ? $run->case->execution : 0; // Fix feedback #1043.
if(!$executionID and $this->app->tab == 'execution') $executionID = $this->session->execution;
return array('title' => $title, 'steps' => $bugSteps, 'storyID' => $run->case->story, 'moduleID' => $run->case->module, 'version' => $run->case->version, 'executionID' => $executionID);
@@ -3294,6 +3295,9 @@ class bugModel extends model
$class .= ' text-ellipsis';
$title = "title='" . $browser . "'";
break;
case 'deadline':
$class .= ' text-center';
break;
}
if($id == 'deadline' && isset($bug->delay) && $bug->status == 'active') $class .= ' delayed';
@@ -3437,7 +3441,7 @@ class bugModel extends model
echo helper::isZeroDate($bug->assignedDate) ? '' : substr($bug->assignedDate, 5, 11);
break;
case 'deadline':
echo helper::isZeroDate($bug->deadline) ? '' : substr($bug->deadline, 5, 11);
echo helper::isZeroDate($bug->deadline) ? '' : '<span>' . substr($bug->deadline, 5, 11) . '</span>';
break;
case 'resolvedBy':
echo zget($users, $bug->resolvedBy, $bug->resolvedBy);
+2 -2
View File
@@ -155,11 +155,11 @@ if($this->app->tab == 'project') js::set('objectID', $projectID);
<?php if($showNoticefeedbackBy):?>
<tr>
<th><nobr><?php echo $lang->bug->feedbackBy;?></nobr></th>
<td><?php echo html::input('feedbackBy', $feedbackBy, "class='form-control'");?></td>
<td><?php echo html::input('feedbackBy', isset($feedbackBy) ? $feedbackBy : '', "class='form-control'");?></td>
<td id='notifyEmailTd'>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->bug->notifyEmail?></span>
<span><?php echo html::input('notifyEmail', $notifyEmail, "class='form-control'");?></span>
<span><?php echo html::input('notifyEmail', isset($notifyEmail) ? $notifyEmail : '', "class='form-control'");?></span>
</div>
</td>
</tr>
+2 -2
View File
@@ -143,7 +143,7 @@ if($this->app->tab == 'project') js::set('objectID', $bug->project);
</tr>
<tr>
<th><?php echo $lang->bug->status;?></th>
<td>
<td class='status-<?php echo $bug->status;?>'>
<?php
echo zget($lang->bug->statusList, $bug->status);
echo html::hidden('status', $bug->status);
@@ -152,7 +152,7 @@ if($this->app->tab == 'project') js::set('objectID', $bug->project);
</tr>
<tr>
<th><?php echo $lang->bug->confirmed;?></th>
<td><?php echo $lang->bug->confirmedList[$bug->confirmed];?></td>
<td class='confirm<?php echo $bug->confirmed;?>'><?php echo $lang->bug->confirmedList[$bug->confirmed];?></td>
</tr>
<tr>
<th><?php echo $lang->bug->assignedTo;?></th>
+1 -1
View File
@@ -208,7 +208,7 @@
</tr>
<tr>
<th><?php echo $lang->bug->confirmed;?></th>
<td><?php echo $lang->bug->confirmedList[$bug->confirmed];?></td>
<td class='confirm<?php echo $bug->confirmed;?>'><?php echo $lang->bug->confirmedList[$bug->confirmed];?></td>
</tr>
<tr>
<th><?php echo $lang->bug->lblAssignedTo;?></th>
+1 -1
View File
@@ -314,7 +314,7 @@ class build extends control
$this->view->canBeChanged = common::canBeChanged('build', $build); // Determines whether an object is editable.
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->build = $build;
$this->view->buildPairs = $this->build->getBuildPairs(0, 0, 'noempty,notrunk', $build->execution, 'execution');
$this->view->buildPairs = $this->build->getBuildPairs(0, 'all', 'noempty,notrunk', $build->execution, 'execution');
$this->view->actions = $this->loadModel('action')->getList('build', $buildID);
$this->view->link = $link;
$this->view->param = $param;
+4 -4
View File
@@ -126,11 +126,11 @@ js::set('flow', $config->global->flow);
<?php endif;?>
<?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?>
</th>
<th class='c-pri' title=<?php echo $lang->pri;?>><?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='text-left'><?php common::printOrderLink('title', $orderBy, $vars, $lang->testcase->title);?></th>
<th class='c-pri' title=<?php echo $lang->pri;?>><?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='c-type'> <?php common::printOrderLink('type', $orderBy, $vars, $lang->typeAB);?></th>
<th class='c-user'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
<th class='c-status'><?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-user'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
<?php
$extendFields = $this->caselib->getFlowExtendFields();
foreach($extendFields as $extendField) echo "<th>{$extendField->name}</th>";
@@ -148,15 +148,15 @@ js::set('flow', $config->global->flow);
<?php echo sprintf('%03d', $case->id);?>
<?php endif;?>
</td>
<td><span class='label-pri label-pri-<?php echo $case->pri;?>' title='<?php echo zget($lang->testcase->priList, $case->pri, $case->pri);?>'><?php echo zget($lang->testcase->priList, $case->pri, $case->pri);?></span></td>
<td class='text-left' title="<?php echo $case->title?>">
<?php if($modulePairs and $case->module) echo "<span title='{$lang->testcase->module}' class='label label-info label-badge'>{$modulePairs[$case->module]}</span> ";?>
<?php $viewLink = $this->createLink('testcase', 'view', "caseID=$case->id&version=$case->version");?>
<?php echo html::a($viewLink, $case->title, null, "style='color: $case->color'");?>
</td>
<td><span class='label-pri label-pri-<?php echo $case->pri;?>' title='<?php echo zget($lang->testcase->priList, $case->pri, $case->pri);?>'><?php echo zget($lang->testcase->priList, $case->pri, $case->pri);?></span></td>
<td><?php echo $lang->testcase->typeList[$case->type];?></td>
<td title="<?php echo zget($users, $case->openedBy);?>"><?php echo zget($users, $case->openedBy);?></td>
<td class='<?php if(isset($run)) echo $run->status;?> testcase-<?php echo $case->status?>'> <?php echo $this->processStatus('testcase', $case);?></td>
<td title="<?php echo zget($users, $case->openedBy);?>"><?php echo zget($users, $case->openedBy);?></td>
<?php foreach($extendFields as $extendField) echo "<td>" . $this->loadModel('flow')->getFieldValue($extendField, $case) . "</td>";?>
<td class='c-actions'>
<?php echo $this->caselib->buildOperateMenu($case, 'browse');?>
+1 -1
View File
@@ -146,7 +146,7 @@ $lang->workingHour = '工时';
$lang->idAB = 'ID';
$lang->priAB = 'P';
$lang->statusAB = '状态';
$lang->openedByAB = '创建';
$lang->openedByAB = '创建者';
$lang->assignedToAB = '指派';
$lang->typeAB = '类型';
$lang->nameAB = '名称';
+1 -1
View File
@@ -136,7 +136,7 @@ $lang->workingHour = '工時';
$lang->idAB = 'ID';
$lang->priAB = 'P';
$lang->statusAB = '狀態';
$lang->openedByAB = '創建';
$lang->openedByAB = '創建者';
$lang->assignedToAB = '指派';
$lang->typeAB = '類型';
$lang->nameAB = '名稱';
+6 -4
View File
@@ -23,11 +23,13 @@
#mainMenu .picker .picker-selections{white-space:nowrap;}
.picker-drop-menu{width:auto !important; max-width:350px !important;}
.timeline>li:before {left: -26px;}
.timeline>li+li:after {left: -23px;}
.timeline > li:before {left: -26px;}
.timeline > li + li:after {left: -23px;}
.timeline-text {margin-left: -18px;}
.label-action {padding: 0 4px;}
.label-id {margin-left: 4px;}
.timeline>li.active:before {left: -30px;}
.timeline>li>div:after {left: -27px;}
.timeline > li.active:before {left: -30px;}
.timeline > li > div:after {left: -27px;}
.timeline .timeline-text {display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
.timeline > li > div > .timeline-tag, .timeline > li > div > .timeline-text > .label-action {color: #838A9D;}
.timeline > li > div > .timeline-text > a {color: #313C52;}
+1 -1
View File
@@ -257,7 +257,7 @@ class custom extends control
}
}
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('custom', 'set', "module=$module&field=$field&lang=" . str_replace('-', '_', isset($this->config->langs[$lang]) ? $lang : 'all'))));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('custom', 'set', "module=$module&field=$field&lang=" . ($lang == 'all' ? $lang : ''))));
}
/* Check whether the current language has been customized. */
-1
View File
@@ -68,7 +68,6 @@ class datatable extends control
$this->app->loadConfig('testtask');
$this->config->testcase->datatable->defaultField = $this->config->testtask->datatable->defaultField;
$this->config->testcase->datatable->fieldList['actions']['width'] = '100';
$this->config->testcase->datatable->fieldList['status']['title'] = $this->lang->testcase->executionStatus;
$this->config->testcase->datatable->fieldList['status']['width'] = '90';
}
if($module == 'testcase')
+1
View File
@@ -33,6 +33,7 @@ $lang->design->affectedStory = "{$lang->SRCommon}";
$lang->design->affectedTasks = 'Task';
$lang->design->reviewObject = 'Review Object';
$lang->design->createdBy = 'CreatedBy';
$lang->design->createdByAB = 'CreatedBy';
$lang->design->createdDate = 'CreatedDate';
$lang->design->basicInfo = 'Basic Information';
$lang->design->noAssigned = 'Unassigned';
+1
View File
@@ -33,6 +33,7 @@ $lang->design->affectedStory = "{$lang->SRCommon}";
$lang->design->affectedTasks = 'Task';
$lang->design->reviewObject = 'Review Object';
$lang->design->createdBy = 'CreatedBy';
$lang->design->createdByAB = 'CreatedBy';
$lang->design->createdDate = 'CreatedDate';
$lang->design->basicInfo = 'Basic Information';
$lang->design->noAssigned = 'Unassigned';
+1
View File
@@ -33,6 +33,7 @@ $lang->design->affectedStory = "{$lang->SRCommon}";
$lang->design->affectedTasks = 'Task';
$lang->design->reviewObject = 'Review Object';
$lang->design->createdBy = 'CreatedBy';
$lang->design->createdByAB = 'CreatedBy';
$lang->design->createdDate = 'CreatedDate';
$lang->design->basicInfo = 'Basic Information';
$lang->design->noAssigned = 'Unassigned';
+1
View File
@@ -33,6 +33,7 @@ $lang->design->affectedStory = "影响{$lang->SRCommon}";
$lang->design->affectedTasks = '影响任务';
$lang->design->reviewObject = '评审对象';
$lang->design->createdBy = '由谁创建';
$lang->design->createdByAB = '创建者';
$lang->design->createdDate = '创建时间';
$lang->design->basicInfo = '基本信息';
$lang->design->noAssigned = '未指派';
+6 -6
View File
@@ -32,12 +32,12 @@
<?php $vars = "projectID=$projectID&productID=$productID&type=$type&param=$param&orderBy=%s&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}";?>
<thead>
<tr>
<th class="text-left w-60px"> <?php common::printOrderLink('id', $orderBy, $vars, $lang->design->id);?></th>
<th class="text-left w-100px"> <?php common::printOrderLink('type', $orderBy, $vars, $lang->design->type);?></th>
<th class="text-left w-60px"> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th class="text-left"> <?php common::printOrderLink('name', $orderBy, $vars, $lang->design->name);?></th>
<th class="text-left w-120px"> <?php common::printOrderLink('createdBy', $orderBy, $vars, $lang->design->createdBy);?></th>
<th class="text-left w-150px"> <?php common::printOrderLink('createdDate', $orderBy, $vars, $lang->design->createdDate);?></th>
<th class="text-left w-100px"> <?php common::printOrderLink('type', $orderBy, $vars, $lang->design->type);?></th>
<th class="c-assignedTo w-120px"><?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->design->assignedTo);?></th>
<th class="text-left w-120px"> <?php common::printOrderLink('createdBy', $orderBy, $vars, $lang->design->createdByAB);?></th>
<th class="text-left w-150px"> <?php common::printOrderLink('createdDate', $orderBy, $vars, $lang->design->createdDate);?></th>
<th class="text-center w-100px"> <?php echo $lang->design->actions;?></th>
</tr>
</thead>
@@ -45,11 +45,11 @@
<?php foreach($designs as $design):?>
<tr>
<td calss="c-id"> <?php printf('%03d', $design->id);?></td>
<td class="c-type"> <?php echo zget($lang->design->typeList, $design->type);?></td>
<td class="c-name" title="<?php echo $design->name;?>"><?php echo common::hasPriv('design', 'view') ? html::a($this->createLink('design', 'view', "id={$design->id}"), $design->name) : $design->name;?></td>
<td class="c-type"> <?php echo zget($lang->design->typeList, $design->type);?></td>
<td class="c-assignedTo"> <?php echo $this->design->printAssignedHtml($design, $users);?></td>
<td class="c-createdBy"> <?php echo zget($users, $design->createdBy);?></td>
<td class="c-createdDate"><?php echo substr($design->createdDate, 0, 11);?></td>
<td class="c-assignedTo"> <?php echo $this->design->printAssignedHtml($design, $users);?></td>
<td class='c-actions text-center'>
<?php
$vars = "design={$design->id}";
+1 -1
View File
@@ -69,7 +69,7 @@ class devModel extends model
$type = substr($rawField->type, 0, $firstPOS > 0 ? $firstPOS : strlen($rawField->type));
$type = str_replace(array('big', 'small', 'medium', 'tiny'), '', $type);
$field = array();
$field['name'] = isset($this->lang->$module->{$rawField->field}) ? sprintf($this->lang->$module->{$rawField->field}, $this->lang->dev->tableList[$module]) : '';
$field['name'] = (isset($this->lang->$module->{$rawField->field}) and is_string($this->lang->$module->{$rawField->field})) ? sprintf($this->lang->$module->{$rawField->field}, $this->lang->dev->tableList[$module]) : '';
if((empty($field['name']) or !is_string($field['name'])) and $aliasModule) $field['name'] = isset($this->lang->$aliasModule->{$rawField->field}) ? $this->lang->$aliasModule->{$rawField->field} : '';
if($subLang) $field['name'] = isset($this->lang->$aliasModule->$subLang->{$rawField->field}) ? $this->lang->$aliasModule->$subLang->{$rawField->field} : $field['name'];
if(!is_string($field['name'])) $field['name'] = '';
+2
View File
@@ -61,9 +61,11 @@ $lang->doc->keywords = 'Tags';
$lang->doc->url = 'URL';
$lang->doc->files = 'Datei';
$lang->doc->addedBy = 'Angelegt von';
$lang->doc->addedByAB = 'Added';
$lang->doc->addedDate = 'Angelegt am';
$lang->doc->editedBy = 'Bearbeitet von';
$lang->doc->editedDate = 'Bearbeitet am';
$lang->doc->lastEditedBy = 'Last Editor';
$lang->doc->version = 'Version';
$lang->doc->basicInfo = 'Basis Info';
$lang->doc->deleted = 'Gelöscht';
+2
View File
@@ -61,9 +61,11 @@ $lang->doc->keywords = 'Tags';
$lang->doc->url = 'URL';
$lang->doc->files = 'Files';
$lang->doc->addedBy = 'Author';
$lang->doc->addedByAB = 'Added';
$lang->doc->addedDate = 'Added';
$lang->doc->editedBy = 'UpdatedBy';
$lang->doc->editedDate = 'Updated';
$lang->doc->lastEditedBy = 'Last Editor';
$lang->doc->version = 'Version';
$lang->doc->basicInfo = 'Basic Information';
$lang->doc->deleted = 'Deleted';
+2
View File
@@ -61,9 +61,11 @@ $lang->doc->keywords = 'Tags';
$lang->doc->url = 'URL';
$lang->doc->files = 'Fichiers';
$lang->doc->addedBy = 'Auteur';
$lang->doc->addedByAB = 'Added';
$lang->doc->addedDate = 'Ajouté le';
$lang->doc->editedBy = 'Màj par';
$lang->doc->editedDate = 'Màj le';
$lang->doc->lastEditedBy = 'Last Editor';
$lang->doc->version = 'Version';
$lang->doc->basicInfo = 'Infos de Base';
$lang->doc->deleted = 'Supprimé';
+2
View File
@@ -61,9 +61,11 @@ $lang->doc->keywords = '关键字';
$lang->doc->url = '文档URL';
$lang->doc->files = '附件';
$lang->doc->addedBy = '由谁添加';
$lang->doc->addedByAB = '创建者';
$lang->doc->addedDate = '添加时间';
$lang->doc->editedBy = '由谁更新';
$lang->doc->editedDate = '更新时间';
$lang->doc->lastEditedBy = '最后更新者';
$lang->doc->version = '版本号';
$lang->doc->basicInfo = '基本信息';
$lang->doc->deleted = '已删除';
+19 -16
View File
@@ -8,7 +8,7 @@ $config->execution->ownerFields = array('PO', 'PM', 'QD', 'RD');
$config->execution->defaultBurnPeriod = 30;
$config->execution->list = new stdclass();
$config->execution->list->exportFields = 'id,name,projectName,code,PM,begin,end,status,totalEstimate,totalConsumed,totalLeft,progress';
$config->execution->list->exportFields = 'id,name,projectName,PM,begin,end,status,totalEstimate,totalConsumed,totalLeft,progress';
$config->execution->modelList['scrum'] = 'sprint';
$config->execution->modelList['waterfall'] = 'stage';
@@ -135,6 +135,7 @@ $config->execution->all->search['fields']['realEnd'] = $lang->execution->
$config->execution->all->search['fields']['closedBy'] = $lang->execution->closedBy;
$config->execution->all->search['fields']['lastEditedDate'] = $lang->execution->lastEditedDate;
$config->execution->all->search['fields']['closedDate'] = $lang->execution->closedDate;
$config->execution->all->search['fields']['teamCount'] = $lang->execution->teamCount;
$config->execution->all->search['params']['name'] = array('operator' => 'include', 'control' => 'input', 'values' => '');
$config->execution->all->search['params']['id'] = array('operator' => '=', 'control' => 'input', 'values' => '');
@@ -150,6 +151,7 @@ $config->execution->all->search['params']['realEnd'] = array('operator' =
$config->execution->all->search['params']['closedBy'] = array('operator' => '=', 'control' => 'select', 'values' => 'users');
$config->execution->all->search['params']['lastEditedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
$config->execution->all->search['params']['closedDate'] = array('operator' => '=', 'control' => 'input', 'values' => '', 'class' => 'date');
$config->execution->all->search['params']['teamCount'] = array('operator' => '=', 'control' => 'input', 'values' => '');
$config->printKanban = new stdClass();
$config->printKanban->col['story'] = 1;
@@ -193,6 +195,12 @@ $config->execution->datatable->fieldList['name']['fixed'] = 'left';
$config->execution->datatable->fieldList['name']['width'] = 'auto';
$config->execution->datatable->fieldList['name']['required'] = 'yes';
$config->execution->datatable->fieldList['project']['title'] = 'project';
$config->execution->datatable->fieldList['project']['fixed'] = 'no';
$config->execution->datatable->fieldList['project']['width'] = '128';
$config->execution->datatable->fieldList['project']['required'] = 'no';
if(!isset($config->setCode) or $config->setCode == 1)
{
$config->execution->datatable->fieldList['code']['title'] = 'execCode';
@@ -201,26 +209,15 @@ if(!isset($config->setCode) or $config->setCode == 1)
$config->execution->datatable->fieldList['code']['required'] = 'no';
}
$config->execution->datatable->fieldList['project']['title'] = 'project';
$config->execution->datatable->fieldList['project']['fixed'] = 'no';
$config->execution->datatable->fieldList['project']['width'] = '100';
$config->execution->datatable->fieldList['project']['required'] = 'no';
$config->execution->datatable->fieldList['PM']['title'] = 'owner';
$config->execution->datatable->fieldList['PM']['fixed'] = 'no';
$config->execution->datatable->fieldList['PM']['width'] = '70';
$config->execution->datatable->fieldList['PM']['required'] = 'no';
$config->execution->datatable->fieldList['status']['title'] = 'execStatus';
$config->execution->datatable->fieldList['status']['fixed'] = 'no';
$config->execution->datatable->fieldList['status']['width'] = '100';
$config->execution->datatable->fieldList['status']['required'] = 'no';
$config->execution->datatable->fieldList['progress']['title'] = 'progress';
$config->execution->datatable->fieldList['progress']['fixed'] = 'no';
$config->execution->datatable->fieldList['progress']['width'] = '70';
$config->execution->datatable->fieldList['progress']['required'] = 'no';
$config->execution->datatable->fieldList['progress']['sort'] = 'no';
$config->execution->datatable->fieldList['PM']['title'] = 'owner';
$config->execution->datatable->fieldList['PM']['fixed'] = 'no';
$config->execution->datatable->fieldList['PM']['width'] = '70';
$config->execution->datatable->fieldList['PM']['required'] = 'no';
$config->execution->datatable->fieldList['openedDate']['title'] = 'openedDate';
$config->execution->datatable->fieldList['openedDate']['fixed'] = 'no';
@@ -267,6 +264,12 @@ $config->execution->datatable->fieldList['left']['width'] = '70';
$config->execution->datatable->fieldList['left']['required'] = 'no';
$config->execution->datatable->fieldList['left']['sort'] = 'no';
$config->execution->datatable->fieldList['progress']['title'] = 'progress';
$config->execution->datatable->fieldList['progress']['fixed'] = 'no';
$config->execution->datatable->fieldList['progress']['width'] = '70';
$config->execution->datatable->fieldList['progress']['required'] = 'no';
$config->execution->datatable->fieldList['progress']['sort'] = 'no';
$config->execution->datatable->fieldList['burn']['title'] = 'burn';
$config->execution->datatable->fieldList['burn']['fixed'] = 'no';
$config->execution->datatable->fieldList['burn']['width'] = '80';
+15 -5
View File
@@ -45,9 +45,14 @@ class execution extends control
$mode = $this->app->tab == 'execution' ? 'multiple' : '';
$this->executions = $this->execution->getPairs(0, 'all', "nocode,{$mode}");
$skipCreateStep = array('computeburn', 'ajaxgetdropmenu', 'executionkanban', 'ajaxgetteammembers', 'all');
if(!in_array($this->methodName, $skipCreateStep) and $this->app->tab == 'execution')
if(!in_array($this->methodName, $skipCreateStep) and $this->app->tab == 'execution' and isset($this->app->user))
{
if(!$this->executions and $this->methodName != 'index' and $this->methodName != 'create' and $this->app->getViewType() != 'mhtml') $this->locate($this->createLink('execution', 'create'));
$this->executions = $this->execution->getPairs(0, 'all', 'nocode');
$skipCreateStep = array('computeburn', 'ajaxgetdropmenu', 'executionkanban', 'ajaxgetteammembers', 'all');
if(!in_array($this->methodName, $skipCreateStep) and $this->app->tab == 'execution')
{
if(!$this->executions and $this->methodName != 'index' and $this->methodName != 'create' and $this->app->getViewType() != 'mhtml') $this->locate($this->createLink('execution', 'create'));
}
}
}
@@ -522,7 +527,10 @@ class execution extends control
$this->app->loadClass('pager', $static = true);
$recTotal = count($tasks2Imported);
$pager = new pager($recTotal, $recPerPage, $pageID);
$tasks2ImportedList = array_chunk($tasks2Imported, $pager->recPerPage, true);
$tasks2ImportedList = empty($tasks2ImportedList) ? $tasks2ImportedList : $tasks2ImportedList[$pageID - 1];
$tasks2ImportedList = $this->loadModel('task')->processTasks($tasks2ImportedList);
/* Save session. */
$this->app->session->set('taskList', $this->app->getURI(true), 'execution');
@@ -531,7 +539,7 @@ class execution extends control
$this->view->pager = $pager;
$this->view->position[] = html::a(inlink('browse', "executionID=$toExecution"), $execution->name);
$this->view->position[] = $this->lang->execution->importTask;
$this->view->tasks2Imported = empty($tasks2ImportedList) ? $tasks2ImportedList : $tasks2ImportedList[$pageID - 1];
$this->view->tasks2Imported = $tasks2ImportedList;
$this->view->executions = $executions;
$this->view->executionID = $execution->id;
$this->view->fromExecution = $fromExecution;
@@ -967,15 +975,16 @@ class execution extends control
* View a story.
*
* @param int $storyID
* @param int $executionID
* @access public
* @return void
*/
public function storyView($storyID)
public function storyView($storyID, $executionID = 0)
{
$this->session->set('productList', $this->app->getURI(true), 'product');
$story = $this->loadModel('story')->getByID($storyID);
echo $this->fetch('story', 'view', "storyID=$storyID&version=$story->version&param=" . $this->session->execution);
echo $this->fetch('story', 'view', "storyID=$storyID&version=$story->version&param=" . ($executionID ? $executionID : $this->session->execution));
}
/**
@@ -3827,6 +3836,7 @@ class execution extends control
$this->view->from = $from;
$this->view->param = $param;
$this->view->isStage = (isset($project->model) and $project->model == 'waterfall') ? true : false;
$this->view->showBatchEdit = $this->cookie->showExecutionBatchEdit;
$this->display();
}
+5 -1
View File
@@ -27,7 +27,7 @@ td.flex span.project-type-label {min-width: 40px;}
.c-name > a, .table-children .text-left > a {padding-left: 5px;}
.has-child > span {margin-right: 5px;}
.c-name > .text-ellipsis {text-overflow: clip;}
.c-code, .c-project {overflow: hidden; white-space: nowrap;}
.c-code, .c-project {overflow: hidden; white-space: nowrap; padding: 0 8px;}
th.c-status, .c-begin, .c-end, .c-realBegan, .c-realEnd {text-align: center;}
.c-project{text-overflow: unset !important;}
@@ -38,3 +38,7 @@ canvas {height: 28px;}
#datatable-executionList .table-child-bottom.table-child-top > .c-name.flex {border-bottom: 2px solid #cbd0db !important;}
#datatable-executionList .parent.has-child.c-name.flex {border-bottom: 1px solid #cbd0db !important;}
#datatable-executionList tr:last-child .c-name.flex {margin-top: 1px !important;}
.table thead .c-estimate.text-right,
.table thead .c-consumed.text-right,
.table thead .c-left.text-right {padding-right: 8px;}
+2 -1
View File
@@ -6,7 +6,8 @@
.dropdown-list > li > a {display: block; padding: 3px 20px; clear: both; font-weight: normal; line-height: 1.53846154; color: #141414; white-space: nowrap;}
.dropdown-list > li > a:hover,
.dropdown-list > li > a:focus {color: #1a4f85; text-decoration: none; background-color: #ddd;}
td.delayed {color: #fff; background: #e84e0f !important;}
.c-severity {width: 80px;}
.c-confirmed {overflow: hidden;}
.c-deadline {text-align: center;}
#main {padding-bottom: 40px;}
+6 -4
View File
@@ -20,11 +20,13 @@
.dynamic.collapsed .timeline > li + li {display: none;}
.dynamic.collapsed .dynamic-btn > .icon:before {content: '\f0d8';}
.timeline>li:before {left: -26px;}
.timeline>li+li:after {left: -23px;}
.timeline > li:before {left: -26px;}
.timeline > li + li:after {left: -23px;}
.timeline-text {margin-left: -18px;}
.label-action {padding: 0 4px;}
.label-id {margin-left: 4px;}
.timeline>li.active:before {left: -30px;}
.timeline>li>div:after {left: -27px;}
.timeline > li.active:before {left: -30px;}
.timeline > li > div:after {left: -27px;}
.timeline .timeline-text {display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
.timeline > li > div > .timeline-tag, .timeline > li > div > .timeline-text > .label-action {color: #838A9D;}
.timeline > li > div > .timeline-text > a {color: #313C52;}
-1
View File
@@ -27,4 +27,3 @@
.c-hours {white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: right;}
.c-user, .c-type {width: 70px;}
.c-progress {width: 60px;}
.delayed {background: #e84e0f !important; color: white;}
+1
View File
@@ -121,3 +121,4 @@
#kanban .kanban-affixed .kanban-header-col .title.action-dbc {pointer-events: none;}
#kanban .kanban-affixed .kanban-header-col .title.action-dbc .storyColumn .text {color: #fff;}
#kanban .kanban-affixed .kanban-header-col .title.action-dbc .storyColumn .caret {display: none;}
.kanban-card a[disabled] {color: #313c52;}
+3 -3
View File
@@ -4,6 +4,6 @@
#productsBox .product.checked:hover {background: #E5FFE6; border: 1px solid #229F24;}
#productsBox .product .checkbox-primary {padding: 9px; cursor: pointer;}
#productsBox .product.has-branch {padding-right: 40%;}
#productsBox .product.has-branch > .chosen-container {position: absolute; width: 40% !important; right: 3px; top: 3px;}
#productsBox .product.has-branch > .chosen-container > .chosen-single {background: rgba(0,0,0,.05);}
#productsBox .product.has-branch > .chosen-container > .chosen-single:hover {background: #fff;}
#productsBox .product.has-branch > .picker {position: absolute; width: 40% !important; right: 3px; top: 3px; background-color: unset;}
#productsBox .product.has-branch > .picker > .picker-selections {background: rgba(0,0,0,.05);}
#productsBox .product.has-branch > .picker > .picker-selections:hover {background: #fff;}
+1 -2
View File
@@ -1,4 +1,3 @@
td.delayed {background: #e84e0f !important; color: white;}
#int-dropdown {margin-left: -8px; border-radius: 4px; border: 1px solid #0c64eb;}
#projectTaskForm table tbody tr td {overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
.table td.c-estimate, .table td.c-consumed, .table td.c-left {padding-right: 12px;}
@@ -11,4 +10,4 @@ td.delayed {background: #e84e0f !important; color: white;}
#taskList .c-progress{padding-right: 8px; text-align: right;}
#datatable-taskList .c-progress{padding-right: 8px; text-align: right;}
.c-finishedBy, .c-lastEditedBy {overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
#executionTaskForm table tbody tr td.c-actions .dividing-line {width: 1px; height: 16px; display: inline-block; vertical-align: middle; background: #F4F5F7; margin: 0 4px 0 0;}
#executionTaskForm table tbody tr td.c-actions .dividing-line {width: 1px; height: 16px; display: inline-block; vertical-align: middle; background: #F4F5F7; margin: 0 4px 0 0;}
+1
View File
@@ -73,3 +73,4 @@
#kanbans .kanban-affixed .kanban-header-col .title.action-dbc {pointer-events: none;}
#kanbans .kanban-affixed .kanban-header-col .title.action-dbc .storyColumn .text {color: #fff;}
#kanbans .kanban-affixed .kanban-header-col .title.action-dbc .storyColumn .caret {display: none;}
.kanban-card a[disabled] {color: #313c52;}
+6 -4
View File
@@ -12,14 +12,16 @@
.block-dynamic .panel-body {height: 230px; overflow: auto; position: relative;}
.block-team div.col-xs-6 {white-space: nowrap; overflow: hidden;}
.timeline>li:before {left: -26px;}
.timeline>li+li:after {left: -23px;}
.timeline > li:before {left: -26px;}
.timeline > li + li:after {left: -23px;}
.timeline-text {margin-left: -18px;}
.block-dynamic .label-action {padding: 0 6px;}
.block-dynamic .label-action + a {padding-left: 6px;}
.timeline>li.active:before {left: -30px;}
.timeline>li>div:after {left: -27px;}
.timeline > li.active:before {left: -30px;}
.timeline > li > div:after {left: -27px;}
.timeline .timeline-text {display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
.timeline > li > div > .timeline-tag, .timeline > li > div > .timeline-text > .label-action {color: #838A9D;}
.timeline > li > div > .timeline-text > a {color: #313C52;}
#cfdChart {margin-top: -20px;}
+62 -3
View File
@@ -1,5 +1,17 @@
$(function()
{
$("#" + status + "Tab").addClass('btn-active-text');
$(document).on('click', '.plan-toggle', function(e)
{
var id = $(this).data('id');
var $toggle = $(this);
var isCollapsed = $toggle.toggleClass('collapsed').hasClass('collapsed');
$toggle.closest('#executionsForm').find('tr.parent-' + id).toggle(!isCollapsed);
e.stopPropagation();
e.preventDefault();
});
$('#executionTableList').on('sort.sortable', function(e, data)
{
var list = '';
@@ -60,6 +72,7 @@ $(function()
}
});
/* Update table summary text. */
$('#executionsForm').table(
{
statisticCreator: function(table)
@@ -67,21 +80,67 @@ $(function()
var $table = table.getTable();
var $checkedRows = $table.find(table.isDataTable ? '.datatable-row-left.checked' : 'tbody>tr.checked');
var $originTable = table.isDataTable ? table.$.find('.datatable-origin') : null;
var $rows = $table.find(table.isDataTable ? '.datatable-rows .datatable-row-left' : 'tbody>tr');
var checkedTotal = $checkedRows.length;
var $rows = checkedTotal ? $checkedRows : $table.find(table.isDataTable ? '.datatable-rows .datatable-row-left' : 'tbody>tr');
var taskIdList = [];
var checkedWait = 0;
var checkedDoing = 0;
var executionIDList = [];
$rows.each(function()
{
var $row = $(this);
if($originTable) $row = $originTable.find('tbody>tr[data-id="' + $row.data('id') + '"]');
var data = $row.data();
taskIdList.push(data.id);
executionIDList.push(data.id);
if(data.status === 'wait') checkedWait++;
if(data.status === 'doing') checkedDoing++;
});
if(status != 'all') return (checkedTotal ? checkedExecutions : executionSummary).replace('%s', $rows.length);
return (checkedTotal ? checkedSummary : pageSummary).replace('%total%', $rows.length).replace('%wait%', checkedWait).replace('%doing%', checkedDoing);
}
})
$('input[name^="showEdit"]').click(function()
{
$.cookie('showExecutionBatchEdit', $(this).is(':checked') ? 1 : 0, {expires: config.cookieLife, path: config.webRoot});
setCheckbox();
});
setCheckbox();
$('#executionTableList tr').on('click', function(e)
{
if($.cookie('showExecutionBatchEdit') != 1) e.stopPropagation();
});
});
/**
* Location to product list.
*
* @param int productID
* @param int projectID
* @param string status
* @access public
* @return void
*/
function byProduct(productID, projectID, status)
{
location.href = createLink('project', 'all', "status=" + status + "&project=" + projectID + "&orderBy=" + orderBy + '&productID=' + productID);
}
/**
* Set batch edit checkbox.
*
* @access public
* @return void
*/
function setCheckbox()
{
$('#executionsForm .checkbox-primary').hide();
$('.check-all, .sortable tr').removeClass('checked');
$(":checkbox[name^='executionIDList']").prop('checked', false);
$('#executionsForm').removeClass('has-row-checked');
if($.cookie('showExecutionBatchEdit') == 1) $('#executionsForm .checkbox-primary').show();
}
+12 -5
View File
@@ -1324,9 +1324,9 @@ function createStoryMenu(options)
var showAction = story.$col.type == 'backlog' || story.$col.type == 'ready' || story.$col.type == 'developing' || story.$col.type == 'developed' || story.$col.type == 'testing' || story.$col.type == 'tested' || story.$col.type == 'verified' || story.$col.type == 'released';
if(priv.canEditStory) items.push({label: storyLang.edit, icon: 'edit', url: createLink('story', 'edit', 'storyID=' + story.id + '&kanbanGroup=' + groupBy, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '95%'}});
if(priv.canChangeStory && showAction) items.push({label: storyLang.change, icon: 'change', url: createLink('story', 'change', 'storyID=' + story.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
if(priv.canCreateTask && showAction) items.push({label: executionLang.wbs, icon: 'plus', url: createLink('task', 'create', 'executionID=' + execution.id + '&storyID=' + story.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
if(priv.canBatchCreateTask && showAction) items.push({label: executionLang.batchWBS, icon: 'pluses', url: createLink('task', 'batchCreate', 'executionID=' + execution.id + '&storyID=' + story.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
if(priv.canChangeStory && showAction && story.status == 'active') items.push({label: storyLang.change, icon: 'change', url: createLink('story', 'change', 'storyID=' + story.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
if(priv.canCreateTask && showAction && story.status == 'active') items.push({label: executionLang.wbs, icon: 'plus', url: createLink('task', 'create', 'executionID=' + execution.id + '&storyID=' + story.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
if(priv.canBatchCreateTask && showAction && story.status == 'active') items.push({label: executionLang.batchWBS, icon: 'pluses', url: createLink('task', 'batchCreate', 'executionID=' + execution.id + '&storyID=' + story.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
if(priv.canActivateStory && story.$col.type == 'closed') items.push({label: executionLang.activate, icon: 'magic', url: createLink('story', 'activate', 'storyID=' + story.id, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
if(priv.canUnlinkStory) items.push({label: executionLang.unlinkStory, icon: 'unlink', url: createLink('execution', 'unlinkStory', 'executionID=' + execution.id + '&storyID=' + story.id, '', 'false'), attrs: {target: 'hiddenwin'}});
if(priv.canDeleteStory) items.push({label: storyLang.delete, icon: 'trash', onClick: function(){deleteCard('story', story.id, story.$lane.region)}});
@@ -1450,8 +1450,8 @@ function initKanban($kanban)
data: groupBy == 'default' ? region.groups : kanbanData[groupBy],
maxColHeight: 'auto',
calcColHeight: calcColHeight,
minColWidth: typeof window.minColWidth === 'number' ? window.minColWidth: defaultMinColWidth,
maxColWidth: typeof window.maxColWidth === 'number' ? window.maxColWidth: defaultMaxColWidth,
minColWidth: typeof window.minColWidth === 'number' ? window.minColWidth : defaultMinColWidth,
maxColWidth: typeof window.maxColWidth === 'number' ? window.maxColWidth : defaultMaxColWidth,
cardHeight: getCardHeight(),
fluidBoardWidth: fluidBoard,
displayCards: typeof window.displayCards === 'number' ? window.displayCards : 2,
@@ -1474,6 +1474,13 @@ function initKanban($kanban)
{
$.zui.ContextMenu.hide();
});
var kanbanMinColWidth = typeof window.minColWidth === 'number' ? window.minColWidth : defaultMinColWidth;
if(kanbanMinColWidth < 190)
{
var miniColWidth = kanbanMinColWidth * 0.2;
$('.kanban-header-col>.title>span:not(.text)').hide();
$('.kanban-header-col>.title > span.text').css('max-width', miniColWidth + 'px');
}
}
/**
+1 -10
View File
@@ -2,14 +2,5 @@ $(function()
{
var heightType = $("[name='heightType']:checked").val();
setCardCount(heightType);
$('#colWidth, #minColWidth, #maxColWidth').attr('onkeyup', 'value=value.match(/^\\d+$/) ? value : ""');
$('#colWidth, #minColWidth, #maxColWidth').attr('maxlength', '3');
var fluidBoard = $("#mainContent input[name='fluidBoard'][checked='checked']").val() || 0;
$('#colWidth').attr('disabled', fluidBoard == 1);
$('#minColWidth, #maxColWidth').attr('disabled', fluidBoard == 0);
$(document).on('change', "#mainContent input[name='fluidBoard']", function(e)
{
$('#colWidth').attr('disabled', e.target.value == 1);
$('#minColWidth, #maxColWidth').attr('disabled', e.target.value == 0);
})
handleKanbanWidthAttr();
});
+1 -1
View File
@@ -13,7 +13,7 @@ $(function()
adjustTableFooter();
$('body').on('click', '#toggleFold', adjustTableFooter);
$('body').on('click', '.icon.icon-angle-double-right', adjustTableFooter);
$('body').on('click', '.icon.icon-angle-right', adjustTableFooter);
/* The display of the adjusting sidebarHeader is synchronized with the sidebar. */
$(".sidebar-toggle").click(function()
+9 -2
View File
@@ -1232,8 +1232,8 @@ $(function()
var commonOptions =
{
maxColHeight: 'auto',
minColWidth: typeof window.minColWidth === 'number' ? window.minColWidth: defaultMinColWidth,
maxColWidth: typeof window.maxColWidth === 'number' ? window.maxColWidth: defaultMaxColWidth,
minColWidth: typeof window.minColWidth === 'number' ? window.minColWidth : defaultMinColWidth,
maxColWidth: typeof window.maxColWidth === 'number' ? window.maxColWidth : defaultMaxColWidth,
cardHeight: getCardHeight(),
showCount: true,
showZeroCount: true,
@@ -1373,6 +1373,13 @@ $(function()
});
}, 10000);
resetKanbanHeight();
var kanbanMinColWidth = typeof window.minColWidth === 'number' ? window.minColWidth : defaultMinColWidth;
if(kanbanMinColWidth < 190)
{
var miniColWidth = kanbanMinColWidth * 0.2;
$('.kanban-header-col>.title>span:not(.text)').hide();
$('.kanban-header-col>.title > span.text').css('max-width', miniColWidth + 'px');
}
});
$('#type').change(function()
+24
View File
@@ -0,0 +1,24 @@
$(function()
{
$('#testtaskForm').table(
{
replaceId: 'taskIdList',
statisticCreator: function(table)
{
var $table = table.getTable();
var $checkedRows = $table.find('tbody>tr.checked');
var checkedTotal = $checkedRows.length;
var checkedWait = $checkedRows.filter("[data-status=wait]").length;
var checkedTesting = $checkedRows.filter("[data-status=doing]").length;
var checkedBlocked = $checkedRows.filter("[data-status=blocked]").length;
var checkedDone = $checkedRows.filter("[data-status=done]").length;
var checkedStatistics = checkedAllSummary.replace('%total%', checkedTotal)
.replace('%wait%', checkedWait)
.replace('%testing%', checkedTesting)
.replace('%blocked%', checkedBlocked)
.replace('%done%', checkedDone);
return checkedTotal ? checkedStatistics : pageSummary;
}
});
});
+5 -1
View File
@@ -54,6 +54,7 @@ $lang->execution->end = 'Ende';
$lang->execution->dateRange = 'Dauer';
$lang->execution->realBeganAB = 'Actual Begin';
$lang->execution->realEndAB = 'Actual End';
$lang->execution->teamCount = 'Anzahl der Personen';
$lang->execution->realBegan = 'Tatsächlicher Start';
$lang->execution->realEnd = 'Tatsächliches Ende';
$lang->execution->to = 'An';
@@ -332,6 +333,9 @@ $lang->execution->stats = '<strong>%s</strong> Verfügbar, <stron
$lang->execution->taskSummary = "Aufgaben auf dieser Seite: <strong>%s</strong> Total, <strong>%s</strong> Wartend, <strong>%s</strong> In Arbeit; &nbsp;&nbsp;&nbsp; Stunden : <strong>%s</strong> geplant., <strong>%s</strong> genutzt, <strong>%s</strong> Rest.";
$lang->execution->pageSummary = "Aufgaben auf dieser Seite: <strong>%total%</strong>, <strong>%wait%</strong> Wartend, <strong>%doing%</strong> In Arbeit; Stunden: <strong>%estimate%</strong> geplant, <strong>%consumed%</strong> genutzt, <strong>%left%</strong> Rest.";
$lang->execution->checkedSummary = " <strong>%total%</strong> Geprüft, <strong>%wait%</strong> Wartend, <strong>%doing%</strong> In Arbeit; Stunden: <strong>%estimate%</strong> geplant, <strong>%consumed%</strong> genutzt, <strong>%left%</strong> Rest.";
$lang->execution->executionSummary = "Total executions: <strong>%s</strong>.";
$lang->execution->pageExecSummary = "Total executions: <strong>%total%</strong>. Waiting: <strong>%wait%</strong>. Doing: <strong>%doing%</strong>.";
$lang->execution->checkedExecSummary = "Selected: <strong>%total%</strong>. Waiting: <strong>%wait%</strong>. Doing: <strong>%doing%</strong>.";
$lang->execution->memberHoursAB = "%s hat <strong>%s</strong> Stunden";
$lang->execution->memberHours = '<div class="table-col"><div class="clearfix segments"><div class="segment"><div class="segment-title">%s Arbeitsstunden</div><div class="segment-value">%s</div></div></div></div>';
$lang->execution->countSummary = '<div class="table-col"><div class="clearfix segments"><div class="segment"><div class="segment-title">Aufgaben</div><div class="segment-value">%s</div></div><div class="segment"><div class="segment-title">In Arbeit</div><div class="segment-value"><span class="label label-dot label-primary"></span> %s</div></div><div class="segment"><div class="segment-title">Wait</div><div class="segment-value"><span class="label label-dot label-primary muted"></span> %s</div></div></div></div>';
@@ -405,7 +409,7 @@ $lang->execution->storyDragError = "The {$lang->SRCommon} is not ac
$lang->execution->countTip = ' (%s member)';
$lang->execution->pleaseInput = "Enter";
$lang->execution->week = 'week';
$lang->execution->checkedExecutions = 'Seleted %s items';
$lang->execution->checkedExecutions = "Seleted %s {$lang->executionCommon}.";
/* Statistics. */
$lang->execution->charts = new stdclass();
+5 -1
View File
@@ -54,6 +54,7 @@ $lang->execution->end = 'Planned End';
$lang->execution->dateRange = 'Plan Duration';
$lang->execution->realBeganAB = 'Actual Begin';
$lang->execution->realEndAB = 'Actual End';
$lang->execution->teamCount = 'number of people';
$lang->execution->realBegan = 'Actual Begin';
$lang->execution->realEnd = 'Actual End';
$lang->execution->to = 'To';
@@ -332,6 +333,9 @@ $lang->execution->stats = 'Available: <strong>%s</strong>(h). Est
$lang->execution->taskSummary = "Total tasks on this page:<strong>%s</strong>. Waiting: <strong>%s</strong>. Doing: <strong>%s</strong>. &nbsp;&nbsp;&nbsp; Estimates: <strong>%s</strong>(h). Cost: <strong>%s</strong>(h). Left: <strong>%s</strong>(h).";
$lang->execution->pageSummary = "Total tasks: <strong>%total%</strong>. Waiting: <strong>%wait%</strong>. Doing: <strong>%doing%</strong>. Estimates: <strong>%estimate%</strong>(h). Cost: <strong>%consumed%</strong>(h). Left: <strong>%left%</strong>(h).";
$lang->execution->checkedSummary = "Selected: <strong>%total%</strong>. Waiting: <strong>%wait%</strong>. Doing: <strong>%doing%</strong>. Estimates: <strong>%estimate%</strong>(h). Cost: <strong>%consumed%</strong>(h). Left: <strong>%left%</strong>(h).";
$lang->execution->executionSummary = "Total {$lang->executionCommon}: <strong>%s</strong>.";
$lang->execution->pageExecSummary = "Total {$lang->executionCommon}: <strong>%total%</strong>. Waiting: <strong>%wait%</strong>. Doing: <strong>%doing%</strong>.";
$lang->execution->checkedExecSummary = "Selected: <strong>%total%</strong>. Waiting: <strong>%wait%</strong>. Doing: <strong>%doing%</strong>.";
$lang->execution->memberHoursAB = "%s has <strong>%s</ strong> hours.";
$lang->execution->memberHours = '<div class="table-col"><div class="clearfix segments"><div class="segment"><div class="segment-title">%s Available Hours</div><div class="segment-value">%s</div></div></div></div>';
$lang->execution->countSummary = '<div class="table-col"><div class="clearfix segments"><div class="segment"><div class="segment-title">Tasks</div><div class="segment-value">%s</div></div><div class="segment"><div class="segment-title">Doing</div><div class="segment-value"><span class="label label-dot label-primary"></span> %s</div></div><div class="segment"><div class="segment-title">Waiting</div><div class="segment-value"><span class="label label-dot label-primary muted"></span> %s</div></div></div></div>';
@@ -405,7 +409,7 @@ $lang->execution->storyDragError = "The {$lang->SRCommon} is not ac
$lang->execution->countTip = ' (%s member)';
$lang->execution->pleaseInput = "Enter";
$lang->execution->week = 'week';
$lang->execution->checkedExecutions = 'Seleted %s items';
$lang->execution->checkedExecutions = "Seleted %s {$lang->executionCommon}.";
/* Statistics. */
$lang->execution->charts = new stdclass();
+5 -1
View File
@@ -54,6 +54,7 @@ $lang->execution->end = 'Fin';
$lang->execution->dateRange = 'Durée';
$lang->execution->realBeganAB = 'Actual Begin';
$lang->execution->realEndAB = 'Actual End';
$lang->execution->teamCount = 'nombre de personnes';
$lang->execution->realBegan = 'Début effectif';
$lang->execution->realEnd = 'Clôture effective';
$lang->execution->to = 'à';
@@ -332,6 +333,9 @@ $lang->execution->stats = 'Disponible: <strong>%s</strong>(h). Es
$lang->execution->taskSummary = "Total des tâches de cette page :<strong>%s</strong>. A Faire: <strong>%s</strong>. En cours: <strong>%s</strong>. &nbsp;&nbsp;&nbsp; Estimé: <strong>%s</strong>(h). Coût: <strong>%s</strong>(h). Reste: <strong>%s</strong>(h).";
$lang->execution->pageSummary = "Total des tâches de cette page: <strong>%total%</strong>. A Faire: <strong>%wait%</strong>. En cours: <strong>%doing%</strong>. &nbsp;&nbsp;&nbsp; Estimé: <strong>%estimate%</strong>(h). Coût: <strong>%consumed%</strong>(h). Reste: <strong>%left%</strong>(h).";
$lang->execution->checkedSummary = "Sélectionné: <strong>%total%</strong>. A Faire: <strong>%wait%</strong>. En cours: <strong>%doing%</strong>. &nbsp;&nbsp;&nbsp; Estimé: <strong>%estimate%</strong>(h). Coût: <strong>%consumed%</strong>(h). Reste: <strong>%left%</strong>(h).";
$lang->execution->executionSummary = "Total executions: <strong>%s</strong>.";
$lang->execution->pageExecSummary = "Total executions: <strong>%total%</strong>. Waiting: <strong>%wait%</strong>. Doing: <strong>%doing%</strong>.";
$lang->execution->checkedExecSummary = "Selected: <strong>%total%</strong>. Waiting: <strong>%wait%</strong>. Doing: <strong>%doing%</strong>.";
$lang->execution->memberHoursAB = "%s a <strong>%s</ strong> heures.";
$lang->execution->memberHours = '<div class="table-col"><div class="clearfix segments"><div class="segment"><div class="segment-title">%s Heures Disponibles</div><div class="segment-value">%s</div></div></div></div>';
$lang->execution->countSummary = '<div class="table-col"><div class="clearfix segments"><div class="segment"><div class="segment-title">Tâches</div><div class="segment-value">%s</div></div><div class="segment"><div class="segment-title">En Cours</div><div class="segment-value"><span class="label label-dot label-primary"></span> %s</div></div><div class="segment"><div class="segment-title">A Faire</div><div class="segment-value"><span class="label label-dot label-primary muted"></span> %s</div></div></div></div>';
@@ -405,7 +409,7 @@ $lang->execution->storyDragError = "The {$lang->SRCommon} is not ac
$lang->execution->countTip = ' (%s member)';
$lang->execution->pleaseInput = "Enter";
$lang->execution->week = 'week';
$lang->execution->checkedExecutions = "Pour s électionner l'élément%s";
$lang->execution->checkedExecutions = "Pour s électionner l'élément%s.";
/* Statistics. */
$lang->execution->charts = new stdclass();
+1
View File
@@ -54,6 +54,7 @@ $lang->execution->RD = 'Quản lý phát hành';
$lang->execution->release = 'Phát hành';
$lang->execution->acl = 'Quyền truy cập';
$lang->execution->teamname = 'Tên đội nhóm';
$lang->execution->teamCount = 'số người';
$lang->execution->order = "Đánh giá {$lang->executionCommon}";
$lang->execution->orderAB = "Đánh giá";
$lang->execution->products = "Liên kết {$lang->productCommon}";
+5 -1
View File
@@ -54,6 +54,7 @@ $lang->execution->end = '计划完成';
$lang->execution->dateRange = '计划起止日期';
$lang->execution->realBeganAB = '实际开始';
$lang->execution->realEndAB = '实际完成';
$lang->execution->teamCount = '人数';
$lang->execution->realBegan = '实际开始日期';
$lang->execution->realEnd = '实际完成日期';
$lang->execution->to = '至';
@@ -332,6 +333,9 @@ $lang->execution->stats = '可用工时 <strong>%s</strong> 工
$lang->execution->taskSummary = "本页共 <strong>%s</strong> 个任务,未开始 <strong>%s</strong>,进行中 <strong>%s</strong>,总预计 <strong>%s</strong> 工时,已消耗 <strong>%s</strong> 工时,剩余 <strong>%s</strong> 工时。";
$lang->execution->pageSummary = "本页共 <strong>%total%</strong> 个任务,未开始 <strong>%wait%</strong>,进行中 <strong>%doing%</strong>,总预计 <strong>%estimate%</strong> 工时,已消耗 <strong>%consumed%</strong> 工时,剩余 <strong>%left%</strong> 工时。";
$lang->execution->checkedSummary = "选中 <strong>%total%</strong> 个任务,未开始 <strong>%wait%</strong>,进行中 <strong>%doing%</strong>,总预计 <strong>%estimate%</strong> 工时,已消耗 <strong>%consumed%</strong> 工时,剩余 <strong>%left%</strong> 工时。";
$lang->execution->executionSummary = "本页共 <strong>%s</strong> 个{$lang->executionCommon}。";
$lang->execution->pageExecSummary = "本页共 <strong>%total%</strong> 个{$lang->executionCommon},未开始 <strong>%wait%</strong>,进行中 <strong>%doing%</strong>。";
$lang->execution->checkedExecSummary = "选中 <strong>%total%</strong> 个{$lang->executionCommon},未开始 <strong>%wait%</strong>,进行中 <strong>%doing%</strong>。";
$lang->execution->memberHoursAB = "<div>%s有 <strong>%s</strong> 工时</div>";
$lang->execution->memberHours = '<div class="table-col"><div class="clearfix segments"><div class="segment"><div class="segment-title">%s可用工时</div><div class="segment-value">%s</div></div></div></div>';
$lang->execution->countSummary = '<div class="table-col"><div class="clearfix segments"><div class="segment"><div class="segment-title">总任务</div><div class="segment-value">%s</div></div><div class="segment"><div class="segment-title">进行中</div><div class="segment-value"><span class="label label-dot label-primary"></span> %s</div></div><div class="segment"><div class="segment-title">未开始</div><div class="segment-value"><span class="label label-dot label-primary muted"></span> %s</div></div></div></div>';
@@ -405,7 +409,7 @@ $lang->execution->storyDragError = "该{$lang->SRCommon}不是激
$lang->execution->countTip = '(%s人)';
$lang->execution->pleaseInput = "请输入";
$lang->execution->week = '周';
$lang->execution->checkedExecutions = '已选择%s项';
$lang->execution->checkedExecutions = "共选中%s个{$lang->executionCommon}。";
/* 统计。*/
$lang->execution->charts = new stdclass();
+1
View File
@@ -54,6 +54,7 @@ $lang->execution->execPM = "{$lang->execution->common}負責人";
$lang->execution->QD = '測試負責人';
$lang->execution->RD = '發佈負責人';
$lang->execution->release = '發佈';
$lang->execution->teamCount = '人數';
$lang->execution->acl = '訪問控制';
$lang->execution->teamname = '團隊名稱';
$lang->execution->updateOrder = '排序';
+48 -20
View File
@@ -109,6 +109,16 @@ class executionModel extends model
unset($this->lang->execution->menu->build);
}
$stageFilter = array('request', 'design', 'review');
if(isset($execution->attribute))
{
if($this->config->edition == 'open' and in_array($execution->attribute, $stageFilter))
{
unset($this->lang->execution->menu->qa);
unset($this->lang->execution->menu->build);
}
}
if($executions and (!isset($executions[$executionID]) or !$this->checkPriv($executionID))) $this->accessDenied();
$moduleName = $this->app->getModuleName();
@@ -360,7 +370,7 @@ class executionModel extends model
}
/* Check the workload format and total. */
if(!empty($sprint->percent)) $this->checkWorkload('create', $sprint->percent);
if(!empty($sprint->percent)) $this->checkWorkload('create', $sprint->percent, $sprint->project);
/* Set planDuration and realDuration. */
if($this->config->edition == 'max')
@@ -1137,7 +1147,7 @@ class executionModel extends model
->batchCheck($this->config->kanban->edit->requiredFields, 'notempty')
->checkIF(!$execution->fluidBoard, 'colWidth', 'gt', 0)
->batchCheckIF($execution->fluidBoard, 'minColWidth,maxColWidth', 'gt', 0)
->checkIF($execution->minColWidth and $execution->maxColWidth and $execution->fluidBoard, 'maxColWidth', 'ge', $kanban->minColWidth)
->checkIF($execution->minColWidth and $execution->maxColWidth and $execution->fluidBoard, 'maxColWidth', 'gt', $execution->minColWidth)
->where('id')->eq((int)$executionID)
->exec();
}
@@ -1145,9 +1155,9 @@ class executionModel extends model
/**
* Check the workload format and total.
*
* @param string $type create|update
* @param int $percent
* @param object $oldExecution
* @param string $type create|update
* @param int $percent
* @param object|int $oldExecution
* @access public
* @return bool
*/
@@ -1168,7 +1178,7 @@ class executionModel extends model
->andWhere('t2.type')->eq('stage')
->andWhere('t2.grade')->eq(1)
->andWhere('t2.deleted')->eq(0)
->andWhere('t2.parent')->eq($oldExecution->parent)
->andWhere('t2.parent')->eq($oldExecution)
->fetch('total');
if($type == 'create') $percentTotal = $percent + $oldPercentTotal;
@@ -1551,6 +1561,15 @@ class executionModel extends model
$hours = $this->loadModel('project')->computerProgress($executions);
$burns = $this->getBurnData($executions);
/* Get the number of execution teams. */
$teams = $this->dao->select('t1.root,count(t1.id) as teams')->from(TABLE_TEAM)->alias('t1')
->leftJoin(TABLE_USER)->alias('t2')->on('t1.account=t2.account')
->where('t1.root')->in(array_keys($executions))
->andWhere('t1.type')->ne('project')
->andWhere('t2.deleted')->eq(0)
->groupBy('t1.root')
->fetchAll('root');
if($withTasks) $executionTasks = $this->getTaskGroupByExecution(array_keys($executions));
/* Process executions. */
@@ -1577,6 +1596,7 @@ class executionModel extends model
/* Process the hours. */
$execution->hours = isset($hours[$execution->id]) ? $hours[$execution->id] : (object)$emptyHour;
$execution->teamCount = isset($teams[$execution->id]) ? $teams[$execution->id]->teams : 0;
if(isset($executionTasks) and isset($executionTasks[$execution->id]))
{
@@ -4273,7 +4293,7 @@ class executionModel extends model
$days = count($dateList) - 1;
$rate = $days ? $firstTime / $days : '';
$baselineJSON = '[';
foreach($dateList as $i => $date) $baselineJSON .= round(($days - $i) * (float)$rate, 1) . ',';
foreach($dateList as $i => $date) $baselineJSON .= round(($days - $i) * (float)$rate, 3) . ',';
$baselineJSON = rtrim($baselineJSON, ',') . ']';
$chartData['labels'] = $this->report->convertFormat($dateList, DT_DATE5);
@@ -4616,25 +4636,24 @@ class executionModel extends model
if(!$isChild)
{
$trClass = 'is-top-level table-nest-child-hide';
$trAttrs = "data-id='$execution->id' data-order='$execution->order' data-nested='true'";
$trAttrs = "data-id='$execution->id' data-order='$execution->order' data-nested='true' data-status={$execution->status}";
}
else
{
$trClass = 'table-nest-hide';
$trAttrs = "data-id={$execution->id} data-parent={$execution->parent}";
$trAttrs = "data-id={$execution->id} data-parent={$execution->parent} data-status={$execution->status}";
$trAttrs .= " data-nest-parent='$execution->parent' data-order='$execution->order' data-nest-path=',$execution->parent,$execution->id,'";
}
$burns = join(',', $execution->burns);
echo "<tr $trAttrs class='$trClass'>";
echo "<td><span id=$execution->id class='table-nest-icon icon table-nest-toggle'></span>";
echo "<td class='c-name text-left flex sort-handler'>";
if(common::hasPriv('execution', 'batchEdit')) echo "<span id=$execution->id class='table-nest-icon icon table-nest-toggle'></span>";
$spanClass = $execution->type == 'stage' ? 'label-warning' : 'label-info';
echo "<span class='project-type-label label label-outline $spanClass'>{$this->lang->execution->typeList[$execution->type]}</span> ";
if(empty($execution->children))
{
echo html::a(helper::createLink('execution', 'view', "executionID=$execution->id"), $execution->name);
echo html::a(helper::createLink('execution', 'view', "executionID=$execution->id"), $execution->name, '', 'class="text-ellipsis"');
if(!helper::isZeroDate($execution->end))
{
if($execution->status != 'closed')
@@ -4645,7 +4664,7 @@ class executionModel extends model
}
else
{
echo $execution->name;
echo "<span class='text-ellipsis'>" . $execution->name . '</span>';
if(!helper::isZeroDate($execution->end))
{
if($execution->status != 'closed')
@@ -4654,14 +4673,14 @@ class executionModel extends model
}
}
}
echo '<td>' . zget($users, $execution->PM) . '</td>';
echo "<td class='status-{$execution->status} text-center'>" . zget($this->lang->project->statusList, $execution->status) . '</td>';
echo '<td>' . html::ring($execution->hours->progress) . '</td>';
echo '<td>' . zget($users, $execution->PM) . '</td>';
echo helper::isZeroDate($execution->begin) ? '<td class="c-date"></td>' : '<td class="c-date">' . $execution->begin . '</td>';
echo helper::isZeroDate($execution->end) ? '<td class="c-date"></td>' : '<td class="c-date">' . $execution->end . '</td>';
echo "<td class='hours' title='{$execution->hours->totalEstimate}{$this->lang->execution->workHour}'>" . $execution->hours->totalEstimate . $this->lang->execution->workHourUnit . '</td>';
echo "<td class='hours' title='{$execution->hours->totalConsumed}{$this->lang->execution->workHour}'>" . $execution->hours->totalConsumed . $this->lang->execution->workHourUnit . '</td>';
echo "<td class='hours' title='{$execution->hours->totalLeft}{$this->lang->execution->workHour}'>" . $execution->hours->totalLeft . $this->lang->execution->workHourUnit . '</td>';
echo "<td class='hours text-right' title='{$execution->hours->totalEstimate}{$this->lang->execution->workHour}'>" . $execution->hours->totalEstimate . $this->lang->execution->workHourUnit . '</td>';
echo "<td class='hours text-right' title='{$execution->hours->totalConsumed}{$this->lang->execution->workHour}'>" . $execution->hours->totalConsumed . $this->lang->execution->workHourUnit . '</td>';
echo "<td class='hours text-right' title='{$execution->hours->totalLeft}{$this->lang->execution->workHour}'>" . $execution->hours->totalLeft . $this->lang->execution->workHourUnit . '</td>';
echo '<td>' . html::ring($execution->hours->progress) . '</td>';
echo "<td id='spark-{$execution->id}' class='sparkline text-left no-padding' values='$burns'></td>";
echo '<td class="c-actions">';
common::printIcon('execution', 'start', "executionID={$execution->id}", $execution, 'list', '', '', 'iframe', true);
@@ -4874,6 +4893,12 @@ class executionModel extends model
if(!empty($execution->children)) $class .= ' has-child';
}
if($id == 'teamCount')
{
$title = " title='{$execution->teamCount}'";
$class .= ' text-right';
}
if($id == 'project') $title = " title='{$execution->projectName}'";
if($id == 'code') $title = " title='{$execution->code}'";
@@ -4915,7 +4940,7 @@ class executionModel extends model
if(isset($execution->delay)) echo "<span class='label label-danger label-badge'>{$this->lang->execution->delayed}</span> ";
if(!empty($execution->children))
{
echo "<a class='plan-toggle' data-id='$execution->id'><i class='icon icon-angle-double-right'></i></a>";
echo "<a class='plan-toggle' data-id='$execution->id'><i class='icon icon-angle-right'></i></a>";
}
break;
case 'code':
@@ -4942,6 +4967,9 @@ class executionModel extends model
case 'begin':
echo helper::isZeroDate($execution->begin) ? '' : $execution->begin;
break;
case 'teamCount':
echo $execution->teamCount;
break;
case 'end':
echo helper::isZeroDate($execution->end) ? '' : $execution->end;
break;
+17 -21
View File
@@ -16,17 +16,26 @@
$datatableId = $this->moduleName . ucfirst($this->methodName);
$useDatatable = (isset($config->datatable->$datatableId->mode) and $config->datatable->$datatableId->mode == 'datatable');
?>
<?php js::set('unfoldExecutions', array());?>
<?php js::set('useDatatable', $useDatatable);?>
<?php js::set('from', $from);?>
<?php
js::set('unfoldExecutions', array());
js::set('useDatatable', $useDatatable);
js::set('from', $from);
/* Replace Iteration to Execution. */
js::set('checkedSummary', str_replace($lang->executionCommon, $lang->execution->common, $lang->execution->checkedExecSummary));
js::set('pageSummary', str_replace($lang->executionCommon, $lang->execution->common, $lang->execution->pageExecSummary));
js::set('executionSummary', str_replace($lang->executionCommon, $lang->execution->common, $lang->execution->executionSummary));
js::set('checkedExecutions', str_replace($lang->executionCommon, $lang->execution->common, $lang->execution->checkedExecutions));
?>
<?php
/* Set unfold parent executionID. */
js::set('unfoldAll', $lang->execution->treeLevel['all']);
js::set('foldAll', $lang->execution->treeLevel['root']);
js::set('isCNLang', !$this->loadModel('common')->checkNotCN())
?>
<?php $canBatchEdit = common::hasPriv('execution', 'batchEdit');?>
<div id='mainMenu' class='clearfix'>
<div class='btn-toolbar pull-left'>
<div class='btn-toolBar pull-left'>
<?php if($from == 'project'):?>
<div class='btn-group'>
<?php $viewName = $productID != 0 ? zget($productList,$productID) : $lang->product->allProduct;?>
@@ -51,6 +60,7 @@ js::set('isCNLang', !$this->loadModel('common')->checkNotCN())
<?php if($status == $key) $label .= " <span class='label label-light label-badge'>{$pager->recTotal}</span>";?>
<?php echo html::a($this->createLink($this->app->rawModule, $this->app->rawMethod, "status=$key&orderBy=$orderBy&productID=$productID"), $label, '', "class='btn btn-link' id='{$key}Tab' data-app='$from'");?>
<?php endforeach;?>
<?php if($canBatchEdit) echo html::checkbox('showEdit', array('1' => $lang->execution->editAction), $showBatchEdit);?>
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php echo $lang->execution->byQuery;?></a>
</div>
<div class='btn-toolbar pull-right'>
@@ -72,8 +82,7 @@ js::set('isCNLang', !$this->loadModel('common')->checkNotCN())
</p>
</div>
<?php else:?>
<?php $canBatchEdit = common::hasPriv('execution', 'batchEdit'); ?>
<form class='main-table' id='executionsForm' method='post' action='<?php echo inLink('batchEdit');?>' <?php if(!$useDatatable) echo "data-ride='table'";?>>
<form class='main-table' id='executionsForm' method='post' action='<?php echo inLink('batchEdit');?>'>
<div class="table-header fixed-right">
<nav class="btn-toolbar pull-right setting"></nav>
</div>
@@ -104,7 +113,7 @@ js::set('isCNLang', !$this->loadModel('common')->checkNotCN())
</thead>
<tbody class='sortable' id='executionTableList'>
<?php foreach($executionStats as $execution):?>
<tr data-id='<?php echo $execution->id ?>' data-order='<?php echo $execution->order ?>'>
<tr data-id='<?php echo $execution->id ?>' data-order='<?php echo $execution->order ?>' data-status='<?php echo $execution->status?>'>
<?php foreach($setting as $key => $value) $this->execution->printCell($value, $execution, $users, $useDatatable ? 'datatable' : 'table', $isStage, $productID);?>
</tr>
<?php if(!empty($execution->children)):?>
@@ -128,28 +137,15 @@ js::set('isCNLang', !$this->loadModel('common')->checkNotCN())
<div class="checkbox-primary check-all"><label><?php echo $lang->selectAll?></label></div>
<div class="table-actions btn-toolbar">
<?php echo html::submitButton($lang->execution->batchEdit, '', 'btn');?>
<div class="table-statistic"></div>
</div>
<?php endif;?>
<div class="table-statistic"></div>
<?php $pager->show('right', 'pagerjs');?>
</div>
<?php endif;?>
</form>
<?php endif;?>
</div>
<script>
$("#<?php echo $status;?>Tab").addClass('btn-active-text');
$(document).on('click', '.plan-toggle', function(e)
{
var $toggle = $(this);
var id = $(this).data('id');
var isCollapsed = $toggle.toggleClass('collapsed').hasClass('collapsed');
$toggle.closest('[data-ride="table"]').find('tr.parent-' + id).toggle(!isCollapsed);
e.stopPropagation();
e.preventDefault();
});
</script>
<?php js::set('orderBy', $orderBy)?>
<?php js::set('status', $status)?>
<?php include '../../common/view/footer.html.php';?>
+2
View File
@@ -51,6 +51,7 @@
<th class="c-id-sm"><?php echo $lang->build->id;?></th>
<th class="c-name w-200px text-left <?php echo $hidden;?>"><?php echo $lang->build->product;?></th>
<th class="c-name text-left"><?php echo $lang->build->name;?></th>
<th class="c-name w-200px text-left"><?php echo $lang->build->product;?></th>
<th class="c-url"><?php echo $lang->build->scmPath;?></th>
<th class="c-url"><?php echo $lang->build->filePath;?></th>
<th class="c-date"><?php echo $lang->build->date;?></th>
@@ -68,6 +69,7 @@
<?php if($build->branchName) echo "<span class='label label-outline label-badge'>{$build->branchName}</span>"?>
<?php echo html::a($this->createLink('build', 'view', "build=$build->id"), $build->name);?>
</td>
<td class="c-name text-left" title='<?php echo $build->productName;?>'><?php echo $build->productName;?></td>
<td class="c-url" title="<?php echo $build->scmPath?>"><?php echo strpos($build->scmPath, 'http') === 0 ? html::a($build->scmPath) : $build->scmPath;?></td>
<td class="c-url" title="<?php echo $build->filePath?>"><?php echo strpos($build->filePath, 'http') === 0 ? html::a($build->filePath) : $build->filePath;?></td>
<td class="c-date"><?php echo $build->date?></td>
+2 -2
View File
@@ -122,7 +122,7 @@
<th class="c-hours"><?php echo $lang->task->leftAB;?></th>
<th class="c-progress" title='<?php echo $lang->task->progress;?>'><?php echo $lang->task->progressAB;?></th>
<th class="c-type"><?php echo $lang->typeAB;?></th>
<th class="c-date"><?php echo $lang->task->deadlineAB;?></th>
<th class="c-date text-center"><?php echo $lang->task->deadlineAB;?></th>
<th class="c-actions-3"><?php echo $lang->actions;?></th>
</tr>
</thead>
@@ -207,7 +207,7 @@
<td class="c-hours em" title="<?php echo $task->left . ' ' . $lang->execution->workHour;?>"><?php echo $task->left . $lang->execution->workHourUnit;?></td>
<td class="c-num em"><?php echo $task->progress . '%';?></td>
<td class="c-type"><?php echo zget($lang->task->typeList, $task->type);?></td>
<td class='c-date <?php if(isset($task->delay)) echo 'delayed';?>'><?php if(substr($task->deadline, 0, 4) > 0) echo substr($task->deadline, 5, 6);?></td>
<td class='c-date text-center <?php if(isset($task->delay)) echo 'delayed';?>'><?php if(substr($task->deadline, 0, 4) > 0) echo '<span>' . substr($task->deadline, 5, 6) . '</span>';?></td>
<td class="c-actions">
<?php if(common::canModify('execution', $execution)):?>
<?php common::printIcon('task', 'assignTo', "executionID=$task->execution&taskID=$task->id", $task, 'list', '', '', 'iframe', true);?>
+2 -2
View File
@@ -42,7 +42,7 @@
<?php endif;?>
<th class='c-user'><?php echo $lang->task->assignedTo;?></th>
<th class='c-hour'><?php echo $lang->task->leftAB;?></th>
<th class='c-date'><?php echo $lang->task->deadlineAB;?></th>
<th class='c-date text-center'><?php echo $lang->task->deadlineAB;?></th>
<th class='c-status'><?php echo $lang->statusAB;?></th>
<th class='c-story'><?php echo $lang->task->story;?></th>
</tr>
@@ -63,7 +63,7 @@
<td class='text-left nobr'><?php if(!common::printLink('task', 'view', "task=$task->id", $task->name, '', "class='preview iframe' data-width='90%'", true, true)) echo $task->name;?></td>
<td <?php echo $class;?>><?php echo $task->assignedToRealName;?></td>
<td title="<?php echo $task->left . ' ' . $lang->execution->workHour;?>"><?php echo $task->left . ' ' . $lang->execution->workHourUnit;?></td>
<td class=<?php if(isset($task->delay)) echo 'delayed';?>><?php if(substr($task->deadline, 0, 4) > 0) echo $task->deadline;?></td>
<td class="text-center <?php if(isset($task->delay)) echo 'delayed';?>"><?php if(substr($task->deadline, 0, 4) > 0) echo '<span>' . $task->deadline . '</span>';?></td>
<td><span class='status-task status-<?php echo $task->status;?>'><?php echo $this->processStatus('task', $task);?></span></td>
<td class='text-left text-ellipsis' title="<?php echo $task->storyTitle;?>">
<?php

Some files were not shown because too many files have changed in this diff Show More