Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms into sprint/244_tianshujie_70498

This commit is contained in:
曹延义
2022-10-10 16:56:50 +08:00
201 changed files with 2461 additions and 1107 deletions
+34 -26
View File
@@ -1,12 +1,13 @@
stages:
- sonar
- unit_test
- uitest
- notify
- cleanup_packages
- sonarqube
- unit-test
- ui-test
- package
sonarqube:
stage: sonar
- cleanup-packages
- notify
program-static-analysis:
stage: sonarqube
variables:
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache
GIT_DEPTH: "0" # Tells git to fetch all the branches of the project, required by the analysis task
@@ -19,6 +20,25 @@ sonarqube:
allow_failure: true
only:
- master # or the name of your main branch
unit-test:
stage: unit-test
script:
- "/home/gitlab-runner/bin/zentao-unittest.sh ${CI_PROJECT_DIR}"
allow_failure: true
only:
- master
- merge_requests
ui-test:
stage: ui-test
script:
- "/home/gitlab-runner/bin/zentao-uitest.sh ${CI_PROJECT_DIR}"
allow_failure: true
only:
- master
- merge_requests
package:
stage: package
script:
@@ -26,22 +46,15 @@ package:
allow_failure: true
only:
- master
unit_test:
stage: unit_test
cleanup-packages:
stage: cleanup-packages
script:
- "/home/gitlab-runner/bin/zentao-unittest.sh ${CI_PROJECT_DIR}"
allow_failure: true
- make clean
when: on_failure
only:
- master
- merge_requests
uitest:
stage: uitest
script:
- "/home/gitlab-runner/bin/zentao-uitest.sh ${CI_PROJECT_DIR}"
allow_failure: true
only:
- master
- merge_requests
notify:
stage: notify
script:
@@ -49,9 +62,4 @@ notify:
when: on_success
only:
- master
- merge_requests
cleanup_packages:
stage: cleanup_packages
script:
- make clean
when: on_failure
- merge_requests
+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. Its 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, its 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 dont 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
@@ -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
@@ -24,7 +24,7 @@ class releasesEntry extends entry
if(empty($productID)) return $this->sendError(400, 'Need product id.');
$control = $this->loadController('release', 'browse');
$control->browse($productID, $this->param('branch', 0), $this->param('status', 'all'), $this->param('order', 't1.date_desc'));
$control->browse($productID, $this->param('branch', 0), $this->param('status', 'all'), $this->param('order', 't1.date_desc'), 0, $this->param('limit', 20), $this->param('page', 1));
/* Response */
$data = $this->getData();
+5
View File
@@ -97,6 +97,11 @@ $config->domainPostfix .= "|international|house|coffee|florist|rich|ceo|camp|edu
$config->CSPs = array();
$config->CSPs[] = "form-action 'self';connect-src 'self'";
/* Config for kanban col setting */
$config->colWidth = 264;
$config->minColWidth = 180;
$config->maxColWidth = 384;
/* 系统框架配置。Framework settings. */
$config->framework = new stdclass();
$config->framework->autoConnectDB = true; // 是否自动连接数据库。 Whether auto connect database or not.
+10 -8
View File
@@ -172,6 +172,7 @@ $filter->tree->browse = new stdclass();
$filter->productplan->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,14 +301,15 @@ $filter->productplan->browse->cookie['viewType'] = 'code';
$filter->task->create->cookie['lastTaskModule'] = 'int';
$filter->task->export->cookie['checkedItem'] = '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';
+6
View File
@@ -0,0 +1,6 @@
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`;
+6
View File
@@ -835,6 +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',
`object` varchar(255) NOT NULL,
`alignment` varchar(10) NOT NULL default 'center',
`createdBy` char(30) NOT NULL,
@@ -1193,6 +1196,9 @@ CREATE TABLE IF NOT EXISTS `zt_project` (
`vision` varchar(10) NOT NULL DEFAULT 'rnd',
`displayCards` smallint(6) NOT NULL default '0',
`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',
`deleted` enum('0','1') NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `parent` (`parent`),
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

+24 -4
View File
@@ -35,8 +35,15 @@
</div>
<?php else:?>
<form id='myTaskForm' class="main-table table-task skip-iframe-modal" method="post">
<?php $canBatchEdit = (common::hasPriv('task', 'batchEdit') and $type == 'assignedTo');?>
<?php $canBatchClose = (common::hasPriv('task', 'batchClose') and $type != 'closedBy');?>
<?php
$canBatchEdit = (common::hasPriv('task', 'batchEdit') and $type == 'assignedTo');
$canBatchClose = (common::hasPriv('task', 'batchClose') and $type != 'closedBy');
$canFinish = common::hasPriv('task', 'finish');
$canClose = common::hasPriv('task', 'close');
$canRecordEstimate = common::hasPriv('task', 'recordEstimate');
$canEdit = common::hasPriv('task', 'edit');
$canBatchCreate = common::hasPriv('task', 'batchCreate');
?>
<table class="table has-sort-head table-fixed" id='taskTable'>
<?php $vars = "mode=$mode&type=$type&orderBy=%s&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"; ?>
<thead>
@@ -134,10 +141,16 @@
}
else
{
$canStart = ($task->status != 'pause' and common::hasPriv('task', 'start'));
$canRestart = ($task->status == 'pause' and common::hasPriv('task', 'restart'));
if($task->status != 'pause') common::printIcon('task', 'start', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, '', '', $task->project);
if($task->status == 'pause') common::printIcon('task', 'restart', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, '', '', $task->project);
common::printIcon('task', 'close', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, '', '', $task->project);
common::printIcon('task', 'finish', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, '', '', $task->project);
common::printIcon('task', 'close', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, '', '', $task->project);
if(($canStart or $canRestart or $canFinish or $canClose) and ($canRecordEstimate or $canEdit or $canBatchCreate))
{
echo "<div class='dividing-line'></div>";
}
common::printIcon('task', 'recordEstimate', "taskID=$task->id", $task, 'list', 'time', '', 'iframe', true, '', '', $task->project);
common::printIcon('task', 'edit', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, "data-width='95%'", '', $task->project);
@@ -198,10 +211,17 @@
}
else
{
$canStart = ($child->status != 'pause' and common::hasPriv('task', 'start'));
$canRestart = ($child->status == 'pause' and common::hasPriv('task', 'restart'));
if($child->status != 'pause') common::printIcon('task', 'start', "taskID=$child->id", $child, 'list', '', '', 'iframe', true, '', '', $child->project);
if($child->status == 'pause') common::printIcon('task', 'restart', "taskID=$child->id", $child, 'list', '', '', 'iframe', true, '', '', $child->project);
common::printIcon('task', 'close', "taskID=$child->id", $child, 'list', '', '', 'iframe', true, '', '', $child->project);
common::printIcon('task', 'finish', "taskID=$child->id", $child, 'list', '', '', 'iframe', true, '', '', $child->project);
common::printIcon('task', 'close', "taskID=$child->id", $child, 'list', '', '', 'iframe', true, '', '', $child->project);
if(($canStart or $canRestart or $canFinish or $canClose) and ($canRecordEstimate or $canEdit or $canBatchCreate))
{
echo "<div class='dividing-line'></div>";
}
common::printIcon('task', 'recordEstimate', "taskID=$child->id", $child, 'list', 'time', '', 'iframe', true, '', '', $child->project);
common::printIcon('task', 'edit', "taskID=$child->id", $child, 'list', '', '', '', '', '', '', $child->project);
@@ -21,7 +21,6 @@
<?php js::set('teamMemberError', $lang->task->error->teamMember);?>
<?php js::set('estimateNotEmpty', sprintf($lang->error->gt, $lang->task->estimate, '0'))?>
<?php if(!empty($storyID)):?>
<style> .title-group.required > .required:after {right: 110px;}</style>
<?php endif;?>
<div id='mainContent' class='main-content'>
<div class='center-block'>
+10 -2
View File
@@ -996,7 +996,15 @@ class baseRouter
if($writable)
{
$ztSessionHandler = new ztSessionHandler($_GET['tid']);
session_set_save_handler($ztSessionHandler, true);
session_set_save_handler(
array($ztSessionHandler, "open"),
array($ztSessionHandler, "close"),
array($ztSessionHandler, "read"),
array($ztSessionHandler, "write"),
array($ztSessionHandler, "destroy"),
array($ztSessionHandler, "gc")
);
register_shutdown_function('session_write_close');
}
}
@@ -3140,7 +3148,7 @@ class EndResponseException extends \Exception
*
* @package framework
*/
class ztSessionHandler implements SessionHandlerInterface
class ztSessionHandler
{
public $sessSavePath;
public $tagID;
+1 -1
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, ";
+72 -72
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,
@@ -159,7 +159,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';
@@ -174,6 +174,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';
@@ -186,16 +192,10 @@ $config->bug->datatable->fieldList['pri']['width'] = '50';
$config->bug->datatable->fieldList['pri']['required'] = 'no';
$config->bug->datatable->fieldList['pri']['name'] = $lang->bug->pri;
$config->bug->datatable->fieldList['confirmed']['title'] = 'confirmedAB';
$config->bug->datatable->fieldList['confirmed']['fixed'] = 'left';
$config->bug->datatable->fieldList['confirmed']['width'] = '100';
$config->bug->datatable->fieldList['confirmed']['required'] = 'no';
$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['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';
@@ -230,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';
@@ -283,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';
+4 -8
View File
@@ -966,14 +966,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()));
}
}
@@ -1158,6 +1152,7 @@ class bug extends control
$branch = $product->type == 'branch' ? ($bug->branch > 0 ? $bug->branch . ',0' : '0') : '';
$productBugs = $this->bug->getProductBugPairs($productID, $branch);
unset($productBugs[$bugID]);
$this->view->bug = $bug;
$this->view->productID = $productID;
@@ -1814,6 +1809,7 @@ class bug extends control
$product = $this->loadModel('product')->getById($productID);
$branch = $product->type == 'branch' ? ($bug->branch > 0 ? $bug->branch . ',0' : '0') : '';
$productBugs = $this->bug->getProductBugPairs($productID, $branch);
unset($productBugs[$bugID]);
$this->bug->checkBugExecutionPriv($bug);
$this->qa->setMenu($this->products, $productID, $bug->branch);
-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;}
+5 -2
View File
@@ -754,7 +754,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);
}
@@ -3297,6 +3297,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';
@@ -3440,7 +3443,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);
+5 -1
View File
@@ -143,7 +143,11 @@
<tr>
<td class='pd-0'><?php echo html::select("resolutions[$bugID]", $resolutionList, $bug->resolution, "class='form-control' onchange=setDuplicate(this.value,$bugID)");?></td>
<td class='pd-0 w-p50' id='<?php echo 'duplicateBugBox' . $bugID;?>' <?php if($bug->resolution != 'duplicate') echo "style='display:none'";?>>
<?php echo html::select("duplicateBugs[$bugID]", $productBugList[$bug->product][$bug->branch], $bug->duplicateBug, "class='form-control' placeholder='{$lang->bug->duplicateTip}'");?>
<?php
$productBugs = $productBugList[$bug->product][$bug->branch];
if(isset($productBugs[$bug->id])) unset($productBugs[$bug->id]);
?>
<?php echo html::select("duplicateBugs[$bugID]", $productBugs, $bug->duplicateBug, "class='form-control' placeholder='{$lang->bug->duplicateTip}'");?>
</td>
</tr>
</table>
+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 = '名稱';
-1
View File
@@ -67,7 +67,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')
+13 -9
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;
@@ -173,17 +175,13 @@ $config->execution->gantt->linkType['end']['end'] = 2;
$config->execution->gantt->linkType['begin']['end'] = 3;
$config->execution->datatable = new stdclass();
if((!isset($config->setCode) or $config->setCode == 1) and $config->systemMode == 'new')
if($config->systemMode == 'new')
{
$config->execution->datatable->defaultField = array('id', 'name', 'code', 'project', 'PM', 'status', 'progress', 'begin', 'end', 'estimate', 'consumed', 'left', 'burn');
}
elseif($config->systemMode == 'new')
{
$config->execution->datatable->defaultField = array('id', 'name', 'project', 'PM', 'status', 'progress', 'begin', 'end', 'estimate', 'consumed', 'left', 'burn');
$config->execution->datatable->defaultField = array('id', 'name', 'project', 'status', 'PM', 'begin', 'end', 'estimate', 'consumed', 'left', 'progress', 'burn');
}
else
{
$config->execution->datatable->defaultField = array('id', 'name', 'PM', 'status', 'progress', 'begin', 'end', 'estimate', 'consumed', 'left', 'burn');
$config->execution->datatable->defaultField = array('id', 'name', 'status', 'PM', 'begin', 'end', 'estimate', 'consumed', 'left', 'progress', 'burn');
}
$config->execution->datatable->fieldList['id']['title'] = 'idAB';
@@ -208,7 +206,7 @@ if($config->systemMode == 'new')
{
$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']['width'] = '128';
$config->execution->datatable->fieldList['project']['required'] = 'no';
}
@@ -255,6 +253,12 @@ $config->execution->datatable->fieldList['realEnd']['width'] = '90';
$config->execution->datatable->fieldList['realEnd']['required'] = 'no';
$config->execution->datatable->fieldList['realEnd']['sort'] = 'no';
$config->execution->datatable->fieldList['teamCount']['title'] = 'teamCount';
$config->execution->datatable->fieldList['teamCount']['fixed'] = 'no';
$config->execution->datatable->fieldList['teamCount']['width'] = '80';
$config->execution->datatable->fieldList['teamCount']['required'] = 'no';
$config->execution->datatable->fieldList['teamCount']['sort'] = 'no';
$config->execution->datatable->fieldList['estimate']['title'] = 'estimate';
$config->execution->datatable->fieldList['estimate']['fixed'] = 'no';
$config->execution->datatable->fieldList['estimate']['width'] = '70';
+2 -1
View File
@@ -3183,7 +3183,7 @@ class execution extends control
{
$this->project->setMenu($object->id);
}
elseif($object->type == 'sprint' or $object->type == 'stage')
elseif($object->type == 'sprint' or $object->type == 'stage' or $object->type == 'kanban')
{
$this->execution->setMenu($object->id);
}
@@ -3760,6 +3760,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;}
+1 -1
View File
@@ -6,7 +6,7 @@
.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;}
-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 -1
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,3 +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;}
+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;}
+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: 240,
maxColWidth: 240,
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
View File
@@ -2,4 +2,5 @@ $(function()
{
var heightType = $("[name='heightType']:checked").val();
setCardCount(heightType);
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: 240,
maxColWidth: 240,
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()
+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';
@@ -341,6 +342,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>';
@@ -415,7 +419,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';
@@ -341,6 +342,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>';
@@ -415,7 +419,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 = 'à';
@@ -341,6 +342,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>';
@@ -415,7 +419,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 = '至';
@@ -341,6 +342,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>';
@@ -415,7 +419,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 = '排序';
+40 -9
View File
@@ -1130,7 +1130,18 @@ class executionModel extends model
if(isset($_POST['heightType']) and $this->post->heightType == 'custom' and !$this->loadModel('kanban')->checkDisplayCards($execution->displayCards)) return;
$this->dao->update(TABLE_EXECUTION)->data($execution)->where('id')->eq((int)$executionID)->exec();
$this->app->loadLang('kanban');
$this->lang->project->colWidth = $this->lang->kanban->colWidth;
$this->lang->project->minColWidth = $this->lang->kanban->minColWidth;
$this->lang->project->maxColWidth = $this->lang->kanban->maxColWidth;
$this->dao->update(TABLE_EXECUTION)->data($execution)
->autoCheck()
->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', 'gt', $execution->minColWidth)
->where('id')->eq((int)$executionID)
->exec();
}
/**
@@ -1520,6 +1531,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. */
@@ -1546,6 +1566,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]))
{
@@ -4571,18 +4592,19 @@ 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>";
if($this->config->systemMode == 'new')
{
$spanClass = $execution->type == 'stage' ? 'label-warning' : 'label-info';
@@ -4615,9 +4637,9 @@ class executionModel extends model
echo '<td>' . html::ring($execution->hours->progress) . '</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 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);
@@ -4830,6 +4852,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}'";
@@ -4865,13 +4893,13 @@ class executionModel extends model
case 'name':
$label = $execution->type == 'stage' ? 'label-warning' : 'label-info';
$executionLink = $execution->projectModel == 'kanban' ? html::a(helper::createLink('execution', 'kanban', 'executionID=' . $execution->id), $execution->name, '', "class='text-ellipsis'") : html::a(helper::createLink('execution', 'task', 'execution=' . $execution->id), $execution->name, '', "class='text-ellipsis'");
if(!$onlyChildStage) echo "<span class='project-type-label label label-outline $label'>{$this->lang->execution->typeList[$execution->type]}</span>";
if($this->config->systemMode != 'classic' and !$onlyChildStage) echo "<span class='project-type-label label label-outline $label'>{$this->lang->execution->typeList[$execution->type]}</span>";
if($onlyChildStage) echo "<span class='label label-badge label-light label-children'>{$this->lang->programplan->childrenAB}</span> ";
echo !empty($execution->children) ? "<span class='text-ellipsis'>$execution->name</span>" : $executionLink;
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':
@@ -4898,6 +4926,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>
@@ -106,7 +115,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)):?>
@@ -130,28 +139,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';?>
+4
View File
@@ -179,6 +179,9 @@
<td id="plansBox" colspan="2">
<div class='row'>
<?php $i = 0;?>
<?php if(empty($linkedProducts)):?>
<div class="col-sm-4" id="plan0"><?php echo html::select("plans[][][]", $productPlans, '', "class='form-control chosen' multiple");?></div>
<?php else:?>
<?php foreach($linkedProducts as $product):?>
<?php foreach($linkedBranches[$product->id] as $branchID => $branch):?>
<?php $plans = isset($productPlans[$product->id][$branchID]) ? $productPlans[$product->id][$branchID] : array();?>
@@ -186,6 +189,7 @@
<?php $i++;?>
<?php endforeach;?>
<?php endforeach;?>
<?php endif;?>
</div>
</td>
</tr>
+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
+4
View File
@@ -47,6 +47,8 @@ js::set('entertime', time());
js::set('displayCards', $execution->displayCards);
js::set('productNum', $productNum);
js::set('fluidBoard', $execution->fluidBoard);
js::set('minColWidth', $execution->fluidBoard == '0' ? $execution->colWidth : $execution->minColWidth);
js::set('maxColWidth',$execution->fluidBoard == '0' ? $execution->colWidth : $execution->maxColWidth);
js::set('colorListLang', $lang->kanbancard->colorList);
js::set('colorList', $this->config->kanban->cardColorList);
js::set('projectID', $projectID);
@@ -56,6 +58,8 @@ js::set('executionID', $execution->id);
js::set('needLinkProducts', $lang->execution->needLinkProducts);
js::set('lastUpdateData', '');
js::set('rdSearchValue', '');
js::set('defaultMinColWidth', $this->config->minColWidth);
js::set('defaultMaxColWidth', $this->config->maxColWidth);
$canSortRegion = commonModel::hasPriv('kanban', 'sortRegion') && count($regions) > 1;
$canCreateRegion = (common::hasPriv('kanban', 'createRegion') and $groupBy == 'default');
@@ -39,7 +39,7 @@
<?php echo "<input type='checkbox' name='products[$i]' value='$productID' $checked $attr id='products{$productID}'>";?>
<label class='text-ellipsis checkbox-inline' for='<?php echo 'products' . $productID;?>' title='<?php echo $productName;?>'><?php echo $productName;?></label>
</div>
<?php if(isset($allBranches[$productID][$branchID])) echo html::select("branch[$i]", $allBranches[$productID], $branchID, "class='form-control chosen' disabled='disabled'");?>
<?php if(isset($allBranches[$productID][$branchID])) echo html::select("branch[$i]", $allBranches[$productID], $branchID, "class='form-control picker-select' disabled='disabled'");?>
</div>
</div>
<?php if(!empty($attr)) echo html::hidden("products[$i]", $productID);?>
@@ -64,7 +64,7 @@
<?php echo "<input type='checkbox' name='products[$i]' value='$productID' id='products{$productID}'>";?>
<label class='text-ellipsis checkbox-inline' for='<?php echo 'products' . $productID;?>'><?php echo $productName;?></label>
</div>
<?php if(isset($branchGroups[$productID])) echo html::select("branch[$i]", $branchGroups[$productID], '', "class='form-control chosen'");?>
<?php if(isset($branchGroups[$productID])) echo html::select("branch[$i]", $branchGroups[$productID], '', "class='form-control picker-select'");?>
</div>
</div>
<?php $i++;?>
@@ -88,7 +88,7 @@
<?php echo "<input type='checkbox' name='products[$i]' value='$productID' id='products{$productID}'>";?>
<label class='text-ellipsis checkbox-inline' for='<?php echo 'products' . $productID;?>'><?php echo $productName;?></label>
</div>
<?php if(isset($branchGroups[$productID])) echo html::select("branch[$i]", $branchGroups[$productID], '', "class='form-control chosen'");?>
<?php if(isset($branchGroups[$productID])) echo html::select("branch[$i]", $branchGroups[$productID], '', "class='form-control picker-select'");?>
</div>
</div>
<?php $i++;?>
+12 -1
View File
@@ -22,7 +22,18 @@
<table class='table table-form'>
<tr>
<th><?php echo $lang->kanban->columnWidth;?></th>
<td colspan='2'><?php echo nl2br(html::radio('fluidBoard', $lang->kanbancolumn->fluidBoardList, $execution->fluidBoard));?></td>
<td colspan='2'>
<div class="width-radio-row">
<?php echo html::radio('fluidBoard', array(0 => $lang->kanbancolumn->fluidBoardList['0']), "class='inline-block'", $execution->fluidBoard);?>
<?php echo html::input('colWidth', !empty($execution->colWidth) ? $execution->colWidth : $this->config->colWidth, "class='form-control inline-block setting-input' placeholder='{$this->config->colWidth}' autocomplete='off'");?>px
</div>
<div class="width-radio-row mt10">
<?php echo html::radio('fluidBoard', array(1 => $lang->kanbancolumn->fluidBoardList['1']), "class='inline-block'", $execution->fluidBoard);?>
<?php echo html::input('minColWidth', !empty($execution->minColWidth) ? $execution->minColWidth: $this->config->minColWidth, "class='form-control inline-block setting-input' placeholder='{$this->config->minColWidth}' autocomplete='off'");?>px
<span class="input-divider">~</span>
<?php echo html::input('maxColWidth', !empty($execution->maxColWidth) ? $execution->maxColWidth: $this->config->maxColWidth, "class='form-control inline-block setting-input' placeholder='{$this->config->maxColWidth}' autocomplete='off'");?>px
</div>
</td>
</tr>
<?php if($laneCount > 1):?>
<tr>
+2 -2
View File
@@ -403,7 +403,7 @@ body {margin-bottom: 25px;}
<script>
$(function()
{
// Update table summary text
/* Update table summary text. */
var checkedSummary = '<?php echo $lang->execution->checkedSummary?>';
var pageSummary = '<?php echo $lang->execution->pageSummary?>';
$('#executionTaskForm').table(
@@ -425,7 +425,7 @@ $(function()
$rows.each(function()
{
var $row = $(this);
if ($originTable)
if($originTable)
{
$row = $originTable.find('tbody>tr[data-id="' + $row.data('id') + '"]');
}
+5 -1
View File
@@ -71,7 +71,7 @@
</div>
<?php
$width = common::checkNotCN() ? '600px' : '470px';
$width = common::checkNotCN() ? '600px' : '560px';
echo "<div class='btn-group menu-actions'>";
echo html::a('javascript:;', "<i class='icon icon-ellipsis-v'></i>", '', "data-toggle='dropdown' class='btn btn-link'");
echo "<ul class='dropdown-menu pull-right'>";
@@ -223,8 +223,12 @@ js::set('priv',
<?php js::set('userList', $userList);?>
<?php js::set('entertime', time());?>
<?php js::set('fluidBoard', $execution->fluidBoard);?>
<?php js::set('minColWidth', $execution->fluidBoard == '0' ? $execution->colWidth : $execution->minColWidth);?>
<?php js::set('maxColWidth',$execution->fluidBoard == '0' ? $execution->colWidth : $execution->maxColWidth);?>
<?php js::set('displayCards', $execution->displayCards);?>
<?php js::set('needLinkProducts', $lang->execution->needLinkProducts);?>
<?php js::set('hourUnit', $config->hourUnit);?>
<?php js::set('orderBy', $storyOrder);?>
<?php js::set('defaultMinColWidth', $this->config->minColWidth);?>
<?php js::set('defaultMaxColWidth', $this->config->maxColWidth);?>
<?php include '../../common/view/footer.html.php';?>
+10 -10
View File
@@ -13,7 +13,7 @@
</div>
</div>
<div class="btn-toolbar pull-left">
<?php echo html::a(inlink('testcase', "executionID=$executionID&productID=$productID&branchID=$branchID&type=$type&moduleID=$moduleID&orderBy=$orderBy"), "<span class='text'>{$lang->execution->featureBar['all']['all']}</span>", '', "class='btn btn-link btn-active-text'");?>
<?php echo html::a(inlink('testcase', "executionID=$executionID&productID=$productID&branchID=$branchID&type=$type&moduleID=$moduleID&orderBy=$orderBy"), "<span class='text'>{$lang->execution->featureBar['all']['all']}</span> <span class='label label-light label-badge'>{$pager->recTotal}</span>", '', "class='btn btn-link btn-active-text'");?>
</div>
<div class="btn-toolbar pull-right">
<?php if(common::canModify('execution', $execution)) echo html::a(helper::createLink('testcase', 'create', "productID=$productID&branch=0&moduleID=0&from=execution&param=$execution->id", '', '', '', true), "<i class='icon icon-plus'></i> " . $lang->testcase->create, '', "class='btn btn-primary' data-app='{$this->app->tab}'");?>
@@ -49,14 +49,14 @@
<thead>
<tr>
<th class='w-id'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th class='c-pri' title=<?php echo $lang->execution->pri;?>> <?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th> <?php common::printOrderLink('title', $orderBy, $vars, $lang->testcase->title);?></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-pri'> <?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='c-type'> <?php common::printOrderLink('type', $orderBy, $vars, $lang->testcase->type);?></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->testcase->openedByAB);?></th>
<th class='c-user'> <?php common::printOrderLink('lastRunner', $orderBy, $vars, $lang->testtask->lastRunAccount);?></th>
<th class='c-date'> <?php common::printOrderLink('lastRunDate', $orderBy, $vars, $lang->testtask->lastRunTime);?></th>
<th class='c-result'><?php common::printOrderLink('lastRunResult', $orderBy, $vars, $lang->testtask->lastRunResult);?></th>
<th class='c-status'><?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-actions-6 text-center'><?php echo $lang->actions;?></th>
</tr>
</thead>
@@ -70,15 +70,11 @@
<td class="c-id">
<?php echo sprintf('%03d', $case->id); ?>
</td>
<td><span class='label-pri <?php echo 'label-pri-' . $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>
<?php $params = "testcaseID=$caseID&version=$case->version";?>
<?php if($type == 'assigntome') $params .= "&from=testtask&taskID=$case->task";?>
<td class='c-title text-left' title="<?php echo $case->title?>"><?php echo html::a($this->createLink('testcase', 'view', $params, '', '', $case->project), $case->title, null, "style='color: $case->color' data-app='{$this->app->tab}'");?></td>
<td><span class='label-pri <?php echo 'label-pri-' . $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 zget($lang->testcase->typeList, $case->type);?></td>
<td><?php echo zget($users, $case->openedBy);?></td>
<td><?php echo zget($users, $case->lastRunner);?></td>
<td><?php if(!helper::isZeroDate($case->lastRunDate)) echo substr($case->lastRunDate, 5, 11);?></td>
<td class='<?php echo $case->lastRunResult;?>'><?php if($case->lastRunResult) echo $lang->testcase->resultList[$case->lastRunResult];?></td>
<td>
<?php
if($case->needconfirm)
@@ -95,6 +91,10 @@
}
?>
</td>
<td><?php echo zget($users, $case->openedBy);?></td>
<td><?php echo zget($users, $case->lastRunner);?></td>
<td><?php if(!helper::isZeroDate($case->lastRunDate)) echo substr($case->lastRunDate, 5, 11);?></td>
<td class='<?php echo $case->lastRunResult;?>'><?php if($case->lastRunResult) echo $lang->testcase->resultList[$case->lastRunResult];?></td>
<td class='c-actions'>
<?php
$case->browseType = $type;
+1
View File
@@ -49,6 +49,7 @@ $(function()
{
setCopyKanban($(this).data('id')); $('#copyKanbanModal').modal('hide');
});
handleKanbanWidthAttr();
})
/**
+1
View File
@@ -39,6 +39,7 @@ $(function()
return false;
}
})
handleKanbanWidthAttr();
})
/**
+10 -2
View File
@@ -1399,8 +1399,8 @@ function initKanban($kanban)
maxColHeight: 510,
calcColHeight: calcColHeight,
fluidBoardWidth: fluidBoard,
minColWidth: 285,
maxColWidth: 285,
minColWidth: typeof window.minColWidth === 'number' ? window.minColWidth : defaultMinColWidth,
maxColWidth: typeof window.maxColWidth === 'number' ? window.maxColWidth : defaultMaxColWidth,
cardHeight: cardHeight,
displayCards: typeof window.displayCards === 'number' ? window.displayCards : 2,
createColumnText: kanbanLang.createColumn,
@@ -1428,6 +1428,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');
}
}
/**
@@ -1559,6 +1566,7 @@ $(function()
distance = 0;
radiusWidth = 10;
initRegionTabs();
$('.leftBtn').click(function()
{
+5 -2
View File
@@ -89,6 +89,9 @@ $lang->kanban->allProducts = 'All Products';
$lang->kanban->mine = 'Mine';
$lang->kanban->alignment = 'Alignment';
$lang->kanban->allUsers = 'Alle Benutzer laden';
$lang->kanban->colWidth = 'Column Width';
$lang->kanban->minColWidth = 'Min Column Width';
$lang->kanban->maxColWidth = 'Max Column Width';
/* Fields. */
$lang->kanban->space = 'Space';
@@ -351,8 +354,8 @@ $lang->kanbanlane->modeList['independent'] = 'Independent Kanban column';
$lang->kanbanlane->heightTypeList['auto'] = "Adaptive <span class='tip'>(Adaptive to card height and lane name height)</span>";
$lang->kanbanlane->heightTypeList['custom'] = "Custom <span class='tip'>(Customize lane height based on number of cards)</span>";
$lang->kanbancolumn->fluidBoardList['0'] = "Fixed<span class='tip'>(Keep all columns the same width)</span>";
$lang->kanbancolumn->fluidBoardList['1'] = "Auto Width<span class='tip'>(Adapts to lane width)</span>";
$lang->kanbancolumn->fluidBoardList['0'] = "Fixed<i class='radio-text-divider'></i>Width";
$lang->kanbancolumn->fluidBoardList['1'] = "Auto Width<i class='radio-text-divider'></i>Column width range";
$lang->kanbanlane->error = new stdclass();
$lang->kanbanlane->error->mustBeInt = 'No. of cards must be a positive integer from 3 to 32767.';
+5 -2
View File
@@ -89,6 +89,9 @@ $lang->kanban->allProducts = 'All Products';
$lang->kanban->mine = 'Mine';
$lang->kanban->alignment = 'Alignment';
$lang->kanban->allUsers = 'Load All Users';
$lang->kanban->colWidth = 'Column Width';
$lang->kanban->minColWidth = 'Min Column Width';
$lang->kanban->maxColWidth = 'Max Column Width';
/* Fields. */
$lang->kanban->space = 'Space';
@@ -351,8 +354,8 @@ $lang->kanbanlane->modeList['independent'] = 'Independent Kanban column';
$lang->kanbanlane->heightTypeList['auto'] = "Adaptive <span class='tip'>(Adaptive to card height and lane name height)</span>";
$lang->kanbanlane->heightTypeList['custom'] = "Custom <span class='tip'>(Customize lane height based on number of cards)</span>";
$lang->kanbancolumn->fluidBoardList['0'] = "Fixed<span class='tip'>(Keep all columns the same width)</span>";
$lang->kanbancolumn->fluidBoardList['1'] = "Auto Width<span class='tip'>(Adapts to lane width)</span>";
$lang->kanbancolumn->fluidBoardList['0'] = "Fixed<i class='radio-text-divider'></i>Width";
$lang->kanbancolumn->fluidBoardList['1'] = "Auto Width<i class='radio-text-divider'></i>Column width range";
$lang->kanbanlane->error = new stdclass();
$lang->kanbanlane->error->mustBeInt = 'No. of cards must be a positive integer from 3 to 32767.';
+5 -2
View File
@@ -89,6 +89,9 @@ $lang->kanban->allProducts = 'All Products';
$lang->kanban->mine = 'Mine';
$lang->kanban->alignment = 'Alignment';
$lang->kanban->allUsers = 'Charger Tous';
$lang->kanban->colWidth = 'Column Width';
$lang->kanban->minColWidth = 'Min Column Width';
$lang->kanban->maxColWidth = 'Max Column Width';
/* Fields. */
$lang->kanban->space = 'Space';
@@ -351,8 +354,8 @@ $lang->kanbanlane->modeList['independent'] = 'Independent Kanban column';
$lang->kanbanlane->heightTypeList['auto'] = "Adaptive <span class='tip'>(Adaptive to card height and lane name height)</span>";
$lang->kanbanlane->heightTypeList['custom'] = "Custom <span class='tip'>(Customize lane height based on number of cards)</span>";
$lang->kanbancolumn->fluidBoardList['0'] = "Fixed<span class='tip'>(Largeur standard pour toutes les colonnes)</span>";
$lang->kanbancolumn->fluidBoardList['1'] = "Auto Width<span class='tip'>(Adapter selon la largeur de voie)</span>";
$lang->kanbancolumn->fluidBoardList['0'] = "Fixed<i class='radio-text-divider'></i>Width";
$lang->kanbancolumn->fluidBoardList['1'] = "Auto Width<i class='radio-text-divider'></i>Column width range";
$lang->kanbanlane->error = new stdclass();
$lang->kanbanlane->error->mustBeInt = 'Nb de cartes doit être un entier positif compris entre 3 et 32767.';
+5 -2
View File
@@ -89,6 +89,9 @@ $lang->kanban->allProducts = '所有产品';
$lang->kanban->mine = '我负责';
$lang->kanban->alignment = '列标题对齐方式';
$lang->kanban->allUsers = '加载所有用户';
$lang->kanban->colWidth = '列宽';
$lang->kanban->minColWidth = '最小列宽';
$lang->kanban->maxColWidth = '最大列宽';
/* Fields. */
$lang->kanban->space = '所属空间';
@@ -351,8 +354,8 @@ $lang->kanbanlane->modeList['independent'] = '采用独立的看板列';
$lang->kanbanlane->heightTypeList['auto'] = "自适应<span class='tip'>(根据卡片高度和泳道名称高度自适应)</span>";
$lang->kanbanlane->heightTypeList['custom'] = "自定义<span class='tip'>(根据卡片数量自定义泳道高度)</span>";
$lang->kanbancolumn->fluidBoardList['0'] = "固定列宽<span class='tip'>(所有列保持一致的宽度)</span>";
$lang->kanbancolumn->fluidBoardList['1'] = "自适应列宽<span class='tip'>(根据泳道宽度自适应)</span>";
$lang->kanbancolumn->fluidBoardList['0'] = "固定列宽<i class='radio-text-divider'></i>宽度";
$lang->kanbancolumn->fluidBoardList['1'] = "自适应列宽<i class='radio-text-divider'></i>列宽范围";
$lang->kanbanlane->error = new stdclass();
$lang->kanbanlane->error->mustBeInt = '卡片数量必须是 3~32767 的正整数。';
+10 -11
View File
@@ -1366,12 +1366,12 @@ class kanbanModel extends model
$cardData['openedDate'] = $object->openedDate;
$cardData['closedDate'] = $object->closedDate;
$cardData['lastEditedDate'] = $object->lastEditedDate;
$cardData['status'] = $object->status;
if($cell->type == 'task')
{
if($searchValue != '' and strpos($object->name, $searchValue) === false) continue;
$cardData['name'] = $object->name;
$cardData['status'] = $object->status;
$cardData['left'] = $object->left;
$cardData['estStarted'] = $object->estStarted;
}
@@ -2237,6 +2237,9 @@ class kanbanModel extends model
$this->dao->insert(TABLE_KANBAN)->data($kanban)
->autoCheck()
->batchCheck($this->config->kanban->create->requiredFields, 'notempty')
->checkIF(!$kanban->fluidBoard, 'colWidth', 'gt', 0)
->batchCheckIF($kanban->fluidBoard, 'minColWidth,maxColWidth', 'gt', 0)
->checkIF($kanban->minColWidth and $kanban->maxColWidth and $kanban->fluidBoard, 'maxColWidth', 'gt', $kanban->minColWidth)
->check('name', 'unique', "space = {$kanban->space}")
->exec();
@@ -2336,24 +2339,20 @@ class kanbanModel extends model
->get();
if($this->post->import == 'on') $kanban->object = implode(',', $this->post->importObjectList);
if(isset($_POST['heightType']) and $this->post->heightType == 'custom')
{
if(!$this->checkDisplayCards($kanban->displayCards)) return;
}
if(isset($_POST['heightType']) and $this->post->heightType == 'custom' and !$this->checkDisplayCards($kanban->displayCards)) return;
$this->dao->update(TABLE_KANBAN)->data($kanban)
->autoCheck()
->batchCheck($this->config->kanban->edit->requiredFields, 'notempty')
->checkIF(!$kanban->fluidBoard, 'colWidth', 'gt', 0)
->batchCheckIF($kanban->fluidBoard, 'minColWidth,maxColWidth', 'gt', 0)
->checkIF($kanban->minColWidth and $kanban->maxColWidth and $kanban->fluidBoard, 'maxColWidth', 'gt', $kanban->minColWidth)
->where('id')->eq($kanbanID)
->exec();
if(!dao::isError())
{
return common::createChanges($oldKanban, $kanban);
}
if(dao::isError()) return false;
return false;
return common::createChanges($oldKanban, $kanban);
}
/**
+12 -1
View File
@@ -66,7 +66,18 @@
<?php endif;?>
<tr>
<th class='columnWidth'><?php echo $lang->kanban->columnWidth;?></th>
<td colspan='2'><?php echo nl2br(html::radio('fluidBoard', $lang->kanbancolumn->fluidBoardList, isset($copyKanban->fluidBoard) ? $copyKanban->fluidBoard : 0));?></td>
<td colspan='2'>
<div class="width-radio-row">
<?php echo html::radio('fluidBoard', array(0 => $lang->kanbancolumn->fluidBoardList['0']), isset($copyKanban->fluidBoard) ? $copyKanban->fluidBoard : 0);?>
<?php echo html::input('colWidth', !empty($copyKanban->colWidth) ? $copyKanban->colWidth : $this->config->colWidth, "class='form-control inline-block setting-input' placeholder='{$this->config->colWidth}' autocomplete='off'");?>px
</div>
<div class="width-radio-row mt10">
<?php echo html::radio('fluidBoard', array(1 => $lang->kanbancolumn->fluidBoardList['1']), isset($copyKanban->fluidBoard) ? $copyKanban->fluidBoard : 0);?>
<?php echo html::input('minColWidth', !empty($copyKanban->minColWidth) ? $copyKanban->minColWidth: $this->config->minColWidth, "class='form-control inline-block setting-input' placeholder='{$this->config->minColWidth}' autocomplete='off'");?>px
<span class="input-divider">~</span>
<?php echo html::input('maxColWidth', !empty($copyKanban->maxColWidth) ? $copyKanban->maxColWidth: $this->config->maxColWidth, "class='form-control inline-block setting-input' placeholder='{$this->config->maxColWidth}' autocomplete='off'");?>px
</div>
</td>
</tr>
<tr>
<th rowspan='2'><?php echo $lang->kanban->import?></th>
+12 -1
View File
@@ -27,7 +27,18 @@
</tr>
<tr>
<th class='columnWidth'><?php echo $lang->kanban->columnWidth;?></th>
<td colspan='2'><?php echo nl2br(html::radio('fluidBoard', $lang->kanbancolumn->fluidBoardList, $kanban->fluidBoard));?></td>
<td colspan='2'>
<div class="width-radio-row">
<?php echo html::radio('fluidBoard', array(0 => $lang->kanbancolumn->fluidBoardList['0']), $kanban->fluidBoard);?>
<?php echo html::input('colWidth', !empty($kanban->colWidth) ? $kanban->colWidth : $this->config->colWidth, "class='form-control inline-block setting-input' placeholder='{$this->config->colWidth}' autocomplete='off'");?>px
</div>
<div class="width-radio-row mt10">
<?php echo html::radio('fluidBoard', array(1 => $lang->kanbancolumn->fluidBoardList['1']), $kanban->fluidBoard);?>
<?php echo html::input('minColWidth', !empty($kanban->minColWidth) ? $kanban->minColWidth : $this->config->minColWidth, "class='form-control inline-block setting-input' placeholder='{$this->config->minColWidth}' autocomplete='off'");?>px
<span class="input-divider">~</span>
<?php echo html::input('maxColWidth', !empty($kanban->maxColWidth) ? $kanban->maxColWidth : $this->config->maxColWidth, "class='form-control inline-block setting-input' placeholder='{$this->config->maxColWidth}' autocomplete='off'");?>px
</div>
</td>
</tr>
<?php if($laneCount > 1):?>
<tr>
+4
View File
@@ -41,8 +41,12 @@ js::set('colorListLang', $lang->kanbancard->colorList);
js::set('colorList', $this->config->kanban->cardColorList);
js::set('displayCards', $kanban->displayCards);
js::set('fluidBoard', $kanban->fluidBoard);
js::set('minColWidth', $kanban->fluidBoard == '0' ? $kanban->colWidth : $kanban->minColWidth);
js::set('maxColWidth',$kanban->fluidBoard == '0' ? $kanban->colWidth : $kanban->maxColWidth);
js::set('mode', $config->systemMode);
js::set('alignment', $kanban->alignment);
js::set('defaultMinColWidth', $this->config->minColWidth);
js::set('defaultMaxColWidth', $this->config->maxColWidth);
js::set('priv', array('canAssignCard' => common::hasPriv('kanban', 'assigncard')));
$canSortRegion = commonModel::hasPriv('kanban', 'sortRegion') && count($regions) > 1;
+5
View File
@@ -256,6 +256,11 @@ class misc extends control
$condition = "owner={$account}&module={$objectType}&section=task&key=unfoldTasks";
$settingPath = $account . ".{$objectType}.task.unfoldTasks";
}
elseif($objectType == 'productplan')
{
$condition = "owner={$account}&module={$objectType}&section=browse&key=unfoldPlans";
$settingPath = $account . ".{$objectType}.browse.unfoldPlans";
}
else
{
$condition = "owner={$account}&module=product&section=browse&key=unfoldStories";
+2
View File
@@ -201,6 +201,8 @@ class mrModel extends model
$MR = fixer::input('post')
->setDefault('jobID', 0)
->setDefault('repoID', 0)
->setDefault('sourceProject,targetProject', 0)
->setDefault('sourceBranch,targetBranch', '')
->setDefault('removeSourceBranch','0')
->setDefault('needCI', 0)
->setDefault('squash', 0)
+14 -14
View File
@@ -329,7 +329,7 @@ EOF;
{
$this->loadModel('story');
/* Save session. */
if($this->app->viewType != 'json') $this->session->set('storyList', $this->app->getURI(true), 'product');
if($this->app->viewType != 'json') $this->session->set('storyList', $this->app->getURI(true), 'my');
/* Load pager. */
$this->app->loadClass('pager', $static = true);
@@ -394,7 +394,7 @@ EOF;
{
/* Save session. */
$this->loadModel('story');
if($this->app->viewType != 'json') $this->session->set('storyList', $this->app->getURI(true), 'product');
if($this->app->viewType != 'json') $this->session->set('storyList', $this->app->getURI(true), 'my');
/* Load pager. */
$this->app->loadClass('pager', $static = true);
@@ -809,17 +809,18 @@ EOF;
}
$PMList = $this->user->getListByAccounts($accounts, 'account');
$this->view->title = $this->lang->my->common . $this->lang->colon . $this->lang->my->project;
$this->view->position[] = $this->lang->my->project;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->projects = $projects;
$this->view->PMList = $PMList;
$this->view->pager = $pager;
$this->view->status = $status;
$this->view->recTotal = $recTotal;
$this->view->recPerPage = $recPerPage;
$this->view->pageID = $pageID;
$this->view->orderBy = $orderBy;
$this->view->title = $this->lang->my->common . $this->lang->colon . $this->lang->my->project;
$this->view->position[] = $this->lang->my->project;
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->projects = $projects;
$this->view->PMList = $PMList;
$this->view->pager = $pager;
$this->view->status = $status;
$this->view->recTotal = $recTotal;
$this->view->recPerPage = $recPerPage;
$this->view->pageID = $pageID;
$this->view->orderBy = $orderBy;
$this->view->usersAvatar = $this->user->getAvatarPairs('');
$this->display();
}
@@ -1516,7 +1517,6 @@ EOF;
$this->session->set('designList', $uri, 'project');
$this->session->set('productPlanList', $uri, 'product');
$this->session->set('releaseList', $uri, 'product');
$this->session->set('programList', $uri, 'program');
$this->session->set('projectList', $uri, 'project');
$this->session->set('executionList', $uri, 'execution');
$this->session->set('taskList', $uri, 'execution');
+1 -2
View File
@@ -1,3 +1,2 @@
td.delayed {color: #fff; background: #e84e0f !important;}
.c-confirm {width:60px;}
[lang^=en] .c-assignedTo {width: 105px !important;}
+1
View File
@@ -1,2 +1,3 @@
.c-hours, .c-progress {width: 80px !important;}
.c-status, .c-date {padding-right: 8px !important; text-align: center;}
.align-right {text-align: right; padding-right: 8px !important;}
+1
View File
@@ -11,3 +11,4 @@
.main-table tbody > tr.table-children > td:first-child::before {width: 3px;}
@-moz-document url-prefix() {.main-table tbody > tr.table-children > td:first-child::before {width: 4px;};}
.c-span {margin-left: 22px;}
[lang^=de] .c-hours{width: 105px;}
+1
View File
@@ -11,3 +11,4 @@
.main-table tbody > tr.table-children > td:first-child::before {width: 3px;}
@-moz-document url-prefix() {.main-table tbody > tr.table-children > td:first-child::before {width: 4px;};}
.c-actions-6 {width: 185px;}
[lang^=de] .c-hours {width: 105px;}
+3 -4
View File
@@ -1,5 +1,3 @@
td.delayed {background: #e84e0f !important; color: white;}
.table-children {border-left: 2px solid #cbd0db; border-right: 2px solid #cbd0db;}
.table tbody > tr.table-children.table-child-top {border-top: 2px solid #cbd0db;}
.table tbody > tr.table-children.table-child-bottom {border-bottom: 2px solid #cbd0db;}
@@ -8,7 +6,7 @@ td.delayed {background: #e84e0f !important; color: white;}
.table td.has-child > .task-toggle:hover {color: #006af1; cursor: pointer;}
.table td.has-child > .task-toggle > .icon {font-size: 16px; display: inline-block; transition: transform .2s; -ms-transform: rotate(-90deg); -moz-transform: rotate(-90deg); -o-transform: rotate(-90deg); -webkit-transform: rotate(-90deg); transform: rotate(-90deg);}
.table td.has-child > .task-toggle > .icon:before {text-align: left;}
.table td.has-child > .task-toggle.collapsed {top: 2px;}
.table td.has-child > .task-toggle.collapsed {top: 0;}
.table td.has-child > .task-toggle.collapsed > .icon {-ms-transform: rotate(90deg); -moz-transform: rotate(90deg); -o-transform: rotate(90deg); -webkit-transform: rotate(90deg); transform: rotate(90deg);}
.table td.c-hours {padding-right: 12px;}
.main-table tbody > tr.table-children > td:first-child::before {width: 3px;}
@@ -28,7 +26,7 @@ html[lang="en"] .c-user-short {width: 88px;}
[lang^=de] #taskTable .c-date {width: 78px;}
[lang^=de] #taskTable .assigned-title {width: 123px !important;}
[lang^=de] #taskTable .c-user {width: 118px;}
[lang^=de] #taskTable .c-hours {width: 86px;}
[lang^=de] #taskTable .estimate, [lang^=de] #taskTable .consumed {width: 86px;}
[lang^=de] #taskTable .c-user-short {width: 75px;}
[lang^=fr] #taskTable .c-name {width: 120px;}
[lang^=fr] #taskTable .c-project {width: 100px;}
@@ -36,3 +34,4 @@ html[lang="en"] .c-user-short {width: 88px;}
[lang^=fr] #taskTable .assigned-title {width: 130px !important;}
[lang^=fr] #taskTable .c-user-short {width: 75px;}
[lang^=fr] #taskTable .c-status {width: 71px;}
#myTaskForm 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
@@ -10,3 +10,4 @@
.panel-actions .btn-icon {padding-left: 7px;}
[lang^=de] .c-pri {width: 69px;}
[lang^=fr] .c-pri {width: 82px;}
[lang^=en] .c-user, [lang^=fr] .c-user {width: 100px !important;}
+1 -1
View File
@@ -10,7 +10,7 @@ $(function()
e.stopPropagation();
e.preventDefault();
});
toggleFold('#myTaskForm', [], 0, 'my');
$('#taskTable td.has-child .task-toggle').each(function()
{
var $td = $(this).closest('td');
+1 -1
View File
@@ -61,7 +61,7 @@ $lang->my->projects = '所属项目';
$lang->my->executions = "所属{$lang->executionCommon}";
$lang->my->executionMenu = new stdclass();
$lang->my->executionMenu->undone = '未结束';
$lang->my->executionMenu->undone = '未完成';
$lang->my->executionMenu->done = '已完成';
$lang->my->taskMenu = new stdclass();
+13 -13
View File
@@ -62,24 +62,24 @@
<?php endif;?>
<?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?>
</th>
<th><?php common::printOrderLink('title', $orderBy, $vars, $lang->bug->title);?></th>
<th class='c-severity' title='<?php echo $lang->bug->severity;?>'><?php common::printOrderLink('severity', $orderBy, $vars, $lang->bug->severityAB);?></th>
<th class='c-pri' title='<?php echo $lang->bug->pri;?>'><?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='c-confirm' title='<?php echo $lang->bug->confirmedAB;?>'><?php common::printOrderLink('confirmed', $orderBy, $vars, $lang->bug->confirmedAB);?></th>
<th><?php common::printOrderLink('title', $orderBy, $vars, $lang->bug->title);?></th>
<th class='c-type'><?php common::printOrderLink('type', $orderBy, $vars, $lang->bug->type);?></th>
<th class='c-product'><?php common::printOrderLink('product', $orderBy, $vars, $lang->bug->product);?></th>
<th class='c-type'><?php common::printOrderLink('type', $orderBy, $vars, $lang->typeAB);?></th>
<?php if($type != 'openedBy'): ?>
<th class='c-user'><?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
<th class='c-user'><?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->bug->openedByAB);?></th>
<?php endif;?>
<th class='c-confirm' title='<?php echo $lang->bug->confirmedAB;?>'><?php common::printOrderLink('confirmed', $orderBy, $vars, $lang->bug->confirmedAB);?></th>
<?php if($app->rawMethod == 'work'):?>
<th class='c-date text-center'><?php common::printOrderLink('deadline', $orderBy, $vars, $lang->bug->deadlineAB);?></th>
<th class='c-date text-center'><?php common::printOrderLink('deadline', $orderBy, $vars, $lang->bug->deadline);?></th>
<?php endif;?>
<?php if($type != 'assignedTo'): ?>
<th class='c-user c-assignedTo'><?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->bug->assignedTo);?></th>
<?php endif;?>
<?php if($type != 'resolvedBy'): ?>
<th class='c-user'><?php common::printOrderLink('resolvedBy', $orderBy, $vars, $lang->bug->resolvedByAB);?></th>
<th class='c-user'><?php common::printOrderLink('resolvedBy', $orderBy, $vars, $lang->bug->resolvedBy);?></th>
<?php endif;?>
<th class='c-resolution'><?php common::printOrderLink('resolution', $orderBy, $vars, $lang->bug->resolutionAB);?></th>
<th class='c-actions-5 text-center'><?php echo $lang->actions;?></th>
@@ -109,6 +109,10 @@
<?php endif;?>
<?php printf('%03d', $bug->id);?>
</td>
<td class='text-left nobr'>
<?php echo html::a($this->createLink('bug', 'view', "bugID=$bug->id"), $bug->title, null, "style='color: $bug->color' title='{$bug->title}'");?>
<?php if($bug->case) echo html::a(helper::createLink('testcase', 'view', "caseID=$bug->case&version=$bug->caseVersion"), "[" . $this->lang->testcase->common . "#$bug->case]", '', "class='bug' title='$bug->case'");?>
</td>
<td>
<?php if($hasCustomSeverity):?>
<span class='<?php echo 'label-severity-custom';?>' title='<?php echo zget($lang->bug->severityList, $bug->severity);?>' data-severity='<?php echo $bug->severity;?>'><?php echo zget($lang->bug->severityList, $bug->severity, $bug->severity);?></span>
@@ -117,24 +121,20 @@
<?php endif;?>
</td>
<td><span class='label-pri <?php echo 'label-pri-' . $bug->pri?>' title='<?php echo zget($lang->bug->priList, $bug->pri);?>'><?php echo zget($lang->bug->priList, $bug->pri)?></span></td>
<td class="text-center"><span class='<?php echo $bug->confirmed == '1' ? 'confirmed' : 'unconfirmed';?>' title='<?php echo zget($lang->bug->confirmedList, $bug->confirmed);?>'><?php echo zget($lang->bug->confirmedList, $bug->confirmed)?></span></td>
<td class='text-left nobr'>
<?php echo html::a($this->createLink('bug', 'view', "bugID=$bug->id"), $bug->title, null, "style='color: $bug->color' title='{$bug->title}'");?>
<?php if($bug->case) echo html::a(helper::createLink('testcase', 'view', "caseID=$bug->case&version=$bug->caseVersion"), "[" . $this->lang->testcase->common . "#$bug->case]", '', "class='bug' title='$bug->case'");?>
</td>
<?php $param = $config->productLink == 'product-all' ? '' : "productID=$bug->product";?>
<td title="<?php echo zget($lang->bug->typeList, $bug->type, '');?>"><?php echo zget($lang->bug->typeList, $bug->type, '');?></td>
<td class='text-left nobr'>
<?php
$productLink = explode('-', $config->productLink);
echo html::a($this->createLink('product', $productLink[1], $param), $bug->productName, null, "title={$bug->productName}");
?>
</td>
<td title="<?php echo zget($lang->bug->typeList, $bug->type, '');?>"><?php echo zget($lang->bug->typeList, $bug->type, '');?></td>
<?php if($type != 'openedBy'): ?>
<td><?php echo zget($users, $bug->openedBy);?></td>
<?php endif;?>
<td class="text-center"><span class='<?php echo $bug->confirmed == '1' ? 'confirmed' : 'unconfirmed';?>' title='<?php echo zget($lang->bug->confirmedList, $bug->confirmed);?>'><?php echo zget($lang->bug->confirmedList, $bug->confirmed)?></span></td>
<?php if($app->rawMethod == 'work'):?>
<td class="text-center <?php echo (isset($bug->delay) and $bug->status == 'active') ? 'delayed' : '';?>"><?php if(substr($bug->deadline, 0, 4) > 0) echo substr($bug->deadline, 5, 6);?></td>
<td class="text-center <?php echo (isset($bug->delay) and $bug->status == 'active') ? 'delayed' : '';?>"><?php if(substr($bug->deadline, 0, 4) > 0) echo '<span>' . substr($bug->deadline, 5, 6) . '</span>';?></td>
<?php endif;?>
<?php if($type != 'assignedTo'): ?>
<td class='c-assignedTo has-btn'><?php $this->bug->printAssignedHtml($bug, $users);?></td>
+8 -16
View File
@@ -34,16 +34,13 @@
<tr class='text-left'>
<th class='c-id'><?php echo $lang->idAB;?></th>
<th class='c-name text-left'><?php echo $lang->my->name;?></th>
<?php if($config->systemMode == 'new'):?>
<th class='c-name text-left'><?php echo $lang->my->projects;?></th>
<?php endif;?>
<th class='c-date'><?php echo $lang->execution->begin;?></th>
<th class='c-date'><?php echo $lang->execution->end;?></th>
<th class='c-status'><?php echo $lang->statusAB;?></th>
<th class='c-user' title='<?php echo $lang->team->roleAB;?>'><?php echo $lang->team->roleAB;?></th>
<th class='c-user text-center'><?php echo $lang->execution->myTask;?></th>
<th class='c-date'><?php echo $lang->execution->begin;?></th>
<th class='c-date'><?php echo $lang->execution->end;?></th>
<th class='c-date'><?php echo $lang->team->join;?></th>
<th class='c-hours'><?php echo $lang->my->hours;?></th>
<th class='c-user'><?php echo $lang->execution->myTask;?></th>
<th class='c-hours align-right'><?php echo $lang->my->hours;?></th>
<th class='c-progress'><?php echo $lang->execution->progress;?></th>
</tr>
</thead>
@@ -62,13 +59,6 @@
<?php endif;?>
<?php echo html::a($link, $execution->name, '', "title='$execution->name'");?>
</td>
<?php if($config->systemMode == 'new'):?>
<td class='c-name text-left'>
<?php echo isset($execution->projectName) ? html::a($this->createLink('project', 'index', "id=$execution->project", '', '', $execution->project), $execution->projectName, '', "title='$execution->projectName'") : '';?>
</td>
<?php endif;?>
<td class='c-date'><?php echo $execution->begin;?></td>
<td class='c-date'><?php echo $execution->end;?></td>
<td class="c-status">
<?php if(isset($execution->delay)):?>
<span class="status-project status-delayed" title='<?php echo $lang->execution->delayed;?>'><?php echo $lang->execution->delayed;?></span>
@@ -78,9 +68,11 @@
<?php endif;?>
</td>
<td><?php echo $execution->role;?></td>
<td class="text-center"><?php echo $execution->assignedToMeTasks;?></td>
<td class='c-date'><?php echo $execution->begin;?></td>
<td class='c-date'><?php echo $execution->end;?></td>
<td class='c-date'><?php echo $execution->join;?></td>
<td><?php echo $execution->hours;?></td>
<td><?php echo $execution->assignedToMeTasks;?></td>
<td class="text-right"><?php echo $execution->hours;?></td>
<td>
<div class='progress-pie' data-doughnut-size='90' data-color='#3CB371' data-value='<?php echo $execution->progress;?>' data-width='24' data-height='24' data-back-color='#e8edf3'>
<div class='progress-info'><?php echo $execution->progress;?></div>
+12 -8
View File
@@ -36,13 +36,13 @@
<tr>
<th class='c-id'><?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th><?php common::printOrderLink('name', $orderBy, $vars, $lang->project->name);?></th>
<th class='c-user'><?php common::printOrderLink('PM', $orderBy, $vars, $lang->project->PM);?></th>
<?php if($status == 'openedbyme'):?>
<th class='c-status'><?php common::printOrderLink('status', $orderBy, $vars, $lang->project->status);?></th>
<?php endif;?>
<th class='text-right c-budget'><?php common::printOrderLink('budget', $orderBy, $vars, $lang->project->budget);?></th>
<th class='c-date c-begin'><?php common::printOrderLink('begin', $orderBy, $vars, $lang->project->begin);?></th>
<th class='c-date c-end'><?php common::printOrderLink('end', $orderBy, $vars, $lang->project->end);?></th>
<th class='text-right c-budget'><?php common::printOrderLink('budget', $orderBy, $vars, $lang->project->budget);?></th>
<th class='c-user'><?php common::printOrderLink('PM', $orderBy, $vars, $lang->project->PM);?></th>
<th class='text-center c-actions-6'><?php echo $lang->actions;?></th>
</tr>
</thead>
@@ -53,17 +53,21 @@
<td class='c-name text-left' title='<?php echo $project->name?>'>
<?php echo html::a($this->createLink('project', 'index', "projectID=$project->id", '', '', $project->id), $project->name, '', "data-group='project' title='{$project->name} ({$this->lang->project->{$project->model}})'");?>
</td>
<td class='c-manager'>
<?php if(!empty($project->PM)):?>
<?php $userName = zget($users, $project->PM);?>
<?php echo html::smallAvatar(array('avatar' => $usersAvatar[$project->PM], 'account' => $project->PM, 'name' => $userName), "avatar-circle avatar-{$project->PM}"); ?>
<?php $userID = isset($PMList[$project->PM]) ? $PMList[$project->PM]->id : '';?>
<?php echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), $userName, '', "title='{$userName}' data-toggle='modal' data-type='iframe' data-width='600'");?>
<?php endif;?>
</td>
<?php if($status == 'openedbyme'):?>
<td class='c-status'><span class="status-project status-<?php echo $project->status?>"><?php echo zget($lang->project->statusList, $project->status, '');?></span></td>
<?php endif;?>
<td class='text-left'><?php echo $project->begin;?></td>
<td class='text-left'><?php echo $project->end == LONG_TIME ? $this->lang->project->longTime : $project->end;?></td>
<?php $projectBudget = in_array($this->app->getClientLang(), array('zh-cn','zh-tw')) ? round((float)$project->budget / 10000, 2) . $this->lang->project->tenThousand : round((float)$project->budget, 2);?>
<td class='text-right c-budget'><?php echo $project->budget != 0 ? zget($lang->project->currencySymbol, $project->budgetUnit) . ' ' . $projectBudget : $lang->project->future;?></td>
<td>
<?php $userID = isset($PMList[$project->PM]) ? $PMList[$project->PM]->id : ''?>
<?php if(!empty($project->PM)) echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), zget($users, $project->PM), '', "data-toggle='modal' data-type='iframe' data-width='600'");?>
</td>
<td class='text-left'><?php echo $project->begin;?></td>
<td class='text-left'><?php echo $project->end == LONG_TIME ? $this->lang->project->longTime : $project->end;?></td>
<td class='c-actions'>
<?php if($project->status == 'wait' || $project->status == 'suspended') common::printIcon('project', 'start', "projectID=$project->id", $project, 'list', 'play', '', 'iframe', true);?>
<?php if($project->status == 'doing') common::printIcon('project', 'close', "projectID=$project->id", $project, 'list', 'off', '', 'iframe', true);?>
+14 -10
View File
@@ -50,6 +50,7 @@
$canBatchReview = common::hasPriv('requirement', 'batchReview');
$canBatchAssignTo = common::hasPriv('requirement', 'batchAssignTo');
$canBatchAction = ($canBatchEdit or $canBatchClose or $canBatchReview or $canBatchAssignTo);
$URTitle = common::checkNotCN() ? $lang->URCommon . ' ' . $lang->my->name : $lang->URCommon . $lang->my->name;
?>
<thead>
<tr>
@@ -61,12 +62,12 @@
<?php endif;?>
<?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?>
</th>
<th class='c-name'> <?php common::printOrderLink('title', $orderBy, $vars, $URTitle);?></th>
<th class='c-pri w-40px' title=<?php echo $lang->pri;?>><?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='c-name'> <?php common::printOrderLink('title', $orderBy, $vars, $lang->my->name);?></th>
<th class='c-product'> <?php common::printOrderLink('productTitle', $orderBy, $vars, $lang->story->product);?></th>
<th class='c-user'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
<th class='c-hours'> <?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimateAB);?></th>
<th class='c-status'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-product'> <?php common::printOrderLink('productTitle', $orderBy, $vars, $lang->story->product);?></th>
<th class='c-user'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->story->openedByAB);?></th>
<th class='c-hours'> <?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimateAB);?></th>
<th class='c-stage'> <?php common::printOrderLink('stage', $orderBy, $vars, $lang->story->stageAB);?></th>
<th class='c-actions-6 text-center'> <?php echo $lang->actions;?></th>
</tr>
@@ -88,15 +89,15 @@
<?php endif;?>
<?php printf('%03d', $story->id);?>
</td>
<td class='c-pri'><span class='label-pri <?php echo 'label-pri-' . $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 nobr <?php if(!empty($story->children)) echo "has-child" ?>'>
<?php echo common::hasPriv('requirement', 'view') ? html::a($storyLink, $story->title, null, "style='color: $story->color' data-group='product' title='$story->title'") : "<span title='$story->title'>$story->title</span>";?>
<?php if(!empty($story->children)) echo '<a class="story-toggle" data-id="' . $story->id . '"><i class="icon icon-angle-double-right"></i></a>';?>
</td>
<td class='c-pri'><span class='label-pri <?php echo 'label-pri-' . $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-status'><span class='status-story status-<?php echo $story->status;?>'><?php echo $this->processStatus('story', $story);?></span></td>
<td class='c-product' title="<?php echo $story->productTitle;?>"><?php echo $story->productTitle;?></td>
<td class='c-user'><?php echo zget($users, $story->openedBy);?></td>
<td class='c-hours' title="<?php echo $story->estimate . ' ' . $lang->hourCommon;?>"><?php echo $story->estimate . $config->hourUnit;?></td>
<td class='c-status'><span class='status-story status-<?php echo $story->status;?>'> <?php echo $this->processStatus('story', $story);?></span></td>
<td class='c-stage'><?php echo zget($lang->story->stageList, $story->stage);?></td>
<td class='c-actions'>
<?php
@@ -113,7 +114,9 @@
{
echo common::buildIconButton('story', 'review', "$vars&from=product&storyType=requirement", $story, 'list', 'search', '', 'iframe', true);
}
echo common::buildIconButton('story', 'recall', "$vars&from=list&storyType=requirement", $story, 'list', 'undo', 'hiddenwin', '', '', '', $lang->story->recall);
$title = $story->status == 'changing' ? $this->lang->story->recallChange : $this->lang->story->recall;
echo common::buildIconButton('story', 'recall', "$vars&from=list&confirm=no&storyType=requirement", $story, 'list', 'undo', 'hiddenwin', '', '', '', $title);
echo common::buildIconButton('story', 'edit', "$vars&from=default&storyType=requirement", $story, 'list', '', '', 'iframe', true, "data-width='95%'");
$storyType = 'storyType=requirement';
@@ -144,14 +147,14 @@
<span class="<?php echo $spanClass?>"></span>
<?php printf('%03d', $child->id);?>
</td>
<td class='c-pri'><span class='label-pri <?php echo 'label-pri-' . $child->pri;?>' title='<?php echo zget($lang->story->priList, $child->pri, $child->pri);?>'><?php echo zget($lang->story->priList, $child->pri, $child->pri);?></span></td>
<td class='c-name nobr'>
<?php echo '<span class="label label-badge label-light" title="' . $this->lang->story->children .'">SR</span> ' . (common::hasPriv('story', 'view') ? html::a($storyLink, $child->title, null, "style='color: $child->color' data-group='product' title='$child->title'") : $child->title);?>
</td>
<td class='c-pri'><span class='label-pri <?php echo 'label-pri-' . $child->pri;?>' title='<?php echo zget($lang->story->priList, $child->pri, $child->pri);?>'><?php echo zget($lang->story->priList, $child->pri, $child->pri);?></span></td>
<td class='c-status'><?php echo $child->URChanged ? "<span class='status-story status-changed'>{$this->lang->story->URChanged}</span>" : "<span class='status-story status-$child->status'>" . $this->processStatus('story', $child) . '</span>'?></td>
<td class='c-product' title="<?php echo $child->productTitle;?>"><?php echo $child->productTitle;?></td>
<td class='c-user'><?php echo zget($users, $child->openedBy);?></td>
<td class='c-hours'><?php echo $child->estimate . $config->hourUnit;?></td>
<td class='c-status'><?php echo $child->URChanged ? "<span class='status-story status-changed'>{$this->lang->story->URChanged}</span>" : "<span class='status-story status-$child->status'>" . $this->processStatus('story', $child) . '</span>'?></td>
<td class='c-stage'><?php echo zget($lang->story->stageList, $child->stage);?></td>
<td class='c-actions'>
<?php
@@ -175,7 +178,8 @@
common::printIcon('story', 'review', "$vars&from=product&storyType=story", $child, 'list', 'search', '', 'iframe', true);
}
common::printIcon('story', 'recall', "$vars&from=list&storyType=story", $child, 'list', 'undo', 'hiddenwin', '', '', '', $lang->story->recall);
$title = $child->status == 'changing' ? $this->lang->story->recallChange : $this->lang->story->recall;
common::printIcon('story', 'recall', "$vars&from=list&confirm=no&storyType=story", $child, 'list', 'undo', 'hiddenwin', '', '', '', $title);
common::printIcon('story', 'edit', "$vars&from=default&storyType=story", $child, 'list');
$storyType = 'storyType=story';
$canChange = common::hasPriv('story', 'change', '', $storyType);
+14 -10
View File
@@ -55,6 +55,7 @@
$canEdit = common::hasPriv('story', 'edit');
$canCreateCase = common::hasPriv('testcase', 'create');
$canClose = common::hasPriv('story', 'close');
$SRTitle = common::checkNotCN() ? $lang->SRCommon . ' ' . $lang->my->name : $lang->SRCommon . $lang->my->name;
?>
<thead>
<tr>
@@ -66,13 +67,13 @@
<?php endif;?>
<?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?>
</th>
<th class='c-name'> <?php common::printOrderLink('title', $orderBy, $vars, $SRTitle);?></th>
<th class='c-pri' title=<?php echo $lang->my->pri;?>><?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='c-name'> <?php common::printOrderLink('title', $orderBy, $vars, $lang->my->name);?></th>
<th class='c-status'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-product'> <?php common::printOrderLink('product', $orderBy, $vars, $lang->story->product);?></th>
<th class='c-plan'> <?php common::printOrderLink('plan', $orderBy, $vars, $lang->story->plan);?></th>
<th class='c-user'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
<th class='c-user'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->story->openedByAB);?></th>
<th class='c-hours'> <?php common::printOrderLink('estimate', $orderBy, $vars, $lang->story->estimateAB);?></th>
<th class='c-status'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-stage'> <?php common::printOrderLink('stage', $orderBy, $vars, $lang->story->stageAB);?></th>
<th class="c-actions-6 text-center"><?php echo $lang->actions;?></th>
</tr>
@@ -93,16 +94,16 @@
<?php endif;?>
<?php printf('%03d', $story->id);?>
</td>
<td class='c-pri'><span class='label-pri <?php echo 'label-pri-' . $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 nobr <?php if(!empty($story->children)) echo "has-child" ?>' title='<?php echo $story->title;?>'>
<?php echo common::hasPriv('story', 'view') ? html::a($storyLink, $story->title, null, "style='color: $story->color' data-group='product'") : $story->title;?>
<?php if(!empty($story->children)) echo '<a class="story-toggle" data-id="' . $story->id . '"><i class="icon icon-angle-double-right"></i></a>';;?>
<?php if(!empty($story->children)) echo '<a class="story-toggle" data-id="' . $story->id . '"><i class="icon icon-angle-right"></i></a>';;?>
</td>
<td class='c-pri'><span class='label-pri <?php echo 'label-pri-' . $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-status'><span class='status-story status-<?php echo $story->status;?>'><?php echo $this->processStatus('story', $story);?></span></td>
<td class='c-product' title='<?php echo $story->productTitle;?>'><?php echo $story->productTitle;?></td>
<td class='c-plan'><?php echo $story->planTitle;?></td>
<td class='c-user'><?php echo zget($users, $story->openedBy);?></td>
<td class='c-hours' title="<?php echo $story->estimate . ' ' . $lang->hourCommon;?>"><?php echo $story->estimate . $config->hourUnit;?></td>
<td class='c-status'><span class='status-story status-<?php echo $story->status;?>'> <?php echo $this->processStatus('story', $story);?></span></td>
<td class='c-stage'><?php echo zget($lang->story->stageList, $story->stage);?></td>
<td class='c-actions'>
<?php
@@ -120,7 +121,8 @@
echo common::buildIconButton('story', 'review', $vars, $story, 'list', 'search', '', 'iframe', true);
}
echo common::buildIconButton('story', 'recall', $vars, $story, 'list', 'undo', 'hiddenwin', '', '', '', $lang->story->recall);
$title = $story->status == 'changing' ? $this->lang->story->recallChange : $this->lang->story->recall;
echo common::buildIconButton('story', 'recall', $vars, $story, 'list', 'undo', 'hiddenwin', '', '', '', $title);
echo common::buildIconButton('story', 'edit', $vars, $story, 'list', '', '', 'iframe', true, "data-width='95%'");
$canSubmitReview = (strpos('draft,changing', $story->status) !== false and common::hasPriv('story', 'submitReview'));
@@ -156,15 +158,15 @@
<?php endif;?>
<?php printf('%03d', $child->id);?>
</td>
<td class='c-pri'><span class='label-pri <?php echo 'label-pri-' . $child->pri;?>' title='<?php echo zget($lang->story->priList, $child->pri, $child->pri);?>'><?php echo zget($lang->story->priList, $child->pri, $child->pri);?></span></td>
<td class='c-name nobr'>
<?php echo '<span class="label label-badge label-light" title="' . $this->lang->story->children .'">' . $this->lang->story->childrenAB . '</span> ' . html::a($storyLink, $child->title, null, "style='color: $child->color' data-group='product' title='$child->title'");?>
</td>
<td class='c-pri'><span class='label-pri <?php echo 'label-pri-' . $child->pri;?>' title='<?php echo zget($lang->story->priList, $child->pri, $child->pri);?>'><?php echo zget($lang->story->priList, $child->pri, $child->pri);?></span></td>
<td class='c-status'><span class='status-story status-<?php echo $child->status;?>'><?php echo $this->processStatus('story', $child);?></span></td>
<td class='c-product' title='<?php echo $child->productTitle;?>'><?php echo $child->productTitle;?></td>
<td class='c-plan'><?php echo $child->planTitle;?></td>
<td class='c-user'><?php echo zget($users, $child->openedBy);?></td>
<td class='c-hours'><?php echo $child->estimate . $config->hourUnit;?></td>
<td class='c-status'><span class='status-story status-<?php echo $child->status;?>'> <?php echo $this->processStatus('story', $child);?></span></td>
<td class='c-stage'><?php echo zget($lang->story->stageList, $child->stage);?></td>
<td class='c-actions'>
<?php
@@ -181,7 +183,9 @@
{
common::printIcon('story', 'review', $vars, $child, 'list', 'search', '', 'iframe', true);
}
common::printIcon('story', 'recall', $vars, $child, 'list', 'undo', 'hiddenwin', '', '', '', $lang->story->recall);
$title = $child->status == 'changing' ? $this->lang->story->recallChange : $this->lang->story->recall;
common::printIcon('story', 'recall', $vars, $child, 'list', 'undo', 'hiddenwin', '', '', '', $title);
common::printIcon('story', 'edit', $vars, $child, 'list', '', '', 'iframe', true, "data-width='95%'");
$canSubmitReview = (strpos('draft,changing', $child->status) !== false and common::hasPriv('story', 'submitReview'));
+65 -39
View File
@@ -44,8 +44,15 @@
</div>
<?php else:?>
<form id='myTaskForm' class="main-table table-task skip-iframe-modal" method="post">
<?php $canBatchEdit = (common::hasPriv('task', 'batchEdit') and $type == 'assignedTo');?>
<?php $canBatchClose = (common::hasPriv('task', 'batchClose') and $type != 'closedBy');?>
<?php
$canBatchEdit = (common::hasPriv('task', 'batchEdit') and $type == 'assignedTo');
$canBatchClose = (common::hasPriv('task', 'batchClose') and $type != 'closedBy');
$canFinish = common::hasPriv('task', 'finish');
$canClose = common::hasPriv('task', 'close');
$canRecordEstimate = common::hasPriv('task', 'recordEstimate');
$canEdit = common::hasPriv('task', 'edit');
$canBatchCreate = common::hasPriv('task', 'batchCreate');
?>
<div class="table-responsive">
<table class="table has-sort-head table-fixed" id='taskTable'>
<?php $vars = "mode=$mode&type=$type&param=myQueryID&orderBy=%s&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID"; ?>
@@ -60,28 +67,28 @@
<?php endif;?>
<?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?>
</th>
<th class='c-pri' title=<?php echo $lang->task->pri;?>><?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='c-name'><?php common::printOrderLink('name', $orderBy, $vars, $lang->task->name);?></th>
<th class='c-pri' title=<?php echo $lang->task->pri;?>><?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class='c-status'><?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<?php if($config->systemMode == 'new'):?>
<th class='c-project'><?php common::printOrderLink('project', $orderBy, $vars, $lang->my->projects);?></th>
<th class='c-project'><?php common::printOrderLink('execution', $orderBy, $vars, $lang->task->execution);?></th>
<?php else:?>
<th class='c-project'><?php common::printOrderLink('execution', $orderBy, $vars, $lang->my->executions);?></th>
<?php endif;?>
<?php if($type != 'openedBy'): ?>
<th class='c-user-short'><?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->openedByAB);?></th>
<?php endif;?>
<th class='c-date text-center'><?php common::printOrderLink('deadline', $orderBy, $vars, $lang->task->deadlineAB);?></th>
<?php if($type != 'assignedTo'): ?>
<th class='c-user assigned-title'><?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->task->assignedTo);?></th>
<?php endif;?>
<?php if($type != 'finishedBy'): ?>
<th class='c-user'><?php common::printOrderLink('finishedBy', $orderBy, $vars, $lang->task->finishedBy);?></th>
<?php endif;?>
<th class='c-date text-center'><?php common::printOrderLink('deadline', $orderBy, $vars, $lang->task->deadlineAB);?></th>
<th class='c-hours estimate'><?php common::printOrderLink('estimate', $orderBy, $vars, $lang->task->estimateAB);?></th>
<th class='c-hours consumed'><?php common::printOrderLink('consumed', $orderBy, $vars, $lang->task->consumedAB);?></th>
<th class='c-hours'><?php common::printOrderLink('left', $orderBy, $vars, $lang->task->leftAB);?></th>
<th class='c-status'><?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<?php if($type != 'openedBy'): ?>
<th class='c-user-short'><?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->task->openedByAB);?></th>
<?php endif;?>
<?php if($type != 'finishedBy'): ?>
<th class='c-user'><?php common::printOrderLink('finishedBy', $orderBy, $vars, $lang->task->finishedByAB);?></th>
<?php endif;?>
<th class="c-actions-6 text-center"><?php echo $lang->actions;?></th>
</tr>
</thead>
@@ -98,7 +105,6 @@
<?php endif;?>
<?php printf('%03d', $task->id);?>
</td>
<td class="c-pri"><span class='label-pri <?php echo 'label-pri-' . $task->pri;?>' title='<?php echo zget($lang->task->priList, $task->pri);?>'><?php echo zget($lang->task->priList, $task->pri);?></span></td>
<td class='c-name <?php if(!empty($task->children)) echo 'has-child';?>' title='<?php echo $task->name?>'>
<?php if(!empty($task->team)) echo '<span class="label label-badge label-light">' . $this->lang->task->multipleAB . '</span> ';?>
<?php
@@ -113,7 +119,17 @@
echo html::a($this->createLink('task', 'view', "taskID=$task->id", '', $onlybody, $task->project), $task->name, null, "class='$class' data-width='80%' style='color: $task->color'");
}
?>
<?php if(!empty($task->children)) echo '<a class="task-toggle" data-id="' . $task->id . '"><i class="icon icon-angle-double-right"></i></a>';?>
<?php if(!empty($task->children)) echo '<a class="task-toggle" data-id="' . $task->id . '"><i class="icon icon-angle-right"></i></a>';?>
</td>
<td class="c-pri"><span class='label-pri <?php echo 'label-pri-' . $task->pri;?>' title='<?php echo zget($lang->task->priList, $task->pri);?>'><?php echo zget($lang->task->priList, $task->pri);?></span></td>
<td class='c-status'>
<?php $storyChanged = (!empty($task->storyStatus) and $task->storyStatus == 'active' and $task->latestStoryVersion > $task->storyVersion and !in_array($task->status, array('cancel', 'closed')));?>
<?php $storyChanged ? print("<span class='status-story status-changed'>{$this->lang->my->storyChanged}</span>") : print("<span class='status-task status-{$task->status}'> " . $this->processStatus('task', $task) . "</span>");?>
</td>
<td class="c-pri"><span class='label-pri <?php echo 'label-pri-' . $task->pri;?>' title='<?php echo zget($lang->task->priList, $task->pri);?>'><?php echo zget($lang->task->priList, $task->pri);?></span></td>
<td class='c-status'>
<?php $storyChanged = (!empty($task->storyStatus) and $task->storyStatus == 'active' and $task->latestStoryVersion > $task->storyVersion and !in_array($task->status, array('cancel', 'closed')));?>
<?php !empty($storyChanged) ? print("<span class='status-story status-changed'>{$this->lang->my->storyChanged}</span>") : print("<span class='status-task status-{$task->status}'> " . $this->processStatus('task', $task) . "</span>");?>
</td>
<?php if($config->systemMode == 'new'):?>
<?php $projectName = isset($projects[$task->execution]->name) ? $projects[$task->execution]->name : '';?>
@@ -123,23 +139,19 @@
</td>
<?php endif;?>
<td class='c-project' title="<?php echo $task->executionName;?>"><?php echo html::a($this->createLink('execution', 'task', "executionID=$task->execution"), $task->executionName, '');?></td>
<?php if($type != 'openedBy'): ?>
<td class='c-user'><?php echo zget($users, $task->openedBy);?></td>
<?php endif;?>
<td class="text-center <?php echo isset($task->delay) ? 'delayed' : '';?>"><?php if(substr($task->deadline, 0, 4) > 0) echo substr($task->deadline, 5, 6);?></td>
<?php if($type != 'assignedTo'): ?>
<td class="c-assignedTo has-btn" title="<?php echo zget($users, $task->assignedTo);?>"> <?php $this->task->printAssignedHtml($task, $users);?></td>
<?php endif;?>
<td class="text-center <?php echo isset($task->delay) ? 'delayed' : '';?>"><?php if(substr($task->deadline, 0, 4) > 0) echo '<span>' . substr($task->deadline, 5, 6) . '</span>';?></td>
<td class='c-hours' title="<?php echo round($task->estimate, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($task->estimate, 1) . $lang->execution->workHourUnit;?></td>
<td class='c-hours' title="<?php echo round($task->consumed, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($task->consumed, 1) . $lang->execution->workHourUnit;?></td>
<td class='c-hours' title="<?php echo round($task->left, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($task->left, 1) . $lang->execution->workHourUnit;?></td>
<?php if($type != 'openedBy'): ?>
<td class='c-user'><?php echo zget($users, $task->openedBy);?></td>
<?php endif;?>
<?php if($type != 'finishedBy'): ?>
<td class='c-user'><?php echo zget($users, $task->finishedBy);?></td>
<?php endif;?>
<td class='c-hours' title="<?php echo round($task->estimate, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($task->estimate, 1) . $lang->execution->workHourUnit;?></td>
<td class='c-hours' title="<?php echo round($task->consumed, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($task->consumed, 1) . $lang->execution->workHourUnit;?></td>
<td class='c-hours' title="<?php echo round($task->left, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($task->left, 1) . $lang->execution->workHourUnit;?></td>
<td class='c-status'>
<?php $storyChanged = (!empty($task->storyStatus) and $task->storyStatus == 'active' and $task->latestStoryVersion > $task->storyVersion and !in_array($task->status, array('cancel', 'closed')));?>
<?php !empty($storyChanged) ? print("<span class='status-story status-changed'>{$this->lang->my->storyChanged}</span>") : print("<span class='status-task status-{$task->status}'> " . $this->processStatus('task', $task) . "</span>");?>
</td>
<td class='c-actions'>
<?php
if($canBeChanged)
@@ -151,11 +163,18 @@
}
else
{
$attr = isset($kanbanList[$task->execution]) ? "disabled" : '';
$attr = isset($kanbanList[$task->execution]) ? "disabled" : '';
$canStart = ($task->status != 'pause' and common::hasPriv('task', 'start'));
$canRestart = ($task->status == 'pause' and common::hasPriv('task', 'restart'));
if($task->status != 'pause') common::printIcon('task', 'start', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
if($task->status == 'pause') common::printIcon('task', 'restart', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
common::printIcon('task', 'close', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
common::printIcon('task', 'finish', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
common::printIcon('task', 'close', "taskID=$task->id", $task, 'list', '', '', 'iframe', true);
if(($canStart or $canRestart or $canFinish or $canClose) and ($canRecordEstimate or $canEdit or $canBatchCreate))
{
echo "<div class='dividing-line'></div>";
}
common::printIcon('task', 'recordEstimate', "taskID=$task->id", $task, 'list', 'time', '', 'iframe', true);
common::printIcon('task', 'edit', "taskID=$task->id", $task, 'list', '', '', 'iframe', true, "data-width='95%'");
@@ -180,11 +199,15 @@
<?php endif;?>
<?php printf('%03d', $child->id);?>
</td>
<td class="c-pri"><span class='label-pri <?php echo 'label-pri-' . $child->pri;?>' title='<?php echo zget($lang->task->priList, $child->pri);?>'><?php echo zget($lang->task->priList, $child->pri);?></span></td>
<td class='c-name' title='<?php echo $child->name?>'>
<?php if($child->parent > 0) echo '<span class="label label-badge label-light">' . $this->lang->task->childrenAB . '</span> ';?>
<?php echo html::a($this->createLink('task', 'view', "taskID=$child->id", '', '', $child->project), $child->name, null, "style='color: $child->color'");?>
</td>
<td class="c-pri"><span class='label-pri <?php echo 'label-pri-' . $child->pri;?>' title='<?php echo zget($lang->task->priList, $child->pri);?>'><?php echo zget($lang->task->priList, $child->pri);?></span></td>
<td class='c-status'>
<?php $storyChanged = (!empty($child->storyStatus) and $child->storyStatus == 'active' and $child->latestStoryVersion > $child->storyVersion and !in_array($child->status, array('cancel', 'closed')));?>
<?php !empty($storyChanged) ? print("<span class='status-story status-changed'>{$this->lang->my->storyChanged}</span>") : print("<span class='status-task status-{$child->status}'> " . $this->processStatus('task', $child) . "</span>");?>
</td>
<?php if($config->systemMode == 'new'):?>
<?php $projectName = isset($projects[$child->execution]->name) ? $projects[$child->execution]->name : '';?>
<?php $projectID = isset($projects[$child->execution]->id) ? $projects[$child->execution]->id : 0;?>
@@ -193,23 +216,19 @@
</td>
<?php endif;?>
<td class='c-project' title="<?php echo $child->projectName;?>"><?php echo html::a($this->createLink('execution', 'task', "executionID=$child->project"), $child->executionName, '');?></td>
<?php if($type != 'openedBy'): ?>
<td class='c-user'><?php echo zget($users, $child->openedBy);?></td>
<?php endif;?>
<td class="text-center <?php echo isset($child->delay) ? 'delayed' : '';?>"><?php if(substr($child->deadline, 0, 4) > 0) echo substr($child->deadline, 5, 6);?></td>
<?php if($type != 'assignedTo'): ?>
<td class="c-assignedTo has-btn" title="<?php echo zget($users, $child->assignedTo);?>"> <?php $this->task->printAssignedHtml($child, $users);?></td>
<?php endif;?>
<td class="text-center <?php echo isset($child->delay) ? 'delayed' : '';?>"><?php if(substr($child->deadline, 0, 4) > 0) echo '<span>' . substr($child->deadline, 5, 6) . '</span>';?></td>
<td class='c-hours' title="<?php echo round($child->estimate, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($child->estimate, 1) . ' ' . $lang->execution->workHourUnit;?></td>
<td class='c-hours' title="<?php echo round($child->consumed, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($child->consumed, 1) . ' ' . $lang->execution->workHourUnit;?></td>
<td class='c-hours' title="<?php echo round($child->left, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($child->left, 1) . ' ' . $lang->execution->workHourUnit;?></td>
<?php if($type != 'openedBy'): ?>
<td class='c-user'><?php echo zget($users, $child->openedBy);?></td>
<?php endif;?>
<?php if($type != 'finishedBy'): ?>
<td class='c-user'><?php echo zget($users, $child->finishedBy);?></td>
<?php endif;?>
<td class='c-hours' title="<?php echo round($child->estimate, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($child->estimate, 1) . ' ' . $lang->execution->workHourUnit;?></td>
<td class='c-hours' title="<?php echo round($child->consumed, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($child->consumed, 1) . ' ' . $lang->execution->workHourUnit;?></td>
<td class='c-hours' title="<?php echo round($child->left, 1) . ' ' . $lang->execution->workHour;?>"><?php echo round($child->left, 1) . ' ' . $lang->execution->workHourUnit;?></td>
<td class='c-status'>
<?php $storyChanged = (!empty($child->storyStatus) and $child->storyStatus == 'active' and $child->latestStoryVersion > $child->storyVersion and !in_array($child->status, array('cancel', 'closed')));?>
<?php !empty($storyChanged) ? print("<span class='status-story status-changed'>{$this->lang->my->storyChanged}</span>") : print("<span class='status-task status-{$child->status}'> " . $this->processStatus('task', $child) . "</span>");?>
</td>
<td class='c-actions'>
<?php
if($canBeChanged)
@@ -221,10 +240,17 @@
}
else
{
$canStart = ($child->status != 'pause' and common::hasPriv('task', 'start'));
$canRestart = ($child->status == 'pause' and common::hasPriv('task', 'restart'));
if($child->status != 'pause') common::printIcon('task', 'start', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
if($child->status == 'pause') common::printIcon('task', 'restart', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
common::printIcon('task', 'close', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
common::printIcon('task', 'finish', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
common::printIcon('task', 'close', "taskID=$child->id", $child, 'list', '', '', 'iframe', true);
if(($canStart or $canRestart or $canFinish or $canClose) and ($canRecordEstimate or $canEdit or $canBatchCreate))
{
echo "<div class='dividing-line'></div>";
}
common::printIcon('task', 'recordEstimate', "taskID=$child->id", $child, 'list', 'time', '', 'iframe', true);
common::printIcon('task', 'edit', "taskID=$child->id", $child, 'list', '', '', 'iframe', true, "data-width='95%'");
+5 -5
View File
@@ -55,17 +55,17 @@
<?php endif;?>
<?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?>
</th>
<th class='c-pri' title=<?php echo $lang->testcase->pri;?>> <?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th> <?php common::printOrderLink('title', $orderBy, $vars, $lang->testcase->title);?></th>
<th class='c-pri'> <?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<?php if($type == 'assigntome'):?>
<th class='c-task'> <?php common::printOrderLink('task', $orderBy, $vars, $lang->testtask->common);?></th>
<?php endif;?>
<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 echo $lang->statusAB;?></th>
<th class='c-user'> <?php common::printOrderLink('openedBy', $orderBy, $vars, $lang->testcase->openedByAB);?></th>
<th class='c-user'> <?php common::printOrderLink('lastRunner', $orderBy, $vars, $lang->testtask->lastRunAccount);?></th>
<th class='c-full-date'><?php common::printOrderLink('lastRunDate', $orderBy, $vars, $lang->testtask->lastRunTime);?></th>
<th class='c-result'> <?php common::printOrderLink('lastRunResult', $orderBy, $vars, $lang->testtask->lastRunResult);?></th>
<th class='c-status'> <?php echo $lang->statusAB;?></th>
<th class='c-actions-5 text-center'> <?php echo $lang->actions;?></th>
</tr>
</thead>
@@ -86,19 +86,19 @@
<?php endif;?>
<?php echo sprintf('%03d', $case->id); ?>
</td>
<td><span class='label-pri <?php echo 'label-pri-' . $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>
<?php $params = "testcaseID=$caseID&version=$case->version";?>
<?php if($type == 'assigntome') $params .= "&from=testtask&taskID=$case->task";?>
<td class='c-name'><?php echo html::a($this->createLink('testcase', 'view', $params), $case->title, null, "style='color: $case->color' title='{$case->title}'");?></td>
<td><span class='label-pri <?php echo 'label-pri-' . $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>
<?php if($type == 'assigntome'):?>
<td class='c-name' title='<?php echo $case->taskName;?>'><?php echo $case->taskName;?></td>
<?php endif;?>
<td><?php echo zget($lang->testcase->typeList, $case->type);?></td>
<td class='<?php if(isset($run)) echo $run->status;?>'><?php echo $this->processStatus('testcase', $case);?></td>
<td><?php echo zget($users, $case->openedBy);?></td>
<td><?php echo zget($users, $case->lastRunner);?></td>
<td><?php echo helper::isZeroDate($case->lastRunDate) ? '' : substr($case->lastRunDate, 5, 11);?></td>
<td class='<?php echo $case->lastRunResult;?>'><?php if($case->lastRunResult) echo $lang->testcase->resultList[$case->lastRunResult];?></td>
<td class='<?php if(isset($run)) echo $run->status;?>'><?php echo $this->processStatus('testcase', $case);?></td>
<td class='c-actions'>
<?php
if($canBeChanged)
+4 -4
View File
@@ -35,11 +35,11 @@
<tr>
<th class='c-id'> <?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?></th>
<th> <?php common::printOrderLink('name', $orderBy, $vars, $lang->testtask->name);?></th>
<th class='c-execution'><?php common::printOrderLink('execution', $orderBy, $vars, $lang->testtask->execution);?></th>
<th class='c-build'> <?php common::printOrderLink('build', $orderBy, $vars, $lang->testtask->build);?></th>
<th class='c-execution'><?php common::printOrderLink('execution', $orderBy, $vars, $lang->testtask->execution);?></th>
<th class='c-status'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-date'> <?php common::printOrderLink('begin', $orderBy, $vars, $lang->testtask->begin);?></th>
<th class='c-date'> <?php common::printOrderLink('end', $orderBy, $vars, $lang->testtask->end);?></th>
<th class='c-status'> <?php common::printOrderLink('status', $orderBy, $vars, $lang->statusAB);?></th>
<th class='c-actions-6 text-center'><?php echo $lang->actions;?></th>
</tr>
</thead>
@@ -48,11 +48,11 @@
<tr>
<td class="c-id"><?php printf('%03d', $task->id);?></td>
<td class='text-left nobr' title='<?php echo $task->name;?>'><?php echo html::a($this->createLink('testtask', 'view', "taskID=$task->id"), $task->name);?></td>
<td class='nobr' title='<?php echo $task->executionName;?>'><?php echo $task->executionName;?></td>
<td class='nobr' title='<?php echo $task->build == 'trunk' ? $lang->trunk : $task->buildName;?>'><?php $task->build == 'trunk' ? print($lang->trunk) : print(html::a($this->createLink('build', 'view', "buildID=$task->build"), $task->buildName));?></td>
<td class='nobr' title='<?php echo $task->executionName;?>'><?php echo $task->executionName;?></td>
<td title='<?php echo $this->processStatus('testtask', $task);?>'><span class="status-task status-<?php echo $task->status?>"><?php echo $this->processStatus('testtask', $task);?></span></td>
<td><?php echo $task->begin?></td>
<td><?php echo $task->end?></td>
<td title='<?php echo $this->processStatus('testtask', $task);?>'><span class="status-task status-<?php echo $task->status?>"><?php echo $this->processStatus('testtask', $task);?></span></td>
<td class='c-actions'>
<?php
common::printIcon('testtask', 'cases', "taskID=$task->id", $task, 'list', 'sitemap', '', '', '', "data-app='qa'");
+17 -9
View File
@@ -87,16 +87,20 @@
<?php endif;?>
<?php common::printOrderLink('id', $orderBy, $vars, $lang->idAB);?>
</th>
<th class="c-date text-center"><?php common::printOrderLink('date', $orderBy, $vars, $lang->todo->date);?></th>
<th class="c-type"><?php common::printOrderLink('type', $orderBy, $vars, $lang->todo->type);?></th>
<th class="c-name"> <?php common::printOrderLink('name', $orderBy, $vars, $lang->todo->name);?></th>
<?php $style = $this->app->clientLang == 'en' ? "style='width:80px'" : '';?>
<th class="c-pri" <?php echo $style;?> title=<?php echo $lang->todo->pri;?>> <?php common::printOrderLink('pri', $orderBy, $vars, $lang->priAB);?></th>
<th class="c-name"> <?php common::printOrderLink('name', $orderBy, $vars, $lang->todo->name);?></th>
<th class="c-date text-center"><?php common::printOrderLink('date', $orderBy, $vars, $lang->todo->date);?></th>
<th class="c-status"> <?php common::printOrderLink('status', $orderBy, $vars, $lang->todo->status);?></th>
<th class="c-type"><?php common::printOrderLink('type', $orderBy, $vars, $lang->todo->type);?></th>
<?php if($type == 'assignedToOther'):?>
<th class="c-user"> <?php common::printOrderLink('assignedTo', $orderBy, $vars, $lang->todo->assignedTo);?></th>
<?php else:?>
<th class="c-user"> <?php common::printOrderLink('assignedBy', $orderBy, $vars, $lang->todo->assignedBy);?></th>
<?php endif;?>
<th class="c-begin"> <?php common::printOrderLink('begin', $orderBy, $vars, $lang->todo->beginAB);?></th>
<th class="c-end"> <?php common::printOrderLink('end', $orderBy, $vars, $lang->todo->endAB);?></th>
<th class="c-status"> <?php common::printOrderLink('status', $orderBy, $vars, $lang->todo->status);?></th>
<th class="c-actions-5"><?php echo $lang->actions;?></th>
<th class="c-actions-5 text-center"><?php echo $lang->actions;?></th>
</tr>
</thead>
<tbody>
@@ -111,14 +115,18 @@
<?php endif;?>
<?php echo $todo->id?>
</td>
<td class="c-date text-center"><?php echo $todo->date == '2030-01-01' ? $lang->todo->periods['future'] : $todo->date;?></td>
<td class="c-type"><?php echo zget($lang->todo->typeList, $todo->type, '');?></td>
<td class="c-pri"><span title="<?php echo zget($lang->todo->priList, $todo->pri);?>" class='label-pri <?php echo 'label-pri-' . $todo->pri;?>' title='<?php echo zget($lang->todo->priList, $todo->pri, $todo->pri);?>'><?php echo zget($lang->todo->priList, $todo->pri)?></span></td>
<td class="c-name" title="<?php echo $todo->name;?>"><?php echo html::a($this->createLink('todo', 'view', "id=$todo->id&from=my", '', true), $todo->name, '', "data-toggle='modal' data-width='80%' data-type='iframe' data-title='" . $lang->todo->view . "' data-icon='check'");?></td>
<td class="c-pri"><span title="<?php echo zget($lang->todo->priList, $todo->pri);?>" class='label-pri <?php echo 'label-pri-' . $todo->pri;?>' title='<?php echo zget($lang->todo->priList, $todo->pri, $todo->pri);?>'><?php echo zget($lang->todo->priList, $todo->pri)?></span></td>
<td class="c-date text-center"><?php echo $todo->date == '2030-01-01' ? $lang->todo->periods['future'] : $todo->date;?></td>
<td class="c-status"><span class="status-todo status-<?php echo $todo->status;?>"><?php echo $lang->todo->statusList[$todo->status];?></span></td>
<td class="c-type"><?php echo zget($lang->todo->typeList, $todo->type, '');?></td>
<?php if($type == 'assignedToOther'):?>
<td><?php echo zget($users, $todo->assignedTo);?></td>
<?php else:?>
<td><?php echo zget($users, $todo->assignedBy);?></td>
<?php endif;?>
<td class="c-begin"><?php echo $todo->begin;?></td>
<td class="c-end"><?php echo $todo->end;?></td>
<td class="c-status"><span class="status-todo status-<?php echo $todo->status;?>"><?php echo $lang->todo->statusList[$todo->status];?></span></td>
<td class="c-actions">
<?php
common::printIcon('todo', 'start', "id=$todo->id", $todo, 'list', 'play', 'hiddenwin');
+4 -4
View File
@@ -37,10 +37,10 @@ js::set('deptID', $deptID);
<thead>
<tr>
<th class="c-id"><?php echo $lang->idAB;?></th>
<th class="c-department"><?php echo $lang->personnel->department;?></th>
<th class="c-user"><?php echo $lang->personnel->realName;?></th>
<th class="c-user"><?php echo $lang->personnel->userName;?></th>
<th class="c-department"><?php echo $lang->personnel->department;?></th>
<th class="c-job"><?php echo $lang->personnel->job;?></th>
<th class="c-user"><?php echo $lang->personnel->userName;?></th>
<th class="c-genders"><?php echo $lang->personnel->genders;?></th>
</tr>
</thead>
@@ -48,10 +48,10 @@ js::set('deptID', $deptID);
<?php foreach($personnelList as $personnel):?>
<tr>
<td class="c-id"><?php echo $personnel->id;?></td>
<td class="c-name"><?php echo zget($deptList, $personnel->dept);?></td>
<td class="c-name"><?php echo $personnel->realname;?></td>
<td class="c-name"><?php echo $personnel->account;?></td>
<td class="c-name"><?php echo zget($deptList, $personnel->dept);?></td>
<td><?php echo zget($lang->user->roleList, $personnel->role, '');?></td>
<td class="c-name"><?php echo $personnel->account;?></td>
<td><?php echo zget($lang->user->genderList, $personnel->gender, '');?></td>
</tr>
<?php endforeach;?>
+2 -2
View File
@@ -5,7 +5,7 @@ $.get(createLink('port', 'ajaxGetTbody','model=<?php echo $model;?>&lastID=0&pag
$('#showData > tbody').append(data);
if($('#showData tbody').find('tr').hasClass('showmore') === false) $('#showData tfoot').removeClass('hidden');
$('#showData tbody').find('.picker-select').picker({chosenMode: true});
$('.form-date').datetimepicker('update');
$('.form-date').datetimepicker({minView: 2, format: "yyyy-mm-dd"});
$('.form-datetime').datetimepicker('update');
$('#showData > tbody').removeClass('load-indicator loading');
})
@@ -37,7 +37,7 @@ function loadData($showmore)
$showmore.after(data);
if($('#showData tbody').find('tr').hasClass('showmore') === false) $('#showData tfoot').removeClass('hidden');
$('#showData tbody').find('.picker-select').picker({chosenMode: true}).removeClass('nopicker');
$('.form-date').datetimepicker('update');
$('.form-date').datetimepicker({minView: 2, format: "yyyy-mm-dd"});
$('.form-datetime').datetimepicker('update');
})
}
+1 -1
View File
@@ -11,7 +11,7 @@ $config->product->custom->batchEditFields = 'line,PO,QD,RD';
if($config->systemMode == 'new') $config->product->custom->batchEditFields .= ',program';
$config->product->list = new stdclass();
$config->product->list->exportFields = 'id,program,line,name,activeRequirements,changedRequirements,draftRequirements,closedRequirements,requireCompleteRate,activeStories,changedStories,draftStories,closedStories,storyCompleteRate,plans,releases,bugs,unResolvedBugs,assignToNullBugs,closedBugs,bugFixedRate';
$config->product->list->exportFields = 'id,program,line,name,manager,draftStories,activeStories,changedStories,reviewingStories,closedStories,storyCompleteRate,bugs,unResolvedBugs,assignToNullBugs,bugFixedRate,plans,releases';
$config->product->showBranchMethod = 'browse,project';
+22 -16
View File
@@ -73,10 +73,13 @@ class product extends control
* @param int $branch
* @param int $involved
* @param string $orderBy
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
* @access public
* @return void
*/
public function project($status = 'all', $productID = 0, $branch = '', $involved = 0, $orderBy = 'order_desc')
public function project($status = 'all', $productID = 0, $branch = '', $involved = 0, $orderBy = 'order_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
$this->app->loadLang('execution');
$this->loadModel('project');
@@ -87,9 +90,13 @@ class product extends control
$this->product->setMenu($productID, $branch);
/* Load pager. */
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
/* Get PM id list. */
$accounts = array();
$projectStats = $this->product->getProjectStatsByProduct($productID, $status, $branch, $involved, $orderBy);
$projectStats = $this->product->getProjectStatsByProduct($productID, $status, $branch, $involved, $orderBy, $pager);
$product = $this->product->getByID($productID);
$projects = $this->project->getPairsByProgram($product->program, 'all', false, 'order_asc');
@@ -112,6 +119,10 @@ class product extends control
$this->view->users = $this->loadModel('user')->getPairs('noletter');
$this->view->branchID = $branch;
$this->view->branchStatus = $this->loadModel('branch')->getByID($branch, 0, 'status');
$this->view->recTotal = $recTotal;
$this->view->recPerPage = $recPerPage;
$this->view->pageID = $pageID;
$this->view->pager = $pager;
$this->display();
}
@@ -1286,6 +1297,9 @@ class product extends control
$this->view->productStructure = $productStructure;
$this->view->productLines = $productLines;
$this->view->programLines = $programLines;
$this->view->users = $this->user->getPairs('noletter');
$this->view->userIdPairs = $this->user->getPairs('noletter|showid');
$this->view->usersAvatar = $this->user->getAvatarPairs('');
$this->view->orderBy = $orderBy;
$this->view->browseType = $browseType;
$this->view->pager = $pager;
@@ -1437,7 +1451,6 @@ class product extends control
$productConfig = $this->config->product;
/* Create field lists. */
if(!$this->config->URAndSR) $productConfig->list->exportFields = str_replace('activeRequirements,changedRequirements,draftRequirements,closedRequirements,requireCompleteRate,', '', $productConfig->list->exportFields);
$fields = $this->post->exportFields ? $this->post->exportFields : explode(',', $productConfig->list->exportFields);
foreach($fields as $key => $fieldName)
{
@@ -1448,28 +1461,21 @@ class product extends control
$lastProgram = $lastLine = '';
$lines = $this->product->getLinePairs();
$users = $this->user->getPairs('noletter');
$productStats = $this->product->getStats('program_desc,line_desc,' . $orderBy, null, $status);
foreach($productStats as $i => $product)
{
$product->line = zget($lines, $product->line, '');
if($this->config->URAndSR)
{
$product->activeRequirements = (int) $product->requirements['active'];
$product->changedRequirements = (int) $product->requirements['changing'];
$product->draftRequirements = (int) $product->requirements['draft'];
$product->closedRequirements = (int) $product->requirements['closed'];
$product->totalRequirements = $product->activeRequirements + $product->changedRequirements + $product->draftRequirements + $product->closedRequirements;
$product->requireCompleteRate = ($product->totalRequirements == 0 ? 0 : round($product->closedRequirements / $product->totalRequirements, 3) * 100) . '%';
}
$product->line = zget($lines, $product->line, '');
$product->manager = zget($users, $product->PO, '');
$product->draftStories = (int)$product->stories['draft'];
$product->activeStories = (int)$product->stories['active'];
$product->changedStories = (int)$product->stories['changing'];
$product->draftStories = (int)$product->stories['draft'];
$product->reviewingStories = (int)$product->stories['reviewing'];
$product->closedStories = (int)$product->stories['closed'];
$product->totalStories = $product->activeStories + $product->changedStories + $product->draftStories + $product->closedStories;
$product->totalStories = $product->activeStories + $product->changedStories + $product->draftStories + $product->closedStories + $product->reviewingStories;
$product->storyCompleteRate = ($product->totalStories == 0 ? 0 : round($product->closedStories / $product->totalStories, 3) * 100) . '%';
$product->unResolvedBugs = (int)$product->unResolved;
$product->assignToNullBugs = (int)$product->assignToNull;
$product->closedBugs = (int)$product->closedBugs;
$product->bugFixedRate = (($product->unResolved + $product->fixedBugs) == 0 ? 0 : round($product->fixedBugs / ($product->unResolved + $product->fixedBugs), 3) * 100) . '%';
$product->program = $product->programName;
+22 -12
View File
@@ -35,33 +35,41 @@
#programTree ul > li.has-list:after {width: 14px;}
#programTree ul > li.item-meas a.selected {color: #0c64eb;}
.side-col {padding-right: 20px; width: 18%;}
#sidebar>.cell {width: 100%;}
#sidebar > .cell {width: 100%;}
th.c-name {width: 400px;}
th.c-PO {width: 100px;}
th.c-story {width: 290px;}
th.c-bug {width: 150px;}
th.c-plan {width: 45px;}
th.c-release {width: 50px;}
th.c-actions {width: 50px;}
.c-name {border-left: none !important;}
.icon-cards-view {color: #888fa1;}
[lang='en'] .en-wrap-text {white-space: normal; height: 24px; line-height: 1; font-size: 12px;}
#productListForm thead>tr>th,
#productListForm tbody>tr>td {text-align: center; text-overflow: unset!important}
#productListForm thead>tr>th {padding: 0; line-height: 24px;}
#productListForm thead>tr:first-child>th {border-left: 1px solid #ddd;}
#productListForm thead>tr>th.c-checkbox {border-left: none; padding-left: 15px; width: 45px;}
#productListForm tbody>tr>td {padding: 2px 4px;}
#productListForm tbody>tr>td:first-child {text-align: left; padding-left: 15px;}
#productListForm thead > tr > th,
#productListForm tbody > tr > td {text-align: center; text-overflow: unset!important}
#productListForm thead > tr > th {padding: 0; line-height: 24px;}
#productListForm thead > tr:first-child > th {border-left: 1px solid #ddd;}
#productListForm thead > tr > th.c-checkbox {border-left: none; padding-left: 15px; width: 30px;}
#productListForm tbody > tr > td {padding: 2px 4px;}
#productListForm tbody > tr > td:first-child {text-align: left; padding-left: 15px;}
#productListForm tbody > tr > td.table-nest-title {padding-left: 16px;}
#productListForm th.table-nest-title .nest-has-checkbox {margin-top: 7px; margin-left: 35px;}
#productListForm th.table-nest-title .nest-none-checkbox {margin-top: 8px; margin-left: 5px;}
#productListForm th.table-nest-title .header {margin-left: 5px;}
#productListForm th.table-nest-title .sort-up {padding-left: 5px;}
#productListForm th.table-nest-title .sort-down {padding-left: 5px;}
#productListForm th.table-nest-title .table-nest-toggle {top: 12px; opacity: .6;}
#productListForm th.table-nest-title .table-nest-toggle {top: 14px; left: auto; right: 10px; opacity: .6;}
#productListForm th.table-nest-title .table-nest-toggle::before {position: absolute; top: 0 !important; right: 0; bottom: 0; left: 0;}
#productListForm th.table-nest-title .table-nest-toggle:hover {opacity: 1;}
#productListForm .table.has-sort-head thead>tr>th>a:after,
#productListForm .table.has-sort-head thead>tr>th>a:before {top: -3px;}
#productListForm .table.has-sort-head thead > tr > th > a:after,
#productListForm .table.has-sort-head thead > tr > th > a:before {top: -3px;}
#productListForm .icon-product:before {content: '\e98f'; width: 22px; height: 22px; background: none; color: rgb(166, 170, 184); top: 0; line-height: 22px; margin-right: 2px; font-size: 14px;}
#productTableList td.table-nest-title > span.icon.table-nest-toggle {vertical-align: middle;}
#productTableList > tr[data-nest-parent] {background: #f8f8f8;}
#productList > thead th.table-nest-title.c-name {position: relative; padding-left: 16px !important;}
@media screen and (max-width: 1460px)
{
@@ -77,7 +85,7 @@ th.c-actions {width: 50px;}
@media screen and (max-width: 1250px)
{
#productListForm thead>tr>th {font-size: 12px;}
#productListForm thead > tr > th {font-size: 12px;}
th.c-requirement {width: 265px;}
th.c-story {width: 265px;}
[lang^='zh-'] th.c-requirement {width: 220px;}
@@ -89,4 +97,6 @@ th.c-actions {width: 50px;}
#productTableList > tr.row-line.no-nest > td.text-left.table-nest-title > span.table-nest-icon.icon:before{content: '\e6f2'; background-color: white; display: inline;}
.statistic {margin-left: 10px; color: #838a9d; float: left; position: relative; line-height: 28px;}
.table-footer.fixed-footer .statistic {color: #fff;}
#productTableList .c-manager {padding-left: 14px;}
#productTableList .c-manager a {top: 7px; left: 22px;}
.checkbox-primary {margin-right: 10px;}
+124 -94
View File
@@ -1,4 +1,121 @@
$("#" + browseType + "Tab").addClass('btn-active-text');
/**
* Set batch edit checkbox.
*
* @access public
* @return void
*/
function setCheckbox()
{
$('#productListForm .c-checkbox, #productListForm .check-all').hide();
$('.c-name').css('border-left', 'none');
$(":checkbox[name^='productIDList']").prop('checked', false);
$('.check-all, .program-checkbox, .row-product').removeClass('checked');
if($.cookie('showProductBatchEdit') == 1)
{
$('#productListForm .c-checkbox, #productListForm .check-all').show();
$('.c-name').css('border-left', '1px solid #ddd');
}
else
{
$('.table-actions').hide();
$('#productsCount').show();
}
}
/**
* Update prarent checkbox.
*
* @param object $parent
* @access public
* @return void
*/
function updatePrarentCheckbox($parent)
{
var $row = $parent.closest('tr');
var $checkbox = $row.find('.program-checkbox');
var rowID = $row.data('id');
var $subRows = $('#productTableList').children('.row-product[data-nest-path^="' + rowID + ',"],.row-product[data-nest-path*=",' + rowID + ',"]');
var allCount = $subRows.length;
var selectedCount = $subRows.find('input:checkbox:checked').length;
var isAllChecked = allCount > 0 && allCount === selectedCount;
$checkbox.toggleClass('checked', isAllChecked)
.toggleClass('indeterminate', selectedCount > 0 && selectedCount < allCount);
$row.toggleClass('checked', isAllChecked);
}
/**
* Update all checkbox.
*
* @access public
* @return void
*/
function updateCheckboxes()
{
$('#productTableList').children('.row-program,.row-line').each(function()
{
updatePrarentCheckbox($(this))
});
}
/**
* Add a statistics prompt statement after the Edit button.
*
* @access public
* @return void
*/
function addStatistic()
{
var checkedLength = $(":checkbox[name^='productIDList']:checked").length;
if(checkedLength > 0)
{
var summary = checkedProducts.replace('%s', checkedLength);
if(cilentLang == "en" && checkedLength < 2) summary = summary.replace('products', 'product');
var statistic = "<div id='productsSummary' class='statistic'>" + summary + "</div>";
$('#productsCount').hide();
$('#productsSummary').remove();
$('#editBtn').after(statistic);
$('.table-actions').show();
}
else
{
$('.table-actions').hide();
$('#productsCount').show();
$('#productsSummary').addClass('hidden');
}
}
/**
* Anti shake operation for jquery.
*
* @param fn $fn
* @param delay $delay
* @access public
* @return void
*/
function debounce(fn, delay)
{
var timer = null;
return function()
{
if(timer) clearTimeout(timer);
timer = setTimeout(fn, delay)
}
}
/**
* Update statistics.
*
* @access public
* @return void
*/
function updateStatistic()
{
debounce(addStatistic(), 200)
}
$(function()
{
$('input[name^="showEdit"]').click(function()
@@ -43,106 +160,19 @@ $(function()
}
});
/**
* Set batch edit checkbox.
*
* @access public
* @return void
*/
function setCheckbox()
$('.main-table').on('click', 'tr', function(e)
{
$('#productListForm .c-checkbox, #productListForm .check-all').hide();
$('.c-name').css('border-left', 'none');
if($.cookie('showProductBatchEdit') == 1)
{
$('#productListForm .c-checkbox, #productListForm .check-all').show();
$('.c-name').css('border-left', '1px solid #ddd');
}
}
if($.cookie('showProductBatchEdit') == 1) updateStatistic();
});
/* Update parent checkbox */
function updatePrarentCheckbox($parent)
$('#productTableList').on('click', 'tr', function(e)
{
var $row = $parent.closest('tr');
var $checkbox = $row.find('.program-checkbox');
var rowID = $row.data('id');
var $subRows = $('#productTableList').children('.row-product[data-nest-path^="' + rowID + ',"],.row-product[data-nest-path*=",' + rowID + ',"]');
var allCount = $subRows.length;
var selectedCount = $subRows.find('input:checkbox:checked').length;
var isAllChecked = allCount > 0 && allCount === selectedCount;
$checkbox.toggleClass('checked', isAllChecked)
.toggleClass('indeterminate', selectedCount > 0 && selectedCount < allCount);
$row.toggleClass('checked', isAllChecked);
}
/* Update checkboxes */
function updateCheckboxes()
{
$('#productTableList').children('.row-program,.row-line').each(function()
{
updatePrarentCheckbox($(this))
});
}
/**
* Add a statistics prompt statement after the Edit button.
*
* @access public
* @return void
*/
function addStatistic()
{
var checkedLength = $(":checkbox[name^='productIDList']:checked").length;
if(checkedLength > 0)
{
var summary = checkedProducts.replace('%s', checkedLength);
if(cilentLang == "en" && checkedLength < 2) summary = summary.replace('products', 'product');
var statistic = "<div id='productsSummary' class='statistic'>" + summary + "</div>";
$('#productsCount').hide();
$('#productsSummary').remove();
$('#editBtn').after(statistic);
$('.table-actions').show();
}
else
{
$('.table-actions').hide();
$('#productsCount').show();
$('#productsSummary').addClass('hidden');
}
}
/**
* Anti shake operation for jquery.
*
* @param fn $fn
* @param delay $delay
* @access public
* @return void
*/
function debounce(fn, delay)
{
var timer = null;
return function()
{
if(timer) clearTimeout(timer);
timer = setTimeout(fn, delay)
}
}
/**
* Update statistics.
*
* @access public
* @return void
*/
function updateStatistic()
{
debounce(addStatistic(), 200)
}
if($.cookie('showProductBatchEdit') != 1) e.stopPropagation();
});
$('#productTableList').on('click', '.row-program,.row-line', function(e)
{
if($.cookie('showProductBatchEdit') != 1) return;
if($(e.target).closest('.table-nest-toggle,a').length) return;
var $row = $(this);
+2
View File
@@ -72,6 +72,8 @@ $lang->product->changedStories = 'Geänderte [S]';
$lang->product->changedStoriesTitle = 'Changed Stories';
$lang->product->draftStories = 'Entwurf [S]';
$lang->product->draftStoriesTitle = 'Draft Stories';
$lang->product->reviewingStories = "Reviewing [S]";
$lang->product->reviewingStoriesTitle = "Reviewing Stories";
$lang->product->closedStories = 'Geschlossene [S]';
$lang->product->closedStoriesTitle = 'Closed Stories';
$lang->product->storyCompleteRate = "{$lang->SRCommon} Completion rate";
+2
View File
@@ -72,6 +72,8 @@ $lang->product->changedStories = 'Changed [S]';
$lang->product->changedStoriesTitle = 'Changed Stories';
$lang->product->draftStories = 'Draft [S]';
$lang->product->draftStoriesTitle = 'Draft Stories';
$lang->product->reviewingStories = "Reviewing [S]";
$lang->product->reviewingStoriesTitle = "Reviewing Stories";
$lang->product->closedStories = 'Closed [S]';
$lang->product->closedStoriesTitle = 'Closed Stories';
$lang->product->storyCompleteRate = "{$lang->SRCommon} Completion rate";
+2
View File
@@ -72,6 +72,8 @@ $lang->product->changedStories = 'Changées [S]';
$lang->product->changedStoriesTitle = 'Stories Modifiées';
$lang->product->draftStories = 'Brouillon [S]';
$lang->product->draftStoriesTitle = 'Stories en Analyse';
$lang->product->reviewingStories = "Reviewing [S]";
$lang->product->reviewingStoriesTitle = "Reviewing Stories";
$lang->product->closedStories = 'Fermées [S]';
$lang->product->closedStoriesTitle = 'Stories Fermées';
$lang->product->storyCompleteRate = "{$lang->SRCommon} Completion rate";
+2
View File
@@ -72,6 +72,8 @@ $lang->product->changedStories = "已变更{$lang->SRCommon}";
$lang->product->changedStoriesTitle = "已变更{$lang->SRCommon}";
$lang->product->draftStories = "草稿{$lang->SRCommon}";
$lang->product->draftStoriesTitle = "草稿{$lang->SRCommon}";
$lang->product->reviewingStories = "评审中{$lang->SRCommon}";
$lang->product->reviewingStoriesTitle = "评审中{$lang->SRCommon}";
$lang->product->closedStories = "已关闭{$lang->SRCommon}";
$lang->product->closedStoriesTitle = "已关闭{$lang->SRCommon}";
$lang->product->storyCompleteRate = "{$lang->SRCommon}完成率";
+19 -11
View File
@@ -1183,15 +1183,16 @@ class productModel extends model
/**
* Get project list by product.
*
* @param int $productID
* @param string $browseType
* @param int $branch
* @param int $involved
* @param string $orderBy
* @param int $productID
* @param string $browseType
* @param int $branch
* @param int $involved
* @param string $orderBy
* @param object $pager
* @access public
* @return array
*/
public function getProjectListByProduct($productID, $browseType = 'all', $branch = 0, $involved = 0, $orderBy = 'order_desc')
public function getProjectListByProduct($productID, $browseType = 'all', $branch = 0, $involved = 0, $orderBy = 'order_desc', $pager = null)
{
$projectList = $this->dao->select('t2.*')->from(TABLE_PROJECTPRODUCT)->alias('t1')
->leftJoin(TABLE_PROJECT)->alias('t2')->on('t1.project = t2.id')
@@ -1210,6 +1211,7 @@ class productModel extends model
->beginIF($branch !== '' and $branch !== 'all')->andWhere('t1.branch')->in($branch)->fi()
->andWhere('t2.deleted')->eq('0')
->orderBy($orderBy)
->page($pager)
->fetchAll('id');
/* Determine how to display the name of the program. */
@@ -1231,12 +1233,13 @@ class productModel extends model
* @param int $branch
* @param int $involved
* @param string $orderBy
* @param object $pager
* @access public
* @return array
*/
public function getProjectStatsByProduct($productID, $browseType = 'all', $branch = 0, $involved = 0, $orderBy = 'order_desc')
public function getProjectStatsByProduct($productID, $browseType = 'all', $branch = 0, $involved = 0, $orderBy = 'order_desc', $pager = null)
{
$projects = $this->getProjectListByProduct($productID, $browseType, $branch, $involved, $orderBy);
$projects = $this->getProjectListByProduct($productID, $browseType, $branch, $involved, $orderBy, $pager);
if(empty($projects)) return array();
$projectKeys = array_keys($projects);
@@ -1817,11 +1820,15 @@ class productModel extends model
{
$programKeys = array(0 => 0);
foreach($products as $product) $programKeys[] = $product->program;
$programs = $this->dao->select('id,name')->from(TABLE_PROGRAM)
$programs = $this->dao->select('id,name,PM')->from(TABLE_PROGRAM)
->where('id')->in(array_unique($programKeys))
->fetchPairs();
->fetchAll('id');
foreach($products as $product) $product->programName = isset($programs[$product->program]) ? $programs[$product->program] : '';
foreach($products as $product)
{
$product->programName = isset($programs[$product->program]) ? $programs[$product->program]->name : '';
$product->programPM = isset($programs[$product->program]) ? $programs[$product->program]->PM : '';
}
}
$stats = array();
@@ -2045,6 +2052,7 @@ class productModel extends model
/* Init vars. */
/* Program name. */
$productStructure[$product->program]['programName'] = $product->programName;
$productStructure[$product->program]['programPM'] = $product->programPM;
$productStructure[$product->program] = $this->statisticData('program', $productStructure, $product);
}
}
+32 -3
View File
@@ -52,6 +52,9 @@
<a class='table-nest-toggle table-nest-toggle-global' data-expand-text='<?php echo $lang->expand; ?>' data-collapse-text='<?php echo $lang->collapse; ?>'></a>
<?php common::printOrderLink('name', $orderBy, $vars, $lang->product->name);?>
</th>
<th class='c-PO' rowspan="2">
<?php common::printOrderLink('PO', $orderBy, $vars, $lang->product->manager);?>
</th>
<th class="c-story" colspan="5"><?php echo $lang->story->story;?></th>
<th class="c-bug" colspan="2"><?php echo $lang->bug->common;?></th>
<th class="c-plan" rowspan="2"><?php echo $lang->product->plan;?></th>
@@ -101,7 +104,21 @@
<?php endif;?>
<td class='text-left table-nest-title' title="<?php echo $program['programName']?>">
<span class="table-nest-icon icon table-nest-toggle"></span>
<?php echo $program['programName']?>
&nbsp;<span class="icon icon-cards-view"></span>
<span><?php echo $program['programName']?></span>
</td>
<td class='c-manager'>
<?php
if(!empty($program['programPM']))
{
$programPM = $program['programPM'];
$userName = zget($users, $programPM);
echo html::smallAvatar(array('avatar' => $usersAvatar[$programPM], 'account' => $programPM, 'name' => $userName), 'avatar-circle avatar-top avatar-' . zget($userIdPairs, $programPM));
$userID = isset($userIdPairs[$programPM]) ? $userIdPairs[$programPM] : '';
echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), $userName, '', "title='{$userName}' data-toggle='modal' data-type='iframe' data-width='600'");
}
?>
</td>
<td><?php echo $program['draftStories'];?></td>
<td><?php echo $program['activeStories'];?></td>
@@ -142,6 +159,7 @@
<span class="table-nest-icon icon table-nest-toggle"></span>
<?php echo $line['lineName']?>
</td>
<td></td>
<td><?php echo isset($line['draftStories']) ? $line['draftStories'] : 0;?></td>
<td><?php echo isset($line['activeStories']) ? $line['activeStories'] : 0;?></td>
<td><?php echo isset($line['changingStories']) ? $line['changingStories'] : 0;?></td>
@@ -160,8 +178,7 @@
<?php if(isset($line['products']) and is_array($line['products'])):?>
<?php foreach($line['products'] as $productID => $product):?>
<?php
$totalStories = $product->stories['active'] + $product->stories['closed'] + $product->stories['draft'] + $product->stories['changing'] + $product->stories['reviewing'];
$totalRequirements = $product->requirements['active'] + $product->requirements['closed'] + $product->requirements['draft'] + $product->requirements['changing'] + $product->requirements['reviewing'];
$totalStories = $product->stories['active'] + $product->stories['closed'] + $product->stories['draft'] + $product->stories['changing'] + $product->stories['reviewing'];
$trClass = '';
if($product->line)
@@ -194,6 +211,18 @@
echo html::a($this->createLink('product', 'browse', 'productID=' . $product->id), $product->name);
?>
</td>
<td class='c-manager'>
<?php
if(!empty($product->PO))
{
$userName = zget($users, $product->PO);
echo html::smallAvatar(array('avatar' => $usersAvatar[$product->PO], 'account' => $product->PO, 'name' => $userName), 'avatar-circle avatar-' . zget($userIdPairs, $product->PO));
$userID = isset($userIdPairs[$product->PO]) ? $userIdPairs[$product->PO] : '';
echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), $userName, '', "title='{$userName}' data-toggle='modal' data-type='iframe' data-width='600'");
}
?>
</td>
<td><?php echo $product->stories['draft'];?></td>
<td><?php echo $product->stories['active'];?></td>
<td><?php echo $product->stories['changing'];?></td>
+16 -12
View File
@@ -49,11 +49,13 @@
<?php else:?>
<th><?php echo $lang->execution->name;?></th>
<?php endif;?>
<?php if(strpos('all,undone', $status) !== false):?>
<th class='c-status'><?php echo $lang->project->status;?></th>
<?php endif;?>
<th class='c-user text-left'><?php echo $lang->project->PM;?></th>
<th class="c-budget text-right"><?php echo $lang->project->budget;?></th>
<th class='c-date'><?php echo $lang->project->begin;?></th>
<th class='c-date'><?php echo $lang->project->end;?></th>
<th class='c-status'><?php echo $lang->project->status;?></th>
<th class="c-budget text-center"><?php echo $lang->project->budget;?></th>
<th class="c-number text-right"><?php echo $lang->project->estimate;?></th>
<th class="c-number text-right"><?php echo $lang->project->consume;?></th>
<th class="c-progress"><?php echo $lang->project->progress;?></th>
@@ -71,28 +73,29 @@
<?php
if($config->systemMode == 'new')
{
echo html::a($this->createLink('project', 'index', 'project=' . $project->id), $project->name);
echo html::a($this->createLink('project', 'index', 'project=' . $project->id), $project->name, '', "title='{$project->name} ({$lang->project->{$project->model}})'");
}
else
{
echo html::a($this->createLink('execution', 'task', 'project=' . $project->id), $project->name);
echo html::a($this->createLink('execution', 'task', 'project=' . $project->id), $project->name, '', "title='{$project->name}'");
}
?>
</td>
<?php if(strpos('all,undone', $status) !== false):?>
<?php $statusTitle = $this->processStatus('project', $project);?>
<td class='c-status' title='<?php echo $statusTitle;?>'>
<span class="status-project status-<?php echo $project->status?>"><?php echo $statusTitle;?></span>
</td>
<?php endif;?>
<td class='padding-right'>
<?php $userID = isset($PMList[$project->PM]) ? $PMList[$project->PM]->id : ''?>
<?php if(!empty($project->PM)) echo html::a($this->createLink('user', 'profile', "userID=$userID", '', true), zget($users, $project->PM), '', "data-toggle='modal' data-type='iframe' data-width='800'");?>
</td>
<td class='padding-right text-left'><?php echo $project->begin;?></td>
<td class='padding-right text-left'><?php echo $project->end;?></td>
<?php $status = $this->processStatus('project', $project);?>
<td class='c-status' title='<?php echo $status;?>'>
<span class="status-project status-<?php echo $project->status?>"><?php echo $status;?></span>
</td>
<?php $projectBudget = in_array($this->app->getClientLang(), array('zh-cn','zh-tw')) ? round((float)$project->budget / 10000, 2) . $this->lang->project->tenThousand : round((float)$project->budget, 2);?>
<?php $budgetTitle = $project->budget != 0 ? zget($this->lang->project->currencySymbol, $project->budgetUnit) . ' ' . $projectBudget : $this->lang->project->future;?>
<?php $textStyle = $project->budget != 0 ? 'text-right' : 'text-center';?>
<td title='<?php echo $budgetTitle;?>' class="text-ellipsis <?php echo $textStyle;?>"><?php echo $budgetTitle;?></td>
<td title='<?php echo $budgetTitle;?>' class="text-ellipsis text-right"><?php echo $budgetTitle;?></td>
<td class='padding-right text-left'><?php echo $project->begin;?></td>
<td class='padding-right text-left'><?php echo $project->end;?></td>
<td class="text-right" title="<?php echo $project->hours->totalEstimate . ' ' . $lang->execution->workHour;?>"><?php echo $project->hours->totalEstimate . $lang->execution->workHourUnit;?></td>
<td class="text-right" title="<?php echo $project->hours->totalConsumed . ' ' . $lang->execution->workHour;?>"><?php echo $project->hours->totalConsumed . $lang->execution->workHourUnit;?></td>
<td>
@@ -104,6 +107,7 @@
<?php endforeach;?>
</tbody>
</table>
<div class='table-footer'><?php echo $pager->show('left', 'pagerjs');?></div>
</form>
<?php endif;?>
</div>
+1
View File
@@ -19,6 +19,7 @@ $config->productplan->future = '2030-01-01';
global $app, $lang;
$app->loadLang('productplan');
$config->productplan->search['module'] = 'productplan';
$config->productplan->browse = new stdclass();
$config->productplan->search['fields']['id'] = $lang->productplan->id;
$config->productplan->search['fields']['title'] = $lang->productplan->title;

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