diff --git a/framework/base/control.class.php b/framework/base/control.class.php index 0c887bfd3d..8a5211adb2 100644 --- a/framework/base/control.class.php +++ b/framework/base/control.class.php @@ -445,44 +445,114 @@ class baseControl */ public function getCSS($moduleName, $methodName) { - $moduleName = strtolower(trim($moduleName)); - $methodName = strtolower(trim($methodName)); + $moduleName = strtolower(trim($moduleName)); + $methodName = strtolower(trim($methodName)); - $modulePath = $this->app->getModulePath($this->appName, $moduleName); - $cssExtPath = $this->app->getModuleExtPath($this->appName, $moduleName, 'css') ; + $modulePath = $this->app->getModulePath($this->appName, $moduleName); + $cssExtPath = $this->app->getModuleExtPath($this->appName, $moduleName, 'css') ; - $css = ''; - $mainCssFile = $modulePath . 'css' . DS . $this->devicePrefix . 'common.css'; - $methodCssFile = $modulePath . 'css' . DS . $this->devicePrefix . $methodName . '.css'; - if(file_exists($mainCssFile)) $css .= file_get_contents($mainCssFile); - if(is_file($methodCssFile)) $css .= file_get_contents($methodCssFile); + $clientLang = $this->app->getClientLang(); + $notCNLang = strpos('|zh-cn|zh-tw|', "|{$clientLang}|") === false; + + $css = ''; + $devicePrefix = $this->devicePrefix; + $mainCssPath = $modulePath . 'css' . DS; + + /* Common css file. like module/story/css/common.css. */ + $mainCssFile = $mainCssPath . $devicePrefix . 'common.css'; + if(is_file($mainCssFile)) $css .= file_get_contents($mainCssFile); + + /* Common css file with lang. like module/story/css/common.en.css. */ + $mainCssLangFile = $mainCssPath . $devicePrefix . "common.{$clientLang}.css"; + if(!file_exists($mainCssLangFile) and $notCNLang) $mainCssLangFile = $mainCssPath . $devicePrefix . "common.en.css"; + if(is_file($mainCssLangFile)) $css .= file_get_contents($mainCssLangFile); + + /* Method css file. like module/story/css/create.css. */ + $methodCssFile = $mainCssPath . $devicePrefix . $methodName . '.css'; + if(is_file($methodCssFile)) $css .= file_get_contents($methodCssFile); + + /* Method css file with lang. like module/story/css/create.en.css. */ + $methodCssLangFile = $mainCssPath . $devicePrefix . "{$methodName}.{$clientLang}.css"; + if(!file_exists($methodCssLangFile) and $notCNLang) $methodCssLangFile = $mainCssPath . $devicePrefix . "{$methodName}.en.css"; + if(is_file($methodCssLangFile)) $css .= file_get_contents($methodCssLangFile); if(!empty($cssExtPath)) { $cssMethodExt = $cssExtPath['common'] . $methodName . DS; $cssCommonExt = $cssExtPath['common'] . 'common' . DS; - $cssExtFiles = glob($cssCommonExt . $this->devicePrefix . '*.css'); - if(!empty($cssExtFiles) and is_array($cssExtFiles)) foreach($cssExtFiles as $cssFile) $css .= file_get_contents($cssFile); + $cssExtFiles = glob($cssCommonExt . $devicePrefix . '*.css'); + if(!empty($cssExtFiles) and is_array($cssExtFiles)) $css .= $this->getExtCSS($cssExtFiles); - $cssExtFiles = glob($cssMethodExt . $this->devicePrefix . '*.css'); - if(!empty($cssExtFiles) and is_array($cssExtFiles)) foreach($cssExtFiles as $cssFile) $css .= file_get_contents($cssFile); + $cssExtFiles = glob($cssMethodExt . $devicePrefix . '*.css'); + if(!empty($cssExtFiles) and is_array($cssExtFiles)) $css .= $this->getExtCSS($cssExtFiles); if(!empty($cssExtPath['site'])) { $cssMethodExt = $cssExtPath['site'] . $methodName . DS; $cssCommonExt = $cssExtPath['site'] . 'common' . DS; - $cssExtFiles = glob($cssCommonExt . $this->devicePrefix . '*.css'); - if(!empty($cssExtFiles) and is_array($cssExtFiles)) foreach($cssExtFiles as $cssFile) $css .= file_get_contents($cssFile); + $cssExtFiles = glob($cssCommonExt . $devicePrefix . '*.css'); + if(!empty($cssExtFiles) and is_array($cssExtFiles)) $css .= $this->getExtCSS($cssExtFiles); - $cssExtFiles = glob($cssMethodExt . $this->devicePrefix . '*.css'); - if(!empty($cssExtFiles) and is_array($cssExtFiles)) foreach($cssExtFiles as $cssFile) $css .= file_get_contents($cssFile); + $cssExtFiles = glob($cssMethodExt . $devicePrefix . '*.css'); + if(!empty($cssExtFiles) and is_array($cssExtFiles)) $css .= $this->getExtCSS($cssExtFiles); } } return $css; } + /** + * Get extension css and extension css with lang. + * + * @param array $files + * @access public + * @return string + */ + public function getExtCSS($files) + { + $clientLang = $this->app->getClientLang(); + $notCNLang = strpos('|zh-cn|zh-tw|', "|{$clientLang}|") === false; + + $filePairs = array(); + foreach($files as $cssFile) + { + $fileName = basename($cssFile); + $filePairs[$fileName] = $cssFile; + } + + $css = ''; + $usedCodes = array(); + foreach($filePairs as $fileName => $cssFile) + { + if(preg_match('/^\w+\.css$/', $fileName)) + { + /* Method extension css file. like module/story/ext/css/create/effort.css. */ + $css .= file_get_contents($cssFile); + list($code) = explode('.', $fileName); + } + else + { + list($code) = explode('.', $fileName); + if(isset($usedCodes[$code])) continue; + } + + + /* Method extension css file. like module/story/ext/css/create/effort.zh-cn.css. */ + if(isset($filePairs["{$code}.{$clientLang}.css"])) + { + $css .= file_get_contents($filePairs["{$code}.{$clientLang}.css"]); + } + elseif($notCNLang and isset($filePairs["{$code}.en.css"])) + { + $css .= file_get_contents($filePairs["{$code}.en.css"]); + } + $usedCodes[$code] = $code; + } + + return $css; + } + /** * 获取适用于当前方法的js:该模块公用的js + 当前方法的js + 扩展的js。 * Get js codes applied to current method: module common js + method js + extension js. @@ -739,8 +809,11 @@ class baseControl * Load the control file. */ if(!is_file($file2Included)) $this->app->triggerError("The control file $file2Included not found", __FILE__, __LINE__, $exit = true); - chdir(dirname($file2Included)); - if(!class_exists($moduleName)) helper::import($file2Included); + if(!class_exists($moduleName)) + { + chdir(dirname($file2Included)); + helper::import($file2Included); + } /** * 设置调用的类名。 diff --git a/framework/control.class.php b/framework/control.class.php index 385fdee3b1..b98973b91f 100644 --- a/framework/control.class.php +++ b/framework/control.class.php @@ -21,10 +21,10 @@ include dirname(__FILE__) . '/base/control.class.php'; class control extends baseControl { /** - * 加载指定模块的model文件。 - * Load the model file of one module. - * - * Extension: set appName as empty. + * 企业版部分功能是从然之合并过来的。然之代码中调用loadModel方法时传递了一个非空的appName,在禅道中会导致错误。 + * 调用父类的loadModel方法来避免这个错误。 + * Some codes merged from ranzhi called the function loadModel with a non-empty appName which causes an error in zentao. + * Call the parent function with empty appName to avoid this error. * * @param string $moduleName 模块名,如果为空,使用当前模块。The module name, if empty, use current module's name. * @param string $appName The app name, if empty, use current app's name. @@ -33,52 +33,7 @@ class control extends baseControl */ public function loadModel($moduleName = '', $appName = '') { - $appName = ''; - - if(empty($moduleName)) $moduleName = $this->moduleName; - if(empty($appName)) $appName = $this->appName; - - global $loadedModels; - if(isset($loadedModels[$appName][$moduleName])) - { - $this->$moduleName = $loadedModels[$appName][$moduleName]; - $this->dao = $this->$moduleName->dao; - return $this->$moduleName; - } - - $modelFile = $this->app->setModelFile($moduleName, $appName); - - /** - * 如果没有model文件,尝试加载config配置信息。 - * If no model file, try load config. - */ - if(!helper::import($modelFile)) - { - $this->app->loadModuleConfig($moduleName, $appName); - $this->app->loadLang($moduleName, $appName); - $this->dao = new dao(); - return false; - } - - /** - * 如果没有扩展文件,model类名是$moduleName + 'model',如果有扩展,还需要增加ext前缀。 - * If no extension file, model class name is $moduleName + 'model', else with 'ext' as the prefix. - */ - $modelClass = class_exists('ext' . $appName . $moduleName. 'model') ? 'ext' . $appName . $moduleName . 'model' : $appName . $moduleName . 'model'; - if(!class_exists($modelClass)) - { - $modelClass = class_exists('ext' . $moduleName. 'model') ? 'ext' . $moduleName . 'model' : $moduleName . 'model'; - if(!class_exists($modelClass)) $this->app->triggerError(" The model $modelClass not found", __FILE__, __LINE__, $exit = true); - } - - /** - * 初始化model对象,在control对象中可以通过$this->$moduleName来引用。同时将dao对象赋为control对象的成员变量,方便引用。 - * Init the model object thus you can try $this->$moduleName to access it. Also assign the $dao object as a member of control object. - */ - $loadedModels[$appName][$moduleName] = new $modelClass($appName); - $this->$moduleName = $loadedModels[$appName][$moduleName]; - $this->dao = $this->$moduleName->dao; - return $this->$moduleName; + return parent::loadModel($moduleName); } /** @@ -198,7 +153,7 @@ class control extends baseControl /** * Execute hooks of a method. * - * @param int $objectID + * @param int $objectID The id of an object. The object maybe a bug | build | feedback | product | productplan | project | release | story | task | testcase | testsuite | testtask. * @access public * @return void */ @@ -214,7 +169,7 @@ class control extends baseControl /** * Build operate menu of a method. * - * @param object $object product|project|productplan|release|build|story|task|bug|testtask|testcase|testsuite + * @param object $object product|project|productplan|release|build|story|task|bug|testtask|testcase|testsuite * @param string $displayOn view|browse * @access public * @return void @@ -230,9 +185,9 @@ class control extends baseControl /** * Print extend fields. * - * @param object $object - * @param string $type - * @param string $extras + * @param object $object bug | build | feedback | product | productplan | project | release | story | task | testcase | testsuite | testtask + * @param string $type table | div + * @param string $extras columns=1,mode=value,position=right|right|all * @access public * @return void */ diff --git a/framework/model.class.php b/framework/model.class.php index caa3db33d1..5132163f4c 100644 --- a/framework/model.class.php +++ b/framework/model.class.php @@ -21,12 +21,10 @@ include dirname(__FILE__) . '/base/model.class.php'; class model extends baseModel { /** - * 加载一个模块的model。加载完成后,使用$this->$moduleName来访问这个model对象。 - * 比如:loadModel('user')引入user模块的model实例对象,可以通过$this->user来访问它。 - * - * Load the model of one module. After loaded, can use $this->$moduleName to visit the model object. - * - * Extension: set appName as empty. + * 企业版部分功能是从然之合并过来的。然之代码中调用loadModel方法时传递了一个非空的appName,在禅道中会导致错误。 + * 调用父类的loadModel方法来避免这个错误。 + * Some codes merged from ranzhi called the function loadModel with a non-empty appName which causes an error in zentao. + * Call the parent function with empty appName to avoid this error. * * @param string $moduleName * @access public @@ -34,31 +32,7 @@ class model extends baseModel */ public function loadModel($moduleName, $appName = '') { - $appName = ''; - - if(empty($moduleName)) return false; - if(empty($appName)) $appName = $this->appName; - - global $loadedModels; - if(isset($loadedModels[$appName][$moduleName])) - { - $this->$moduleName = $loadedModels[$appName][$moduleName]; - return $this->$moduleName; - } - - $modelFile = $this->app->setModelFile($moduleName, $appName); - - if(!helper::import($modelFile)) return false; - $modelClass = class_exists('ext' . $appName . $moduleName. 'model') ? 'ext' . $appName . $moduleName . 'model' : $appName . $moduleName . 'model'; - if(!class_exists($modelClass)) - { - $modelClass = class_exists('ext' . $moduleName. 'model') ? 'ext' . $moduleName . 'model' : $moduleName . 'model'; - if(!class_exists($modelClass)) $this->app->triggerError(" The model $modelClass not found", __FILE__, __LINE__, $exit = true); - } - - $loadedModels[$appName][$moduleName] = new $modelClass($appName); - $this->$moduleName = $loadedModels[$appName][$moduleName]; - return $this->$moduleName; + return parent::loadModel($moduleName); } /** diff --git a/framework/router.class.php b/framework/router.class.php index 02c9a94cd3..fd1cbd4bdc 100755 --- a/framework/router.class.php +++ b/framework/router.class.php @@ -39,9 +39,18 @@ class router extends baseRouter public $rawMethod; /** - * Add custom langs when set client lang. + * 标记是否是工作流 + * Whether the tag is a workflow * - * @param string $lang zh-cn|zh-tw|zh-hk|en + * @var bool + * @access public + */ + public $isFlow = false; + + /** + * Merge system and translated langs. + * + * @param string $lang zh-cn|zh-tw|en * @access public * @return void */ @@ -57,8 +66,10 @@ class router extends baseRouter } /** - * 加载语言文件,返回全局$lang对象。 - * Load lang and return it as the global lang object. + * 企业版部分功能是从然之合并过来的。然之代码中调用loadLang方法时传递了一个非空的appName,在禅道中会导致错误。 + * 把appName设置为空来避免这个错误。 + * Some codes merged from ranzhi called the function loadLang with a non-empty appName which causes an error in zentao. + * Set the value of appName to empty to avoid this error. * * @param string $moduleName the module name * @param string $appName the app name @@ -112,8 +123,10 @@ class router extends baseRouter $productProject = $productProject->value; list($productCommon, $projectCommon) = explode('_', $productProject); } - $lang->productCommon = isset($this->config->productCommonList[$this->clientLang][(int)$productCommon]) ? $this->config->productCommonList[$this->clientLang][(int)$productCommon] : $this->config->productCommonList['en'][0]; - $lang->projectCommon = isset($this->config->projectCommonList[$this->clientLang][(int)$projectCommon]) ? $this->config->projectCommonList[$this->clientLang][(int)$projectCommon] : $this->config->projectCommonList['en'][0]; + + /* Set productCommon and projectCommon. Default english lang. */ + $lang->productCommon = isset($this->config->productCommonList[$this->clientLang][(int)$productCommon]) ? $this->config->productCommonList[$this->clientLang][(int)$productCommon] : $this->config->productCommonList['en'][(int)$productCommon]; + $lang->projectCommon = isset($this->config->projectCommonList[$this->clientLang][(int)$projectCommon]) ? $this->config->projectCommonList[$this->clientLang][(int)$projectCommon] : $this->config->projectCommonList['en'][(int)$projectCommon]; } parent::loadLang($moduleName, $appName); @@ -165,13 +178,10 @@ class router extends baseRouter } /** - * 加载模块的config文件,返回全局$config对象。 - * 如果该模块是common,加载$configRoot的配置文件,其他模块则加载其模块的配置文件。 - * - * Load config and return it as the global config object. - * If the module is common, search in $configRoot, else in $modulePath. - * - * Extension: set appName as empty. + * 企业版部分功能是从然之合并过来的。然之代码中调用loadModuleConfig方法时传递了一个非空的appName,在禅道中会导致错误。 + * 把appName设置为空来避免这个错误。 + * Some codes merged from ranzhi called the function loadModuleConfig with a non-empty appName which causes an error in zentao. + * Set the value of appName to empty to avoid this error. * * @param string $moduleName module name * @param string $appName app name @@ -222,8 +232,7 @@ class router extends baseRouter } /** - * 调用父类方法时不传递$appName参数,保证父类方法中$appName值为空。 - * The $appName parameter is not passed when calling the parent class method, ensuring that the $appName value in the parent class method is null. + * The alias for loadModuleConfig. * * @param string $moduleName * @param string $appName @@ -286,6 +295,10 @@ class router extends baseRouter */ public function setControlFile($exitIfNone = true) { + /* Set raw module and method name for fetch control. */ + if(empty($this->rawModule)) $this->rawModule = $this->moduleName; + if(empty($this->rawMethod)) $this->rawMethod = $this->methodName; + /* If is not a biz version or is in install mode or in in upgrade mode, call parent method. */ if(!isset($this->config->bizVersion) or defined('IN_INSTALL') or defined('IN_UPGRADE')) return parent::setControlFile($exitIfNone); @@ -305,6 +318,7 @@ class router extends baseRouter { $this->rawModule = $this->moduleName; $this->rawMethod = 'browse'; + $this->isFlow = true; $moduleName = 'flow'; $methodName = 'browse'; @@ -318,6 +332,7 @@ class router extends baseRouter { $this->rawModule = $this->moduleName; $this->rawMethod = $this->methodName; + $this->isFlow = true; $this->loadModuleConfig('workflowaction'); @@ -434,8 +449,8 @@ class router extends baseRouter } /** - * 如果$this->rawModule和$this->rawMethod的值不为空,说明这个请求需要工作流引擎来处理,则要根据工作流引擎的需要重新设置参数。 - * If the values of $this->rawModule and $this->rawMethod are not empty, indicating that the request needs to be processed + * 如果$this->isFlow的值为true,说明这个请求需要工作流引擎来处理,则要根据工作流引擎的需要重新设置参数。 + * If the values of $this->isFlow is true, indicating that the request needs to be processed * by the workflow engine, the parameters are reset according to the needs of the workflow engine. * * @param array $defaultParams the default params defined by the method. @@ -445,14 +460,14 @@ class router extends baseRouter */ public function mergeParams($defaultParams, $passedParams) { - /* If the rawModule and rawMethod is not empty, reset the passed params. */ - if($this->rawModule && $this->rawMethod) + /* If the isFlow is true, reset the passed params. */ + if($this->isFlow) { $passedParams = array_reverse($passedParams); /* 如果请求的方法名不是browse、create、edit、view、delete、export中的任何一个,则需要添加action参数来传递请求的方法名。 */ /* If the requested method name is not any of browse, create, edit, view, delete, or export, you need to add an action parameter to pass the requested method name. */ - if(!in_array($this->rawMethod, $this->config->workflowaction->default->actions)) $passedParams['action'] = $this->rawMethod; + if(isset($this->config->workflowaction->default->actions) and !in_array($this->rawMethod, $this->config->workflowaction->default->actions)) $passedParams['action'] = $this->rawMethod; /* 添加module参数来传递请求的模块名。 */ /* Add the module parameter to pass the requested module name. */ $passedParams['module'] = $this->rawModule; diff --git a/lib/base/front/front.class.php b/lib/base/front/front.class.php index 6fbe58ac12..4281932177 100644 --- a/lib/base/front/front.class.php +++ b/lib/base/front/front.class.php @@ -1075,6 +1075,7 @@ EOT; $jsLang = new stdclass(); $jsLang->submitting = isset($lang->loading) ? $lang->loading : ''; $jsLang->save = $jsConfig->save; + $jsLang->expand = isset($lang->expand) ? $lang->expand : ''; $jsLang->timeout = isset($lang->timeout) ? $lang->timeout : ''; $js = self::start(false); diff --git a/lib/filter/filter.class.php b/lib/filter/filter.class.php index 03c47426ac..a6e1ae9d42 100644 --- a/lib/filter/filter.class.php +++ b/lib/filter/filter.class.php @@ -34,6 +34,7 @@ class fixer extends baseFixer { $fields = str_replace(' ', '', trim($fields)); + /* Get extend field by flow. */ global $config; $flowFields = array(); if(isset($config->bizVersion)) @@ -45,14 +46,27 @@ class fixer extends baseFixer } foreach($this->data as $field => $value) { - if(isset($flowFields[$field]) and is_array($value)) $this->data->$field = implode(',', $value); + /* Implode array when form has array. */ + if(isset($flowFields[$field]) and is_array($value)) + { + $canImplode = true; + foreach($value as $k => $v) + { + if(is_object($v) or is_array($v)) + { + $canImplode = false; + break; + } + } + if($canImplode) $this->data->$field = implode(',', $value); + } $this->specialChars($field); } - if(empty($fields)) return $this->data; if(strpos($fields, ',') === false) return $this->data->$fields; + /* Process fields for check by key. */ $fields = array_flip(explode(',', $fields)); foreach($this->data as $field => $value) { diff --git a/lib/phpmailer/class.smtp.php b/lib/phpmailer/class.smtp.php index ed372e3e2e..1d2aa89c82 100644 --- a/lib/phpmailer/class.smtp.php +++ b/lib/phpmailer/class.smtp.php @@ -126,11 +126,12 @@ class SMTP { } // connect to the smtp server - $this->smtp_conn = fsockopen($host, // the host of the server - $port, // the port to use - $errno, // error number if any - $errstr, // error message if any - $tval); // give up after ? secs + // Replace fsockopen for don't validate remote hosts + $contextOptions['ssl']['verify_host'] = false; + $contextOptions['ssl']['verify_peer'] = false; + $contextOptions['ssl']['verify_peer_name'] = false; + $context = stream_context_create($contextOptions); + $this->smtp_conn = stream_socket_client($host . ':' . $port, $errno, $errstr, $tval, STREAM_CLIENT_CONNECT, $context); // verify we connected properly if(empty($this->smtp_conn)) { $this->error = array("error" => "Failed to connect to server", @@ -616,7 +617,7 @@ class SMTP { protected function parseHelloFields($type) { - $this->server_caps = []; + $this->server_caps = array(); $lines = explode("\n", $this->helo_rply); foreach ($lines as $n => $s) { @@ -638,7 +639,7 @@ class SMTP { break; case 'AUTH': if (!is_array($fields)) { - $fields = []; + $fields = array(); } break; default: diff --git a/module/action/lang/en.php b/module/action/lang/en.php index 3f94f775a7..b971bdd570 100755 --- a/module/action/lang/en.php +++ b/module/action/lang/en.php @@ -19,6 +19,7 @@ $lang->action->actor = 'User'; $lang->action->action = 'Action'; $lang->action->actionID = 'Action ID'; $lang->action->date = 'Date'; +$lang->action->extra = 'Extra'; $lang->action->trash = 'Recycle'; $lang->action->undelete = 'Restore'; @@ -87,7 +88,7 @@ $lang->action->objectTypes['testreport'] = 'Report'; $lang->action->objectTypes['entry'] = 'Entry'; $lang->action->objectTypes['webhook'] = 'Webhook'; -/* 用来描述操作历史记录。*/ +/* Used to describe operation history. */ $lang->action->desc = new stdclass(); $lang->action->desc->common = '$date, $action by $actor.' . "\n"; $lang->action->desc->extra = '$date, $action as $extra by $actor.' . "\n"; @@ -129,7 +130,7 @@ $lang->action->desc->diff2 = '%s is changed. Th $lang->action->desc->diff3 = 'File Name %s was changed to %s .' . "\n"; $lang->action->desc->linked2bug = '$date, linked to $extra by $actor'; -/* 子任务修改父任务的历史操作记录 */ +/* Used to describe the history of operations related to parent-child tasks. */ $lang->action->desc->createchildren = '$date, $actor created a child task $extra。' . "\n"; $lang->action->desc->linkchildtask = '$date, $actor linked a child task $extra。' . "\n"; $lang->action->desc->linkchildtask = '$date, $actor linked a child task $extra。' . "\n"; @@ -137,11 +138,11 @@ $lang->action->desc->unlinkchildrentask = '$date, $actor unlink $lang->action->desc->linkparenttask = '$date, $actor linked to a parent task $extra。' . "\n"; $lang->action->desc->unlinkparenttask = '$date, $actor unlinked a parent task $extra。' . "\n"; -/* 关联用例和移除用例时的历史操作记录。*/ +/* Historical record of actions when associating and removing cases. */ $lang->action->desc->linkrelatedcase = '$date, $actor linked a case $extra.' . "\n"; $lang->action->desc->unlinkrelatedcase = '$date, $actor unlinked a case $extra.' . "\n"; -/* 用来显示动态信息。*/ +/* Used to display dynamic information. */ $lang->action->label = new stdclass(); $lang->action->label->created = 'created '; $lang->action->label->opened = 'opened '; @@ -209,7 +210,7 @@ $lang->action->label->batchcreate = "batch created tasks"; $lang->action->label->createchildren = "create child tasks"; $lang->action->label->managed = "managed"; -/* 动态信息按照对象分组 */ +/* Dynamic information is grouped by object. */ $lang->action->dynamicAction = new stdclass; $lang->action->dynamicAction->todo['opened'] = 'Create Todo'; $lang->action->dynamicAction->todo['edited'] = 'Edit Todo'; @@ -357,7 +358,7 @@ $lang->action->dynamicAction->user['loginxuanxuan'] = 'Login Desktop'; $lang->action->dynamicAction->entry['created'] = 'Add Application'; $lang->action->dynamicAction->entry['edited'] = 'Edit Application'; -/* 用来生成相应对象的链接。*/ +/* Generate the corresponding object link. */ $lang->action->label->product = $lang->productCommon . '|product|view|productID=%s'; $lang->action->label->productplan = 'Plan|productplan|view|productID=%s'; $lang->action->label->release = 'Release|release|view|productID=%s'; @@ -402,7 +403,7 @@ $lang->action->search->objectTypeList['testsuite'] = 'Suite'; $lang->action->search->objectTypeList['caselib'] = 'Library'; $lang->action->search->objectTypeList['testreport'] = 'Report'; -/* 用来在动态显示中显示动作 */ +/* Used to display actions in dynamic method. */ $lang->action->search->label[''] = ''; $lang->action->search->label['created'] = $lang->action->label->created; $lang->action->search->label['opened'] = $lang->action->label->opened; diff --git a/module/action/lang/zh-cn.php b/module/action/lang/zh-cn.php index 665d1098c3..e6d26c50d3 100755 --- a/module/action/lang/zh-cn.php +++ b/module/action/lang/zh-cn.php @@ -19,6 +19,7 @@ $lang->action->actor = '操作者'; $lang->action->action = '动作'; $lang->action->actionID = '记录ID'; $lang->action->date = '日期'; +$lang->action->extra = '附加值'; $lang->action->trash = '回收站'; $lang->action->undelete = '还原'; @@ -129,7 +130,7 @@ $lang->action->desc->diff2 = '修改了 %s, $lang->action->desc->diff3 = '将文件名 %s 改为 %s 。' . "\n"; $lang->action->desc->linked2bug = '$date 由 $actor 关联到版本 $extra'; -/* 子任务修改父任务的历史操作记录 */ +/* 用来描述和父子任务相关的操作历史记录。*/ $lang->action->desc->createchildren = '$date, 由 $actor 创建子任务 $extra。' . "\n"; $lang->action->desc->linkchildtask = '$date, 由 $actor 关联子任务 $extra。' . "\n"; $lang->action->desc->linkchildtask = '$date, 由 $actor 关联子任务 $extra。' . "\n"; diff --git a/module/action/lang/zh-tw.php b/module/action/lang/zh-tw.php index 51a07b3f3a..8c22824465 100755 --- a/module/action/lang/zh-tw.php +++ b/module/action/lang/zh-tw.php @@ -19,6 +19,7 @@ $lang->action->actor = '操作者'; $lang->action->action = '動作'; $lang->action->actionID = '記錄ID'; $lang->action->date = '日期'; +$lang->action->extra = '附加值'; $lang->action->trash = '資源回收筒'; $lang->action->undelete = '還原'; @@ -129,7 +130,7 @@ $lang->action->desc->diff2 = '修改了 %s, $lang->action->desc->diff3 = '將檔案名 %s 改為 %s 。' . "\n"; $lang->action->desc->linked2bug = '$date 由 $actor 關聯到版本 $extra'; -/* 子任務修改父任務的歷史操作記錄 */ +/* 用來描述和父子任務相關的操作歷史記錄。*/ $lang->action->desc->createchildren = '$date, 由 $actor 創建子任務 $extra。' . "\n"; $lang->action->desc->linkchildtask = '$date, 由 $actor 關聯子任務 $extra。' . "\n"; $lang->action->desc->linkchildtask = '$date, 由 $actor 關聯子任務 $extra。' . "\n"; diff --git a/module/action/model.php b/module/action/model.php index 27394bd8dd..da708c9ea9 100755 --- a/module/action/model.php +++ b/module/action/model.php @@ -45,9 +45,11 @@ class actionModel extends model $action->actor = $actor; $action->action = $actionType; $action->date = helper::now(); - $action->comment = trim(strip_tags($comment, $this->config->allowedTags)); $action->extra = $extra; + $_POST['comment'] = $comment; + $action->comment = fixer::input('post')->stripTags('comment')->get('comment'); + /* Process action. */ $action = $this->loadModel('file')->processImgURL($action, 'comment', $this->post->uid); if($autoDelete) $this->file->autoDelete($this->post->uid); @@ -978,6 +980,12 @@ class actionModel extends model { $this->dao->update(TABLE_DOCLIB)->set('deleted')->eq(0)->where($action->objectType)->eq($action->objectID)->exec(); } + /* Revert productplan project status */ + if($action->objectType == 'productplan') + { + $plan = $this->loadModel('productplan')->getById($action->objectID); + $this->loadModel('productplan')->updatePlanParentStatus($plan->parent); + } /* Update action record in action table. */ $this->dao->update(TABLE_ACTION)->set('extra')->eq(ACTIONMODEL::BE_UNDELETED)->where('id')->eq($actionID)->exec(); @@ -1059,7 +1067,7 @@ class actionModel extends model if($dateGroup) { - $lastDateActions = $this->dao->select('*')->from(TABLE_ACTION)->where($this->session->actionQueryCondition)->andWhere('`date`')->like(substr($action->originalDate, 0, 10) . '%')->orderBy($this->session->actionOrderBy)->fetchAll('id'); + $lastDateActions = $this->dao->select('*')->from(TABLE_ACTION)->where($this->session->actionQueryCondition)->andWhere("(LEFT(`date`, 10) = '" . substr($action->originalDate, 0, 10) . "')")->orderBy($this->session->actionOrderBy)->fetchAll('id'); if(count($dateGroup[$date]) < count($lastDateActions)) { unset($dateGroup[$date]); diff --git a/module/action/view/trash.html.php b/module/action/view/trash.html.php index ef7c090b5e..6e56576a07 100755 --- a/module/action/view/trash.html.php +++ b/module/action/view/trash.html.php @@ -53,7 +53,7 @@ $flow = $config->action->customFlows[$action->objectType]; $module = $flow->module; } - if(strpos(',doclib,module,webhook,workflowdatasource,workflowfield,workflowlabel,workflowlayout,workflowrule,', ",{$module},") !== false) + if(strpos(',doclib,module,webhook,', ",{$module},") !== false) { echo $action->objectName; } @@ -63,7 +63,7 @@ } ?> - actor];?> + actor);?> date;?> block->params->value = '参数值'; $lang->block->createBlock = '添加区块'; $lang->block->editBlock = '编辑区块'; $lang->block->ordersSaved = '排序已保存'; -$lang->block->confirmRemoveBlock = '确定移除区块吗?'; +$lang->block->confirmRemoveBlock = '确定隐藏区块吗?'; $lang->block->noticeNewBlock = '10.0版本以后各个视图主页提供了全新的视图,您要启用新的视图布局吗?'; $lang->block->confirmReset = '是否恢复默认布局?'; $lang->block->closeForever = '永久关闭'; diff --git a/module/block/lang/zh-tw.php b/module/block/lang/zh-tw.php index 41787aec32..b0220d7c4a 100644 --- a/module/block/lang/zh-tw.php +++ b/module/block/lang/zh-tw.php @@ -53,7 +53,7 @@ $lang->block->params->value = '參數值'; $lang->block->createBlock = '添加區塊'; $lang->block->editBlock = '編輯區塊'; $lang->block->ordersSaved = '排序已保存'; -$lang->block->confirmRemoveBlock = '確定移除區塊嗎?'; +$lang->block->confirmRemoveBlock = '確定隱藏區塊嗎?'; $lang->block->noticeNewBlock = '10.0版本以後各個視圖主頁提供了全新的視圖,您要啟用新的視圖佈局嗎?'; $lang->block->confirmReset = '是否恢復預設佈局?'; $lang->block->closeForever = '永久關閉'; diff --git a/module/block/view/dynamic.html.php b/module/block/view/dynamic.html.php index 67e8a9e9f4..d23610aaec 100644 --- a/module/block/view/dynamic.html.php +++ b/module/block/view/dynamic.html.php @@ -11,7 +11,7 @@ $i = 0; foreach($actions as $action) { - $user = isset($users[$action->actor]) ? $users[$action->actor] : $action->actor; + $user = zget($users, $action->actor); if($action->action == 'login' or $action->action == 'logout' or empty($action->objectLink)) $action->objectName = $action->objectLabel = ''; $class = $action->major ? "class='active'" : ''; echo "
  • "; diff --git a/module/block/view/productstatisticblock.html.php b/module/block/view/productstatisticblock.html.php index 6de4f89c30..2d247b3af1 100644 --- a/module/block/view/productstatisticblock.html.php +++ b/module/block/view/productstatisticblock.html.php @@ -26,7 +26,7 @@ .product-info .type-info {color: #A6AAB8; text-align: center; position: absolute; right: 0; top: 6px; width: 100px;} html[lang="en"] .product-info .type-info {color: #A6AAB8; text-align: center; position: absolute; right: 0; top: 6px; width: 90px;} .product-info .type-value, -.product-info .type-label {font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;} +.product-info .type-label {font-size: 12px; overflow: visible; text-overflow: ellipsis; white-space: nowrap;} .product-info .type-value {font-size: 14px;} .product-info .type-value > strong {font-size: 20px; color: #3C4353;} .product-info .actions {position: absolute; left: 10px; top: 14px;} diff --git a/module/block/view/todoblock.html.php b/module/block/view/todoblock.html.php index 56da2fa3e2..46cd6b7801 100644 --- a/module/block/view/todoblock.html.php +++ b/module/block/view/todoblock.html.php @@ -19,7 +19,7 @@ if(!$selfCall) die(include('./todolist.html.php')); .block-todoes .todoes-input .form-control:-ms-input-placeholder {font-size: 12px; line-height: 20px;color: #a4a8b6;} .block-todoes .todoes-input .form-control::placeholder {font-size: 12px; line-height: 20px; color: #a4a8b6;} .block-todoes .todoes {padding: 0 10px 10px 10px; margin: 0 -20px; max-height: 350px; overflow: auto; overflow-x:hidden} -.block-todoes .todoes > li {position: relative; padding: 5px 10px 5px 35px; list-style: none; white-space:nowrap; overflow: auto; overflow-x:hidden;} +.block-todoes .todoes > li {position: relative; padding: 5px 10px 5px 35px; list-style: none; white-space:nowrap; overflow: auto; overflow-x:hidden; max-width: 820px;} .block-todoes .todoes > li:hover {background-color: #e9f2fb;} .block-todoes .todo-title {padding: 5px 15px 5px 5px;} .block-todoes .todo-pri {margin: 0 5px;} diff --git a/module/branch/lang/en.php b/module/branch/lang/en.php index bf4dae07bc..eb9a8d7a76 100644 --- a/module/branch/lang/en.php +++ b/module/branch/lang/en.php @@ -12,6 +12,7 @@ $lang->branch->id = 'ID'; $lang->branch->product = 'Product'; $lang->branch->name = 'Name'; $lang->branch->order = 'Order'; +$lang->branch->deleted = 'Delete'; $lang->branch->confirmDelete = 'Do you want to delete this @branch@?'; $lang->branch->canNotDelete = 'There is data in @branch@. It cannot be deleted.'; diff --git a/module/branch/lang/zh-cn.php b/module/branch/lang/zh-cn.php index 3051ad8c11..7b2223fb70 100644 --- a/module/branch/lang/zh-cn.php +++ b/module/branch/lang/zh-cn.php @@ -12,6 +12,7 @@ $lang->branch->id = '编号'; $lang->branch->product = '所属产品'; $lang->branch->name = '名称'; $lang->branch->order = '排序'; +$lang->branch->deleted = '已删除'; $lang->branch->confirmDelete = '是否删除该@branch@?'; $lang->branch->canNotDelete = '该@branch@下已经有数据,不能删除!'; diff --git a/module/branch/lang/zh-tw.php b/module/branch/lang/zh-tw.php index e129be903c..b55e8213cb 100644 --- a/module/branch/lang/zh-tw.php +++ b/module/branch/lang/zh-tw.php @@ -12,6 +12,7 @@ $lang->branch->id = '編號'; $lang->branch->product = '所屬產品'; $lang->branch->name = '名稱'; $lang->branch->order = '排序'; +$lang->branch->deleted = '已刪除'; $lang->branch->confirmDelete = '是否刪除該@branch@?'; $lang->branch->canNotDelete = '該@branch@下已經有數據,不能刪除!'; diff --git a/module/bug/control.php b/module/bug/control.php index e9d07487fc..1e3432bf67 100644 --- a/module/bug/control.php +++ b/module/bug/control.php @@ -1591,6 +1591,7 @@ class bug extends control } if(!(in_array('platform', $productsType) or in_array('branch', $productsType))) unset($fields['branch']);// If products's type are normal, unset branch field. + if(isset($this->config->bizVersion)) list($fields, $bugs) = $this->loadModel('workflowfield')->appendDataFromFlow($fields, $bugs); $this->post->set('fields', $fields); $this->post->set('rows', $bugs); diff --git a/module/bug/css/browse.css b/module/bug/css/browse.css index c1098009a6..a69a925a74 100644 --- a/module/bug/css/browse.css +++ b/module/bug/css/browse.css @@ -1,8 +1,8 @@ .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;} -.confirm0 {color:gray; font-size:9px} -.confirm1 {color:green; font-size:9px} +.confirm0 {color:gray;} +.confirm1 {color:green;} td.delayed{color:#fff; background: #e84e0f!important;} .datatable-wrapper .table-datatable .datatable-row td {height:37px;} diff --git a/module/bug/css/create.css b/module/bug/css/create.css index f1e616083b..f006a70179 100644 --- a/module/bug/css/create.css +++ b/module/bug/css/create.css @@ -38,6 +38,7 @@ html[lang='en'] #deadlineTd .input-group-addon{padding: 5px 18px} .title-group #severity + .chosen-container > .chosen-single {border-radius: 0!important;} .title-group #pri + .chosen-container > .chosen-single {border-top-left-radius: 0!important; border-bottom-left-radius: 0!important;} .title-group .has-icon-right{min-width:700px} +#mainContent .center-block{padding-bottom:40px;} #typeBox {width:180px;} #osBox {width:190px;} diff --git a/module/bug/css/edit.css b/module/bug/css/edit.css index ddb55edfd8..581c88c64e 100644 --- a/module/bug/css/edit.css +++ b/module/bug/css/edit.css @@ -4,6 +4,3 @@ .col-side .chosen-container[id^="resolvedBuild"] {width: 172px!important} .chosen-choices li.search-choice{word-break: break-all;} #linkBugBox > li {margin-left:-56px} - -.thWidth{width:100px !important;} -html[lang^='zh-'] .thWidth{width:80px !important;} diff --git a/module/bug/css/edit.en.css b/module/bug/css/edit.en.css new file mode 100644 index 0000000000..b0e274a3db --- /dev/null +++ b/module/bug/css/edit.en.css @@ -0,0 +1 @@ +.thWidth{width:100px !important;} diff --git a/module/bug/css/edit.zh-cn.css b/module/bug/css/edit.zh-cn.css new file mode 100644 index 0000000000..585844a6f4 --- /dev/null +++ b/module/bug/css/edit.zh-cn.css @@ -0,0 +1 @@ +.thWidth{width:80px !important;} diff --git a/module/bug/css/edit.zh-tw.css b/module/bug/css/edit.zh-tw.css new file mode 100644 index 0000000000..585844a6f4 --- /dev/null +++ b/module/bug/css/edit.zh-tw.css @@ -0,0 +1 @@ +.thWidth{width:80px !important;} diff --git a/module/bug/css/resolve.css b/module/bug/css/resolve.css index eafaa6152e..097655b0a0 100644 --- a/module/bug/css/resolve.css +++ b/module/bug/css/resolve.css @@ -1,4 +1 @@ .chosen-container[id^="buildProject"] {max-width: 160px; border-radius: 0} - -.thWidth{width:130px !important;} -html[lang^='zh-'] .thWidth{width:100px !important;} diff --git a/module/bug/css/resolve.en.css b/module/bug/css/resolve.en.css new file mode 100644 index 0000000000..82442a3745 --- /dev/null +++ b/module/bug/css/resolve.en.css @@ -0,0 +1 @@ +.thWidth{width:130px !important;} diff --git a/module/bug/css/resolve.zh-cn.css b/module/bug/css/resolve.zh-cn.css new file mode 100644 index 0000000000..b0e274a3db --- /dev/null +++ b/module/bug/css/resolve.zh-cn.css @@ -0,0 +1 @@ +.thWidth{width:100px !important;} diff --git a/module/bug/css/resolve.zh-tw.css b/module/bug/css/resolve.zh-tw.css new file mode 100644 index 0000000000..b0e274a3db --- /dev/null +++ b/module/bug/css/resolve.zh-tw.css @@ -0,0 +1 @@ +.thWidth{width:100px !important;} diff --git a/module/bug/css/view.css b/module/bug/css/view.css index 065bf82cc4..f426ccc058 100644 --- a/module/bug/css/view.css +++ b/module/bug/css/view.css @@ -3,8 +3,3 @@ .table-data tr > td{word-break: break-all; word-wrap: break-word;} .side-col .cell{padding:0px;} .tab-pane table {border: 1px solid #ddd; border-top: none;} - -#legendBasicInfo .thWidth{width:110px !important;} -#legendLife .thWidth{width:100px !important;} -html[lang^='zh-'] #legendBasicInfo .thWidth{width:70px !important;} -html[lang^='zh-'] #legendLife .thWidth{width:90px !important;} diff --git a/module/bug/css/view.en.css b/module/bug/css/view.en.css new file mode 100644 index 0000000000..a12586a55b --- /dev/null +++ b/module/bug/css/view.en.css @@ -0,0 +1,2 @@ +#legendBasicInfo .thWidth{width:110px !important;} +#legendLife .thWidth{width:100px !important;} diff --git a/module/bug/css/view.zh-cn.css b/module/bug/css/view.zh-cn.css new file mode 100644 index 0000000000..ae536dd36e --- /dev/null +++ b/module/bug/css/view.zh-cn.css @@ -0,0 +1,2 @@ +#legendBasicInfo .thWidth{width:70px !important;} +#legendLife .thWidth{width:90px !important;} diff --git a/module/bug/css/view.zh-tw.css b/module/bug/css/view.zh-tw.css new file mode 100644 index 0000000000..ae536dd36e --- /dev/null +++ b/module/bug/css/view.zh-tw.css @@ -0,0 +1,2 @@ +#legendBasicInfo .thWidth{width:70px !important;} +#legendLife .thWidth{width:90px !important;} diff --git a/module/bug/lang/en.php b/module/bug/lang/en.php index a5039d2a7c..5ea2864591 100644 --- a/module/bug/lang/en.php +++ b/module/bug/lang/en.php @@ -19,6 +19,8 @@ $lang->bug->module = 'Module'; $lang->bug->moduleAB = 'Module'; $lang->bug->project = $lang->projectCommon; $lang->bug->story = 'Story'; +$lang->bug->storyVersion = 'Story Version'; +$lang->bug->color = 'Color'; $lang->bug->task = 'Task'; $lang->bug->title = 'Title'; $lang->bug->severity = 'Severity'; @@ -65,6 +67,8 @@ $lang->bug->linkBug = 'Linked Bugs'; $lang->bug->linkBugs = 'Link Bug'; $lang->bug->unlinkBug = 'Unlink'; $lang->bug->case = 'Cases'; +$lang->bug->caseVersion = 'Case Version'; +$lang->bug->testtask = 'Request'; $lang->bug->files = 'Files'; $lang->bug->keywords = 'Tags'; $lang->bug->lastEditedByAB = 'EditedBy'; @@ -74,7 +78,7 @@ $lang->bug->fromCase = 'From Case'; $lang->bug->toCase = 'To Case'; $lang->bug->colorTag = 'Color'; -/* 方法列表。*/ +/* Method list. */ $lang->bug->index = 'Bug Home'; $lang->bug->create = 'Report Bug'; $lang->bug->batchCreate = 'Batch Report'; @@ -110,7 +114,7 @@ $lang->bug->confirmStoryChange = 'Confirm Story Change'; $lang->bug->copy = 'Copy'; $lang->bug->search = 'Search'; -/* 查询条件列表。*/ +/* Query condition list. */ $lang->bug->assignToMe = 'AssignedToMe'; $lang->bug->openedByMe = 'ReportedByMe'; $lang->bug->resolvedByMe = 'ResolvedByMe'; @@ -143,7 +147,7 @@ $lang->bug->noBug = 'No bugs yet.'; $lang->bug->noModule = '
    You have no modules.
    Manage now
    '; $lang->bug->delayWarning = " Delay %s days "; -/* 页面标签。*/ +/* Page tags. */ $lang->bug->lblAssignedTo = 'AssignTo'; $lang->bug->lblMailto = 'Mailto'; $lang->bug->lblLastEdited = 'EditedBy'; @@ -152,7 +156,7 @@ $lang->bug->allUsers = 'Load All Users'; $lang->bug->allBuilds = 'All Builds'; $lang->bug->createBuild = 'New'; -/* legend列表。*/ +/* Legend list。*/ $lang->bug->legendBasicInfo = 'Basic Info'; $lang->bug->legendAttatch = 'Files'; $lang->bug->legendPrjStoryTask = $lang->projectCommon . '/Story/Task'; @@ -164,22 +168,22 @@ $lang->bug->legendLife = 'Bug Life'; $lang->bug->legendMisc = 'Misc.'; $lang->bug->legendRelated = 'Related Info'; -/* 功能按钮。*/ +/* Button. */ $lang->bug->buttonConfirm = 'Confirm'; -/* 交互提示。*/ +/* Interactive prompt. */ $lang->bug->summary = "Total %s bugs on this page, and %s Active."; $lang->bug->confirmChangeProduct = "Any change to {$lang->productCommon} will cause linked {$lang->projectCommon}s, stories and tasks change. Do you want to do this?"; $lang->bug->confirmDelete = 'Do you want to delete this bug?'; $lang->bug->remindTask = 'This bug has been converted to a task. Do you want to update the status of Task(ID %s)?'; $lang->bug->skipClose = 'Bug %s is active. You cannot close it.'; -/* 模板。*/ +/* Template. */ $lang->bug->tplStep = "

    [Steps]


    "; $lang->bug->tplResult = "

    [Results]


    "; $lang->bug->tplExpect = "

    [Expectations]


    "; -/* 各个字段取值列表。*/ +/* Value list for each field. */ $lang->bug->severityList[1] = '1'; $lang->bug->severityList[2] = '2'; $lang->bug->severityList[3] = '3'; @@ -269,7 +273,7 @@ $lang->bug->resolutionList['postponed'] = 'Postponed'; $lang->bug->resolutionList['willnotfix'] = "Won't Fix"; $lang->bug->resolutionList['tostory'] = 'Convert to Story'; -/* 统计报表。*/ +/* Statistical statement. */ $lang->bug->report = new stdclass(); $lang->bug->report->common = 'Report'; $lang->bug->report->select = 'Select Report Type'; @@ -365,7 +369,7 @@ $lang->bug->report->bugsPerAssignedTo->graph->xAxisName = 'AssignTo'; $lang->bug->report->bugLiveDays->graph->xAxisName = 'Handling Time'; $lang->bug->report->bugHistories->graph->xAxisName = 'Handling Steps'; -/* 操作记录。*/ +/* Operating record. */ $lang->bug->action = new stdclass(); $lang->bug->action->resolved = array('main' => '$date, resolved by $actor and the resolution is $extra $appendLink.', 'extra' => 'resolutionList'); $lang->bug->action->tostory = array('main' => '$date, converted by $actor to Story with ID $extra.'); diff --git a/module/bug/lang/zh-cn.php b/module/bug/lang/zh-cn.php index 43768c566f..ad014b3832 100644 --- a/module/bug/lang/zh-cn.php +++ b/module/bug/lang/zh-cn.php @@ -19,6 +19,8 @@ $lang->bug->module = '所属模块'; $lang->bug->moduleAB = '模块'; $lang->bug->project = '所属' . $lang->projectCommon; $lang->bug->story = '相关需求'; +$lang->bug->storyVersion = '需求版本'; +$lang->bug->color = '标题颜色'; $lang->bug->task = '相关任务'; $lang->bug->title = 'Bug标题'; $lang->bug->severity = '严重程度'; @@ -30,7 +32,7 @@ $lang->bug->browser = '浏览器'; $lang->bug->steps = '重现步骤'; $lang->bug->status = 'Bug状态'; $lang->bug->statusAB = '状态'; -$lang->bug->subStatus = 'Bug子状态'; +$lang->bug->subStatus = '子状态'; $lang->bug->activatedCount = '激活次数'; $lang->bug->activatedCountAB = '激活次数'; $lang->bug->activatedDate = '激活日期'; @@ -65,6 +67,8 @@ $lang->bug->linkBug = '相关Bug'; $lang->bug->linkBugs = '关联相关Bug'; $lang->bug->unlinkBug = '移除相关Bug'; $lang->bug->case = '相关用例'; +$lang->bug->caseVersion = '用例版本'; +$lang->bug->testtask = '测试单'; $lang->bug->files = '附件'; $lang->bug->keywords = '关键词'; $lang->bug->lastEditedByAB = '修改者'; diff --git a/module/bug/lang/zh-tw.php b/module/bug/lang/zh-tw.php index 640be62e9c..d74dc3af9a 100644 --- a/module/bug/lang/zh-tw.php +++ b/module/bug/lang/zh-tw.php @@ -19,6 +19,8 @@ $lang->bug->module = '所屬模組'; $lang->bug->moduleAB = '模組'; $lang->bug->project = '所屬' . $lang->projectCommon; $lang->bug->story = '相關需求'; +$lang->bug->storyVersion = '需求版本'; +$lang->bug->color = '標題顏色'; $lang->bug->task = '相關任務'; $lang->bug->title = 'Bug標題'; $lang->bug->severity = '嚴重程度'; @@ -30,6 +32,7 @@ $lang->bug->browser = '瀏覽器'; $lang->bug->steps = '重現步驟'; $lang->bug->status = 'Bug狀態'; $lang->bug->statusAB = '狀態'; +$lang->bug->subStatus = '子狀態'; $lang->bug->activatedCount = '激活次數'; $lang->bug->activatedCountAB = '激活次數'; $lang->bug->activatedDate = '激活日期'; @@ -64,6 +67,8 @@ $lang->bug->linkBug = '相關Bug'; $lang->bug->linkBugs = '關聯相關Bug'; $lang->bug->unlinkBug = '移除相關Bug'; $lang->bug->case = '相關用例'; +$lang->bug->caseVersion = '用例版本'; +$lang->bug->testtask = '測試單'; $lang->bug->files = '附件'; $lang->bug->keywords = '關鍵詞'; $lang->bug->lastEditedByAB = '修改者'; diff --git a/module/bug/view/activate.html.php b/module/bug/view/activate.html.php index 51b56bc2f6..d3af8dcb37 100644 --- a/module/bug/view/activate.html.php +++ b/module/bug/view/activate.html.php @@ -27,14 +27,18 @@
    - + + + + + + printExtendFields($bug, 'table', 'columns=1');?> - printExtendFields($bug, 'table', 'columns=2');?> diff --git a/module/bug/view/assignto.html.php b/module/bug/view/assignto.html.php index 47ee363e0f..3953004a00 100644 --- a/module/bug/view/assignto.html.php +++ b/module/bug/view/assignto.html.php @@ -34,11 +34,15 @@ js::set('page', 'assignedto'); + + + + + printExtendFields($bug, 'table', 'columns=1');?> - printExtendFields($bug, 'table', 'columns=2');?> diff --git a/module/bug/view/close.html.php b/module/bug/view/close.html.php index 18d796dd68..6ceb3f22a4 100644 --- a/module/bug/view/close.html.php +++ b/module/bug/view/close.html.php @@ -26,6 +26,10 @@
    bug->assignedTo;?>bug->assignedTo;?> resolvedBy, "class='form-control chosen'");?>
    bug->status;?>
    bug->openedBuild;?> openedBuild, 'size=4 multiple=multiple class="form-control chosen"');?>
    comment;?> bug->assignBug;?> assignedTo, "class='form-control chosen'");?>
    bug->status;?>status);?>
    bug->mailto;?> mailto), 'class="form-control chosen" multiple');?>
    comment;?>
    + + + + printExtendFields($bug, 'table', 'columns=1');?> diff --git a/module/bug/view/confirmbug.html.php b/module/bug/view/confirmbug.html.php index ce927a4cda..e9b31fca17 100755 --- a/module/bug/view/confirmbug.html.php +++ b/module/bug/view/confirmbug.html.php @@ -45,11 +45,16 @@ js::set('page', 'confirmbug'); + + + + + + printExtendFields($bug, 'table', 'columns=1');?> - printExtendFields($bug, 'table', 'columns=2');?> diff --git a/module/bug/view/create.html.php b/module/bug/view/create.html.php index 4774860a1d..1ab8b9d20e 100644 --- a/module/bug/view/create.html.php +++ b/module/bug/view/create.html.php @@ -288,7 +288,11 @@ js::set('flow', $config->global->flow); - printExtendFields('', 'table', 'columns=2');?> + + + + + printExtendFields('', 'table', 'columns=1');?> diff --git a/module/bug/view/edit.html.php b/module/bug/view/edit.html.php index 0bbaf8cf4e..93e71d744d 100644 --- a/module/bug/view/edit.html.php +++ b/module/bug/view/edit.html.php @@ -213,7 +213,7 @@ js::set('oldResolvedBuild' , $bug->resolvedBuild); - + diff --git a/module/bug/view/resolve.html.php b/module/bug/view/resolve.html.php index d7ea3129ff..f2c2523579 100644 --- a/module/bug/view/resolve.html.php +++ b/module/bug/view/resolve.html.php @@ -73,6 +73,10 @@ js::set('productID' , $bug->product); + + + + printExtendFields($bug, 'table', 'columns=1');?> diff --git a/module/bug/view/view.html.php b/module/bug/view/view.html.php index a4326a40e8..1794eefb73 100644 --- a/module/bug/view/view.html.php +++ b/module/bug/view/view.html.php @@ -199,7 +199,7 @@ - + @@ -224,7 +224,7 @@ - +
    bug->status;?>
    comment;?>bug->priList, $bug->pri, "class='form-control chosen'");?>
    bug->status;?>status);?>
    bug->mailto;?> mailto), 'class="form-control chosen" multiple');?>
    comment;?>
    bug->status;?>
    bug->files;?> fetch('file', 'buildform', 'fileCount=1&percent=0.85');?>
    bug->openedBy;?>openedBy];?>openedBy);?>
    bug->openedBuild;?>bug->assignedTo;?>
    bug->status;?>
    bug->files;?>
    bug->lblAssignedTo;?>assignedTo) echo $users[$bug->assignedTo] . $lang->at . $bug->assignedDate;?>assignedTo) echo zget($users, $bug->assignedTo) . $lang->at . $bug->assignedDate;?>
    bug->deadline;?>
    bug->mailto;?>mailto)); foreach($mailto as $account) echo ' ' . $users[$account]; ?>mailto)); foreach($mailto as $account) echo ' ' . zget($users, $account); ?>
    @@ -376,7 +376,7 @@
    - printExtendFields($bug, 'div', "position=right&divCell=true");?> + printExtendFields($bug, 'div', "position=right&mode=value");?> diff --git a/module/build/view/linkbug.html.php b/module/build/view/linkbug.html.php index fda90de279..c6c24e9dc8 100644 --- a/module/build/view/linkbug.html.php +++ b/module/build/view/linkbug.html.php @@ -45,8 +45,8 @@ bug->priList, $bug->pri, $bug->pri)?> createLink('bug', 'view', "bugID=$bug->id", '', true), $bug->title, '', "data-toggle='modal' data-type='iframe' data-width='90%'");?> - openedBy];?> - status == 'resolved' or $bug->status == 'closed') ? $users[$bug->resolvedBy] : html::select("resolvedBy[{$bug->id}]", $users, $this->app->user->account, "class='form-control chosen'");?> + openedBy);?> + status == 'resolved' or $bug->status == 'closed') ? zget($users, $bug->resolvedBy) : html::select("resolvedBy[{$bug->id}]", $users, $this->app->user->account, "class='form-control chosen'");?> processStatus('bug', $bug);?> diff --git a/module/build/view/linkstory.html.php b/module/build/view/linkstory.html.php index 308efa3590..c5d5d0d988 100644 --- a/module/build/view/linkstory.html.php +++ b/module/build/view/linkstory.html.php @@ -47,8 +47,8 @@ story->priList, $story->pri, $story->pri)?> createLink('story', 'view', "storyID=$story->id", '', true), $story->title, '', "data-toggle='modal' data-type='iframe' data-width='90%'");?> - openedBy];?> - assignedTo];?> + openedBy);?> + assignedTo);?> estimate;?> diff --git a/module/build/view/view.html.php b/module/build/view/view.html.php index cd883be5ff..f968eadafd 100644 --- a/module/build/view/view.html.php +++ b/module/build/view/view.html.php @@ -131,7 +131,7 @@ tbody tr td:first-child input{display:none;} story->priList, $story->pri, $story->pri);?> title, '', "class='iframe' data-width='1000'");?> - openedBy];?> + openedBy);?> estimate;?> @@ -209,9 +209,9 @@ tbody tr td:first-child input{display:none;} processStatus('bug', $bug);?> - openedBy];?> + openedBy);?> openedDate, 5, 11)?> - resolvedBy];?> + resolvedBy);?> resolvedDate, 5, 11)?> processStatus('bug', $bug);?> - openedBy];?> + openedBy);?> openedDate, 5, 11)?> - resolvedBy];?> + resolvedBy);?> resolvedDate, 5, 11)?> @@ -321,7 +321,7 @@ tbody tr td:first-child input{display:none;} build->builder;?> - builder];?> + builder);?> build->date;?> diff --git a/module/common/lang/de.php b/module/common/lang/de.php index 2c10f0e03e..4419ee0369 100644 --- a/module/common/lang/de.php +++ b/module/common/lang/de.php @@ -21,6 +21,7 @@ $lang->percent = '%'; $lang->dash = '-'; $lang->zentaoPMS = 'ZenTao'; +$lang->logoImg = 'zt-logo-en.png'; $lang->welcome = "%s PMS"; $lang->logout = 'Abmelden'; $lang->login = 'Anmelden'; @@ -477,7 +478,7 @@ $lang->error = new stdclass(); $lang->error->companyNotFound = "The domain %s cannot be found!"; $lang->error->length = array("『%s』Length Error. It should be『%s』", "『%s』length should be <=『%s』and >『%s』."); $lang->error->reg = "『%s』Format Error. It should be『%s』."; -$lang->error->unique = "『%s』『%s』existed. Please go to Admin->Recycle to restore it, if you are sure it is deleted."; +$lang->error->unique = "『%s』『%s』existed. Please go to Admin->Data->Recycle to restore it, if you are sure it is deleted."; $lang->error->gt = "『%s』should be >『%s』."; $lang->error->ge = "『%s』should be >=『%s』."; $lang->error->notempty = "『%s』should not be blank."; diff --git a/module/common/lang/en.php b/module/common/lang/en.php index 49952cdf56..2546b436fc 100644 --- a/module/common/lang/en.php +++ b/module/common/lang/en.php @@ -21,6 +21,7 @@ $lang->percent = '%'; $lang->dash = '-'; $lang->zentaoPMS = 'ZenTao'; +$lang->logoImg = 'zt-logo-en.png'; $lang->welcome = "%s ALM"; $lang->logout = 'Logout'; $lang->login = 'Login'; @@ -178,7 +179,7 @@ $lang->index->menu = new stdclass(); $lang->index->menu->product = "{$lang->productCommon}|product|browse"; $lang->index->menu->project = "{$lang->projectCommon}|project|browse"; -/* my dashboard menu settings. */ +/* My dashboard menu settings. */ $lang->my = new stdclass(); $lang->my->menu = new stdclass(); @@ -477,7 +478,7 @@ $lang->error = new stdclass(); $lang->error->companyNotFound = "The domain %s cannot be found!"; $lang->error->length = array("『%s』length error. It should be『%s』", "『%s』length should be <=『%s』and >『%s』."); $lang->error->reg = "『%s』format error. It should be『%s』."; -$lang->error->unique = "『%s』『%s』exists. Go to Admin->Recycle Bin to restore it, if you are sure it is deleted."; +$lang->error->unique = "『%s』『%s』exists. Go to Admin->Data->Recycle Bin to restore it, if you are sure it is deleted."; $lang->error->gt = "『%s』should be >『%s』."; $lang->error->ge = "『%s』should be >=『%s』."; $lang->error->notempty = "『%s』should not be blank."; diff --git a/module/common/lang/zh-cn.php b/module/common/lang/zh-cn.php index 7a790c191b..96d560411b 100644 --- a/module/common/lang/zh-cn.php +++ b/module/common/lang/zh-cn.php @@ -21,6 +21,7 @@ $lang->percent = '%'; $lang->dash = '-'; $lang->zentaoPMS = '禅道'; +$lang->logoImg = 'zt-logo.png'; $lang->welcome = "%s项目管理系统"; $lang->logout = '退出'; $lang->login = '登录'; @@ -477,7 +478,7 @@ $lang->error = new stdclass(); $lang->error->companyNotFound = "您访问的域名 %s 没有对应的公司。"; $lang->error->length = array("『%s』长度错误,应当为『%s』", "『%s』长度应当不超过『%s』,且大于『%s』。"); $lang->error->reg = "『%s』不符合格式,应当为:『%s』。"; -$lang->error->unique = "『%s』已经有『%s』这条记录了。如果您确定该记录已删除,请到后台管理-回收站还原。"; +$lang->error->unique = "『%s』已经有『%s』这条记录了。如果您确定该记录已删除,请到后台-数据-回收站还原。"; $lang->error->gt = "『%s』应当大于『%s』。"; $lang->error->ge = "『%s』应当不小于『%s』。"; $lang->error->notempty = "『%s』不能为空。"; diff --git a/module/common/lang/zh-tw.php b/module/common/lang/zh-tw.php index b9b1a0be16..959f9ca859 100644 --- a/module/common/lang/zh-tw.php +++ b/module/common/lang/zh-tw.php @@ -21,6 +21,7 @@ $lang->percent = '%'; $lang->dash = '-'; $lang->zentaoPMS = '禪道'; +$lang->logoImg = 'zt-logo.png'; $lang->welcome = "%s項目管理系統"; $lang->logout = '退出'; $lang->login = '登錄'; @@ -477,7 +478,7 @@ $lang->error = new stdclass(); $lang->error->companyNotFound = "您訪問的域名 %s 沒有對應的公司。"; $lang->error->length = array("『%s』長度錯誤,應當為『%s』", "『%s』長度應當不超過『%s』,且大於『%s』。"); $lang->error->reg = "『%s』不符合格式,應當為:『%s』。"; -$lang->error->unique = "『%s』已經有『%s』這條記錄了。如果您確定該記錄已刪除,請到後台管理-資源回收筒還原。"; +$lang->error->unique = "『%s』已經有『%s』這條記錄了。如果您確定該記錄已刪除,請到後台-數據-資源回收筒還原。"; $lang->error->gt = "『%s』應當大於『%s』。"; $lang->error->ge = "『%s』應當不小於『%s』。"; $lang->error->notempty = "『%s』不能為空。"; diff --git a/module/common/model.php b/module/common/model.php index 3460942eb2..f4690ddb5e 100644 --- a/module/common/model.php +++ b/module/common/model.php @@ -553,6 +553,13 @@ class commonModel extends model $menu = customModel::getModuleMenu($moduleName); $isMobile = $app->viewType === 'mhtml'; + /* If this is not workflow then use rawModule and rawMethod to judge highlight. */ + if(!$app->isFlow) + { + $currentModule = $app->rawModule; + $currentMethod = $app->rawMethod; + } + /* The beginning of the menu. */ echo $isMobile ? '' : " EOD; $lang->install->ranzhi = new stdclass(); -$lang->install->ranzhi->name = 'ZDOO Collaborative System'; -$lang->install->ranzhi->logo = 'images/main/zdoo_org.png'; -$lang->install->ranzhi->url = 'http://www.zdoo.org'; -$lang->install->ranzhi->desc = <<install->ranzhi->name = 'ZDOO Collaborative System'; +$lang->install->ranzhi->width = 'col-md-6'; +$lang->install->ranzhi->logo = 'images/main/zdoo_org.png'; +$lang->install->ranzhi->url = 'http://www.zdoo.org'; +$lang->install->ranzhi->desc = <<
  • CRM: Customer Management and Order Tracking
  • OA: Approve, Announce, Trip, Leave and so on.
  • -
  • Project,Task and Document management
  • +
  • Projec t,Task and Document management
  • Money: Income, Expense, Transfer, Invest and Debt
  • EOD; + +$lang->install->ydisk = new stdclass(); +$lang->install->ydisk->name = 'Y Disk-Free NetDisk for Enterprises'; +$lang->install->ydisk->width = 'col-md-6'; +$lang->install->ydisk->logo = 'images/main/ydisk.png'; +$lang->install->ydisk->url = 'http://www.ydisk.cn'; +$lang->install->ydisk->desc = << +
  • Self-Hosted: deploy on your own machine
  • +
  • Storage: depend on your hard drive size
  • +
  • Transmission: as fast as your bandwidth allows
  • +
  • Secure: 12 permissions for any strict settings
  • + +EOD; + +$lang->install->meshiot = new stdclass(); +$lang->install->meshiot->name = 'MeshIoT'; +$lang->install->meshiot->width = 'col-md-6'; +$lang->install->meshiot->logo = 'images/main/meshiot.png'; +$lang->install->meshiot->url = 'https://www.meshiot.com'; +$lang->install->meshiot->desc = << +
  • Performance: one gateway can monitor 65,536 equipments
  • +
  • Accessibility: unique radio communication protocol covers 2,500m radius
  • +
  • Dimming System: 200+ sensors and monitors
  • +
  • Battery Available: no requirements to any equipment on your site
  • + +EOD; diff --git a/module/install/lang/zh-cn.php b/module/install/lang/zh-cn.php index 893a92576c..6dd25da825 100644 --- a/module/install/lang/zh-cn.php +++ b/module/install/lang/zh-cn.php @@ -82,7 +82,7 @@ $lang->install->iconvFail = '修改PHP配置文件,加载ICONV扩展。'; $lang->install->tmpRoot = '临时文件目录'; $lang->install->dataRoot = '上传文件目录'; $lang->install->session = 'Session存储目录'; -$lang->install->sessionFail = '修改PHP配置文件,设置session.save_path'; +$lang->install->sessionFail = '修改PHP配置文件,设置session.save_path。
    如果使用宝塔面板,可以到宝塔Web面板中“软件商店”,打开PHP设置,到“Session配置”项,选择files,点击保存。老版本需要修改php配置文件。'; $lang->install->mkdirWin = '

    需要创建目录%s。命令为:
    mkdir %s

    '; $lang->install->chmodWin = '需要修改目录 "%s" 的权限。'; $lang->install->mkdirLinux = '

    需要创建目录%s。
    命令为:
    mkdir -p %s

    '; @@ -172,14 +172,15 @@ $lang->install->joinZentao = <<您已经成功安装禅道管理系统%s,请及时删除install.php。

    友情提示:为了您及时获得禅道的最新动态,请在禅道社区(www.zentao.net)进行登记。

    EOT; -$lang->install->product = array('chanzhi', 'ranzhi', 'xuanxuan'); +$lang->install->product = array('chanzhi', 'ranzhi', 'xuanxuan', 'ydisk', 'meshiot'); -$lang->install->promotion = "为您推荐易软天创旗下其他产品:"; -$lang->install->chanzhi = new stdclass(); -$lang->install->chanzhi->name = '蝉知企业门户系统'; -$lang->install->chanzhi->logo = 'images/main/chanzhi.png'; -$lang->install->chanzhi->url = 'http://www.chanzhi.org'; -$lang->install->chanzhi->desc = <<install->promotion = "为您推荐易软天创旗下其他产品:"; +$lang->install->chanzhi = new stdclass(); +$lang->install->chanzhi->name = '蝉知企业门户系统'; +$lang->install->chanzhi->width = 'col-md-4'; +$lang->install->chanzhi->logo = 'images/main/chanzhi.png'; +$lang->install->chanzhi->url = 'http://www.chanzhi.org'; +$lang->install->chanzhi->desc = <<
  • 专业的企业营销门户系统
  • 功能丰富,操作简洁方便
  • @@ -189,10 +190,11 @@ $lang->install->chanzhi->desc = <<install->ranzhi = new stdclass(); -$lang->install->ranzhi->name = '然之协同管理系统'; -$lang->install->ranzhi->logo = 'images/main/ranzhi.png'; -$lang->install->ranzhi->url = 'http://www.ranzhi.org'; -$lang->install->ranzhi->desc = <<install->ranzhi->name = '然之协同管理系统'; +$lang->install->ranzhi->width = 'col-md-4'; +$lang->install->ranzhi->logo = 'images/main/ranzhi.png'; +$lang->install->ranzhi->url = 'http://www.ranzhi.org'; +$lang->install->ranzhi->desc = <<
  • 客户管理,订单跟踪
  • 项目任务,公告文档
  • @@ -202,8 +204,10 @@ $lang->install->ranzhi->desc = <<install->zdoo = new stdclass(); -$lang->install->zdoo->name = '可深度定制的云端一体化协作平台'; -$lang->install->zdoo->desc = <<install->zdoo->name = '可深度定制的云端一体化协作平台'; +$lang->install->zdoo->width = 'col-md-4'; +$lang->install->zdoo->url = 'http://www.zdoo.com'; +$lang->install->zdoo->desc = <<
  • 安全、稳定、高效
  • 以容器为交付单位
  • @@ -213,10 +217,11 @@ $lang->install->zdoo->desc = <<install->xuanxuan = new stdclass(); -$lang->install->xuanxuan->name = '喧喧即时聊天软件'; -$lang->install->xuanxuan->logo = 'images/main/xuanxuan.png'; -$lang->install->xuanxuan->url = 'http://www.xuan.im'; -$lang->install->xuanxuan->desc = <<install->xuanxuan->name = '喧喧即时聊天软件'; +$lang->install->xuanxuan->width = 'col-md-4'; +$lang->install->xuanxuan->logo = 'images/main/xuanxuan.png'; +$lang->install->xuanxuan->url = 'http://www.xuan.im'; +$lang->install->xuanxuan->desc = <<
  • 轻:轻量级架构,容易部署
  • 跨:真正完整跨平台解决方案
  • @@ -224,3 +229,31 @@ $lang->install->xuanxuan->desc = <<开:开放架构,方便二开集成 EOD; + +$lang->install->ydisk = new stdclass(); +$lang->install->ydisk->name = '悦库免费企业网盘'; +$lang->install->ydisk->width = 'col-md-6'; +$lang->install->ydisk->logo = 'images/main/ydisk.png'; +$lang->install->ydisk->url = 'http://www.ydisk.cn'; +$lang->install->ydisk->desc = << +
  • 绝对私有,只部署在自己的机器上。
  • +
  • 海量存储,只取决于您的硬盘大小。
  • +
  • 极限传输,只取决于您的网络带宽。
  • +
  • 极度安全,十二种权限组合。
  • + +EOD; + +$lang->install->meshiot = new stdclass(); +$lang->install->meshiot->name = '易天物联'; +$lang->install->meshiot->width = 'col-md-6'; +$lang->install->meshiot->logo = 'images/main/meshiot.png'; +$lang->install->meshiot->url = 'https://www.meshiot.com'; +$lang->install->meshiot->desc = << +
  • 超性能网关,一个就可管65536个设备。
  • +
  • 独创无线电通讯协议,2500米穿墙无障碍。
  • +
  • 200余款传感器控制器,独创调光系统。
  • +
  • 可配电池,对既有场地设备无任何要求。
  • + +EOD; diff --git a/module/install/view/index.html.php b/module/install/view/index.html.php index ce3a8d3c3a..c751b11f68 100644 --- a/module/install/view/index.html.php +++ b/module/install/view/index.html.php @@ -42,8 +42,9 @@
    install->promotion?>
    + install->product);?> install->product as $product):?> -
    +
    diff --git a/module/misc/view/about.html.php b/module/misc/view/about.html.php index 2d5df8639f..829d6a8d7a 100644 --- a/module/misc/view/about.html.php +++ b/module/misc/view/about.html.php @@ -8,7 +8,7 @@ @@ -23,4 +23,4 @@ - \ No newline at end of file + diff --git a/module/my/css/changepassword.css b/module/my/css/changepassword.css deleted file mode 100644 index 142e74674d..0000000000 --- a/module/my/css/changepassword.css +++ /dev/null @@ -1,2 +0,0 @@ -.thWidth{width:130px !important;} -html[lang^='zh-'] .thWidth{width:100px !important;} diff --git a/module/my/css/changepassword.en.css b/module/my/css/changepassword.en.css new file mode 100644 index 0000000000..82442a3745 --- /dev/null +++ b/module/my/css/changepassword.en.css @@ -0,0 +1 @@ +.thWidth{width:130px !important;} diff --git a/module/my/css/changepassword.zh-cn.css b/module/my/css/changepassword.zh-cn.css new file mode 100644 index 0000000000..b0e274a3db --- /dev/null +++ b/module/my/css/changepassword.zh-cn.css @@ -0,0 +1 @@ +.thWidth{width:100px !important;} diff --git a/module/my/css/changepassword.zh-tw.css b/module/my/css/changepassword.zh-tw.css new file mode 100644 index 0000000000..b0e274a3db --- /dev/null +++ b/module/my/css/changepassword.zh-tw.css @@ -0,0 +1 @@ +.thWidth{width:100px !important;} diff --git a/module/my/view/editprofile.html.php b/module/my/view/editprofile.html.php index c6fb2eb0a0..3b34754ead 100644 --- a/module/my/view/editprofile.html.php +++ b/module/my/view/editprofile.html.php @@ -44,7 +44,7 @@ - + diff --git a/module/my/view/story.html.php b/module/my/view/story.html.php index 63c4ee9d4c..6fa9711ef2 100644 --- a/module/my/view/story.html.php +++ b/module/my/view/story.html.php @@ -73,7 +73,7 @@ - + diff --git a/module/product/control.php b/module/product/control.php index 09a734b5b9..e8fda11f42 100644 --- a/module/product/control.php +++ b/module/product/control.php @@ -739,6 +739,7 @@ class product extends control if(strpos(",$checkedItem,", ",{$product->id},") === false) unset($productStats[$i]); } } + if(isset($this->config->bizVersion)) list($fields, $productStats) = $this->loadModel('workflowfield')->appendDataFromFlow($fields, $productStats); $this->post->set('fields', $fields); $this->post->set('rows', $productStats); diff --git a/module/product/lang/zh-cn.php b/module/product/lang/zh-cn.php index 68476e9fa0..42110a75cc 100644 --- a/module/product/lang/zh-cn.php +++ b/module/product/lang/zh-cn.php @@ -73,6 +73,7 @@ $lang->product->order = '排序'; $lang->product->type = "{$lang->productCommon}类型"; $lang->product->typeAB = "类型"; $lang->product->status = '状态'; +$lang->product->subStatus = '子状态'; $lang->product->desc = "{$lang->productCommon}描述"; $lang->product->manager = '负责人'; $lang->product->PO = "{$lang->productCommon}负责人"; diff --git a/module/product/lang/zh-tw.php b/module/product/lang/zh-tw.php index 8c3b75d5b5..05a0972a90 100644 --- a/module/product/lang/zh-tw.php +++ b/module/product/lang/zh-tw.php @@ -65,31 +65,34 @@ $lang->product->confirmDelete = " 您確定刪除該{$lang->productCommon}嗎 $lang->product->errorNoProduct = "還沒有創建{$lang->productCommon}!"; $lang->product->accessDenied = "您無權訪問該{$lang->productCommon}"; -$lang->product->id = '編號'; -$lang->product->name = "{$lang->productCommon}名稱"; -$lang->product->code = "{$lang->productCommon}代號"; -$lang->product->line = "{$lang->productCommon}綫"; -$lang->product->order = '排序'; -$lang->product->type = "{$lang->productCommon}類型"; -$lang->product->typeAB = "類型"; -$lang->product->status = '狀態'; -$lang->product->desc = "{$lang->productCommon}描述"; -$lang->product->manager = '負責人'; -$lang->product->PO = "{$lang->productCommon}負責人"; -$lang->product->QD = '測試負責人'; -$lang->product->RD = '發佈負責人'; -$lang->product->acl = '訪問控制'; -$lang->product->whitelist = '分組白名單'; -$lang->product->branch = '所屬%s'; -$lang->product->qa = '測試'; -$lang->product->release = '發佈'; -$lang->product->allRelease = '所有發佈'; -$lang->product->maintain = '維護中'; -$lang->product->latestDynamic = '最新動態'; -$lang->product->plan = '計劃'; -$lang->product->iteration = '版本迭代'; -$lang->product->iterationInfo = '迭代 %s 次'; -$lang->product->iterationView = '查看詳情'; +$lang->product->id = '編號'; +$lang->product->name = "{$lang->productCommon}名稱"; +$lang->product->code = "{$lang->productCommon}代號"; +$lang->product->line = "{$lang->productCommon}綫"; +$lang->product->order = '排序'; +$lang->product->type = "{$lang->productCommon}類型"; +$lang->product->typeAB = "類型"; +$lang->product->status = '狀態'; +$lang->product->subStatus = '子狀態'; +$lang->product->desc = "{$lang->productCommon}描述"; +$lang->product->manager = '負責人'; +$lang->product->PO = "{$lang->productCommon}負責人"; +$lang->product->QD = '測試負責人'; +$lang->product->RD = '發佈負責人'; +$lang->product->acl = '訪問控制'; +$lang->product->whitelist = '分組白名單'; +$lang->product->branch = '所屬%s'; +$lang->product->qa = '測試'; +$lang->product->release = '發佈'; +$lang->product->allRelease = '所有發佈'; +$lang->product->maintain = '維護中'; +$lang->product->latestDynamic = '最新動態'; +$lang->product->plan = '計劃'; +$lang->product->iteration = '版本迭代'; +$lang->product->iterationInfo = '迭代 %s 次'; +$lang->product->iterationView = '查看詳情'; +$lang->product->createdBy = '由誰創建'; +$lang->product->createdDate = '創建日期'; $lang->product->searchStory = '搜索'; $lang->product->assignedToMe = '指給我'; diff --git a/module/product/model.php b/module/product/model.php index e514e67dfc..2206bcbb79 100644 --- a/module/product/model.php +++ b/module/product/model.php @@ -636,7 +636,7 @@ class productModel extends model { if(($plan->end != '0000-00-00' and strtotime($plan->end) - time() <= 0) or $plan->end == '2030-01-01') continue; $year = substr($plan->end, 0, 4); - $roadmap[$year][$plan->branch][] = $plan; + $roadmap[$year][$plan->branch][$plan->end] = $plan; $total++; } @@ -650,7 +650,7 @@ class productModel extends model foreach($releases as $release) { $year = substr($release->date, 0, 4); - $roadmap[$year][$release->branch][] = $release; + $roadmap[$year][$release->branch][$release->date] = $release; $total++; if($count > 0 and $total >= $count) break; @@ -664,6 +664,7 @@ class productModel extends model { foreach($branchRoadmaps as $branch => $roadmaps) { + krsort($roadmaps); $totalData = count($roadmaps); $rows = ceil($totalData / 8); $maxPerRow = ceil($totalData / $rows); diff --git a/module/product/view/build.html.php b/module/product/view/build.html.php index fbbcf67135..1c74e09239 100644 --- a/module/product/view/build.html.php +++ b/module/product/view/build.html.php @@ -51,7 +51,7 @@ - + - - + + diff --git a/module/task/control.php b/module/task/control.php index 441e672237..7438014f28 100644 --- a/module/task/control.php +++ b/module/task/control.php @@ -1490,6 +1490,7 @@ class task extends control } } } + if(isset($this->config->bizVersion)) list($fields, $tasks) = $this->loadModel('workflowfield')->appendDataFromFlow($fields, $tasks); $this->post->set('fields', $fields); $this->post->set('rows', $tasks); diff --git a/module/task/css/activate.css b/module/task/css/activate.css deleted file mode 100644 index 40079b4d82..0000000000 --- a/module/task/css/activate.css +++ /dev/null @@ -1,2 +0,0 @@ -.thWidth{width:90px !important;} -html[lang^='zh-'] .thWidth{width:70px !important;} diff --git a/module/task/css/activate.en.css b/module/task/css/activate.en.css new file mode 100644 index 0000000000..6e60376bc6 --- /dev/null +++ b/module/task/css/activate.en.css @@ -0,0 +1 @@ +.thWidth{width:90px !important;} diff --git a/module/task/css/activate.zh-cn.css b/module/task/css/activate.zh-cn.css new file mode 100644 index 0000000000..b9b2a977fd --- /dev/null +++ b/module/task/css/activate.zh-cn.css @@ -0,0 +1 @@ +.thWidth{width:70px !important;} diff --git a/module/task/css/activate.zh-tw.css b/module/task/css/activate.zh-tw.css new file mode 100644 index 0000000000..b9b2a977fd --- /dev/null +++ b/module/task/css/activate.zh-tw.css @@ -0,0 +1 @@ +.thWidth{width:70px !important;} diff --git a/module/task/css/edit.css b/module/task/css/edit.css deleted file mode 100644 index ad2424880d..0000000000 --- a/module/task/css/edit.css +++ /dev/null @@ -1,4 +0,0 @@ -.thWidth{width:85px !important;} -.lifeThWidth{width:120px !important;} -html[lang^='zh-'] .thWidth{width:70px !important;} -html[lang^='zh-'] .lifeThWidth{width:70px !important;} diff --git a/module/task/css/edit.en.css b/module/task/css/edit.en.css new file mode 100644 index 0000000000..431f63ee3f --- /dev/null +++ b/module/task/css/edit.en.css @@ -0,0 +1,2 @@ +.thWidth{width:85px !important;} +.lifeThWidth{width:120px !important;} diff --git a/module/task/css/edit.zh-cn.css b/module/task/css/edit.zh-cn.css new file mode 100644 index 0000000000..0845bfd2fc --- /dev/null +++ b/module/task/css/edit.zh-cn.css @@ -0,0 +1,2 @@ +.thWidth{width:80px !important;} +.lifeThWidth{width:80px !important;} diff --git a/module/task/css/edit.zh-tw.css b/module/task/css/edit.zh-tw.css new file mode 100644 index 0000000000..0845bfd2fc --- /dev/null +++ b/module/task/css/edit.zh-tw.css @@ -0,0 +1,2 @@ +.thWidth{width:80px !important;} +.lifeThWidth{width:80px !important;} diff --git a/module/task/css/finish.css b/module/task/css/finish.css deleted file mode 100644 index 168c123dd1..0000000000 --- a/module/task/css/finish.css +++ /dev/null @@ -1,2 +0,0 @@ -.thWidth{width:120px !important;} -html[lang^='zh-'] .thWidth{width:100px !important;} diff --git a/module/task/css/finish.en.css b/module/task/css/finish.en.css new file mode 100644 index 0000000000..62f3e6f10c --- /dev/null +++ b/module/task/css/finish.en.css @@ -0,0 +1 @@ +.thWidth{width:120px !important;} diff --git a/module/task/css/finish.zh-cn.css b/module/task/css/finish.zh-cn.css new file mode 100644 index 0000000000..b0e274a3db --- /dev/null +++ b/module/task/css/finish.zh-cn.css @@ -0,0 +1 @@ +.thWidth{width:100px !important;} diff --git a/module/task/css/finish.zh-tw.css b/module/task/css/finish.zh-tw.css new file mode 100644 index 0000000000..b0e274a3db --- /dev/null +++ b/module/task/css/finish.zh-tw.css @@ -0,0 +1 @@ +.thWidth{width:100px !important;} diff --git a/module/task/css/recordestimate.css b/module/task/css/recordestimate.css index 29f1fdaf3b..e9786a1ccf 100644 --- a/module/task/css/recordestimate.css +++ b/module/task/css/recordestimate.css @@ -1,4 +1 @@ .form-condensed .table-form {margin-bottom: 20px;} - -.thWidth{width:90px !important;} -html[lang^='zh-'] .thWidth{width:70px !important;} diff --git a/module/task/css/recordestimate.en.css b/module/task/css/recordestimate.en.css new file mode 100644 index 0000000000..6e60376bc6 --- /dev/null +++ b/module/task/css/recordestimate.en.css @@ -0,0 +1 @@ +.thWidth{width:90px !important;} diff --git a/module/task/css/recordestimate.zh-cn.css b/module/task/css/recordestimate.zh-cn.css new file mode 100644 index 0000000000..b9b2a977fd --- /dev/null +++ b/module/task/css/recordestimate.zh-cn.css @@ -0,0 +1 @@ +.thWidth{width:70px !important;} diff --git a/module/task/css/recordestimate.zh-tw.css b/module/task/css/recordestimate.zh-tw.css new file mode 100644 index 0000000000..b9b2a977fd --- /dev/null +++ b/module/task/css/recordestimate.zh-tw.css @@ -0,0 +1 @@ +.thWidth{width:70px !important;} diff --git a/module/task/css/view.css b/module/task/css/view.css index 1c67a36b94..f925220cde 100644 --- a/module/task/css/view.css +++ b/module/task/css/view.css @@ -2,7 +2,4 @@ .side-col #legendProjectAndTask .list-unstyled{padding:10px; border:1px solid #ddd; border-top:0px; margin:0px;} .tab-pane table {border: 1px solid #ddd; border-top: none;} -#legendLife .thWidth{width:100px !important;} -.effortThWidth{width:90px !important;} -html[lang^='zh-'] #legendLife .thWidth{width:70px !important;} -html[lang^='zh-'] .effortThWidth{width:70px !important;} +html[lang^='zh-'] .thWidth{width:80px !important;} diff --git a/module/task/css/view.en.css b/module/task/css/view.en.css new file mode 100644 index 0000000000..c470aad1aa --- /dev/null +++ b/module/task/css/view.en.css @@ -0,0 +1,2 @@ +#legendLife .thWidth{width:100px !important;} +.effortThWidth{width:90px !important;} diff --git a/module/task/css/view.zh-cn.css b/module/task/css/view.zh-cn.css new file mode 100644 index 0000000000..fdc11d4eec --- /dev/null +++ b/module/task/css/view.zh-cn.css @@ -0,0 +1,2 @@ +#legendLife .thWidth{width:70px !important;} +.effortThWidth{width:70px !important;} diff --git a/module/task/css/view.zh-tw.css b/module/task/css/view.zh-tw.css new file mode 100644 index 0000000000..fdc11d4eec --- /dev/null +++ b/module/task/css/view.zh-tw.css @@ -0,0 +1,2 @@ +#legendLife .thWidth{width:70px !important;} +.effortThWidth{width:70px !important;} diff --git a/module/task/js/start.js b/module/task/js/start.js index 1b64249543..42d34541d7 100644 --- a/module/task/js/start.js +++ b/module/task/js/start.js @@ -8,4 +8,4 @@ function checkLeft() if(!result) setTimeout(function() {$.enableForm()}, 500); return result; } -} \ No newline at end of file +} diff --git a/module/task/lang/zh-cn.php b/module/task/lang/zh-cn.php index e5409fb53b..57cd640a3f 100644 --- a/module/task/lang/zh-cn.php +++ b/module/task/lang/zh-cn.php @@ -85,7 +85,7 @@ $lang->task->date = '日期'; $lang->task->deadline = '截止日期'; $lang->task->deadlineAB = '截止'; $lang->task->status = '任务状态'; -$lang->task->subStatus = '任务子状态'; +$lang->task->subStatus = '子状态'; $lang->task->desc = '任务描述'; $lang->task->assign = '指派'; $lang->task->assignAction = '指派任务'; diff --git a/module/task/lang/zh-tw.php b/module/task/lang/zh-tw.php index 0828690502..0214a36401 100644 --- a/module/task/lang/zh-tw.php +++ b/module/task/lang/zh-tw.php @@ -61,6 +61,8 @@ $lang->task->story = '相關需求'; $lang->task->storyAB = '需求'; $lang->task->storySpec = '需求描述'; $lang->task->storyVerify = '驗收標準'; +$lang->task->storyVersion = '需求版本'; +$lang->task->color = '標題顏色'; $lang->task->name = '任務名稱'; $lang->task->type = '任務類型'; $lang->task->pri = '優先順序'; @@ -83,6 +85,7 @@ $lang->task->date = '日期'; $lang->task->deadline = '截止日期'; $lang->task->deadlineAB = '截止'; $lang->task->status = '任務狀態'; +$lang->task->subStatus = '子狀態'; $lang->task->desc = '任務描述'; $lang->task->assign = '指派'; $lang->task->assignAction = '指派任務'; diff --git a/module/task/model.php b/module/task/model.php index 1796c611ec..7e0f0bd64e 100644 --- a/module/task/model.php +++ b/module/task/model.php @@ -315,6 +315,7 @@ class taskModel extends model if(!dao::isError()) $this->loadModel('score')->create('ajax', 'batchCreate'); if($parentID > 0 && !empty($taskID)) { + $oldParentTask = $this->dao->select('*')->from(TABLE_TASK)->where('id')->eq((int)$parentID)->fetch(); $this->updateParentStatus($taskID); $this->computeBeginAndEnd($parentID); @@ -324,7 +325,10 @@ class taskModel extends model $task->lastEditedDate = $now; $this->dao->update(TABLE_TASK)->data($task)->where('id')->eq($parentID)->exec(); - $this->action->create('task', $parentID, 'createChildren', '', trim($childTasks, ',')); + $newParentTask = $this->dao->select('*')->from(TABLE_TASK)->where('id')->eq((int)$parentID)->fetch(); + $changes = common::createChanges($oldParentTask, $newParentTask); + $actionID = $this->action->create('task', $parentID, 'createChildren', '', trim($childTasks, ',')); + if(!empty($changes)) $this->action->logHistory($actionID, $changes); } return $mails; } @@ -408,6 +412,7 @@ class taskModel extends model if(empty($parentID)) $parentID = $childTask->parent; if($parentID <= 0) return true; + $oldParentTask = $this->dao->select('*')->from(TABLE_TASK)->where('id')->eq($parentID)->fetch(); $this->computeWorkingHours($parentID); $childrenStatus = $this->dao->select('id,status')->from(TABLE_TASK)->where('parent')->eq($parentID)->andWhere('deleted')->eq(0)->fetchPairs('status', 'status'); @@ -499,7 +504,8 @@ class taskModel extends model { if(!$createAction) return $task; - $changes = common::createChanges($parentTask, $task); + $newParentTask = $this->dao->select('*')->from(TABLE_TASK)->where('id')->eq($parentID)->fetch(); + $changes = common::createChanges($oldParentTask, $newParentTask); $action = ''; if($status == 'done') $action = 'Finished'; if($status == 'closed') $action = 'Closed'; @@ -515,6 +521,19 @@ class taskModel extends model } } } + else + { + if(!dao::isError()) + { + $newParentTask = $this->dao->select('*')->from(TABLE_TASK)->where('id')->eq($parentID)->fetch(); + $changes = common::createChanges($oldParentTask, $newParentTask); + if($changes) + { + $actionID = $this->loadModel('action')->create('task', $parentID, 'Edited'); + $this->action->logHistory($actionID, $changes); + } + } + } } /** @@ -1103,7 +1122,7 @@ class taskModel extends model ->setDefault('account', $this->app->user->account) ->setDefault('task', $taskID) ->setDefault('date', $task->realStarted) - ->remove('realStarted,comment') + ->remove('realStarted,comment,status') ->get(); $estimate->consumed = $estimate->consumed - $oldTask->consumed; $this->addTaskEstimate($estimate); @@ -1329,7 +1348,7 @@ class taskModel extends model ->setDefault('date', date(DT_DATE1)) ->setIF($this->post->finishedDate, 'date', $this->post->finishedDate) ->setDefault('left', 0) - ->remove('finishedDate,comment,assignedTo,files,labels,consumed,currentConsumed') + ->remove('finishedDate,comment,assignedTo,files,labels,consumed,currentConsumed,status') ->get(); $estimate->consumed = $consumed; @@ -1655,41 +1674,9 @@ class taskModel extends model $parents = array(); foreach($tasks as $task) { - if($task->parent == -1) $parents[] = $task->id; - } - if(!empty($parents)) - { - /* Select children task. */ - $children = $this->dao->select('DISTINCT t1.*, t2.id AS storyID, t2.title AS storyTitle, t2.product, t2.branch, t2.version AS latestStoryVersion, t2.status AS storyStatus, t3.realname AS assignedToRealName') - ->from(TABLE_TASK)->alias('t1') - ->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story = t2.id') - ->leftJoin(TABLE_USER)->alias('t3')->on('t1.assignedTo = t3.account') - ->leftJoin(TABLE_MODULE)->alias('t4')->on('t1.module = t4.id') - ->where('t1.parent')->in($parents) - ->andWhere('t1.deleted')->eq(0) - ->beginIF($productID)->andWhere("((t4.root=" . (int)$productID . " and t4.type='story') OR t2.product=" . (int)$productID . ")")->fi() - ->beginIF($type == 'undone')->andWhere("(t1.status = 'wait' or t1.status ='doing')")->fi() - ->beginIF($type == 'needconfirm')->andWhere('t2.version > t1.storyVersion')->andWhere("t2.status = 'active'")->fi() - ->beginIF($type == 'assignedtome')->andWhere('t1.assignedTo')->eq($this->app->user->account)->fi() - ->beginIF($type == 'finishedbyme') - ->andWhere('t1.finishedby', 1)->eq($this->app->user->account) - ->orWhere('t1.finishedList')->like("%,{$this->app->user->account},%") - ->markRight(1) - ->fi() - ->beginIF($type == 'delayed')->andWhere('t1.deadline')->gt('1970-1-1')->andWhere('t1.deadline')->lt(date(DT_DATE1))->andWhere('t1.status')->in('wait,doing')->fi() - ->beginIF(is_array($type) or strpos(',all,undone,needconfirm,assignedtome,delayed,finishedbyme,myinvolved,', ",$type,") === false)->andWhere('t1.status')->in($type)->fi() - ->beginIF($modules)->andWhere('t1.module')->in($modules)->fi() - ->orderBy("t1.$orderBy") - ->fetchAll('id'); - - if(!empty($children)) - { - foreach($children as $child) - { - $tasks[$child->parent]->children[$child->id] = $child; - } - } + if($task->parent > 0) $parents[$task->parent] = $task->parent; } + $parents = $this->dao->select('*')->from(TABLE_TASK)->where('id')->in($parents)->fetchAll('id'); foreach($tasks as $task) { @@ -1700,6 +1687,11 @@ class taskModel extends model $tasks[$task->parent]->children[$task->id] = $task; unset($tasks[$task->id]); } + else + { + $parent = $parents[$task->parent]; + $task->parentName = $parent->name; + } } } @@ -1832,13 +1824,37 @@ class taskModel extends model */ public function getStoryTasks($storyID, $projectID = 0) { - $tasks = $this->dao->select('id, name, assignedTo, pri, status, estimate, consumed, closedReason, `left`') + $tasks = $this->dao->select('id, parent, name, assignedTo, pri, status, estimate, consumed, closedReason, `left`') ->from(TABLE_TASK) ->where('story')->eq((int)$storyID) ->andWhere('deleted')->eq(0) ->beginIF($projectID)->andWhere('project')->eq($projectID)->fi() ->fetchAll('id'); + $parents = array(); + foreach($tasks as $task) + { + if($task->parent > 0) $parents[$task->parent] = $task->parent; + } + $parents = $this->dao->select('*')->from(TABLE_TASK)->where('id')->in($parents)->fetchAll('id'); + + foreach($tasks as $task) + { + if($task->parent > 0) + { + if(isset($tasks[$task->parent])) + { + $tasks[$task->parent]->children[$task->id] = $task; + unset($tasks[$task->id]); + } + else + { + $parent = $parents[$task->parent]; + $task->parentName = $parent->name; + } + } + } + foreach($tasks as $task) { /* Compute task progress. */ @@ -1854,8 +1870,27 @@ class taskModel extends model { $task->progress = round($task->consumed / ($task->consumed + $task->left), 2) * 100; } - } + if(!empty($task->children)) + { + foreach($task->children as $child) + { + /* Compute child progress. */ + if($child->consumed == 0 and $child->left == 0) + { + $child->progress = 0; + } + elseif($child->consumed != 0 and $child->left == 0) + { + $child->progress = 100; + } + else + { + $child->progress = round($child->consumed / ($child->consumed + $child->left), 2) * 100; + } + } + } + } return $tasks; } @@ -2616,6 +2651,7 @@ class taskModel extends model echo ""; break; case 'name': + if($task->parent > 0 and isset($task->parentName)) $task->name = "{$task->parentName} / {$task->name}"; if(!empty($task->product) && isset($branchGroups[$task->product][$task->branch])) echo "" . $branchGroups[$task->product][$task->branch] . ' '; if(empty($task->children) and $task->module and isset($modulePairs[$task->module])) echo "" . $modulePairs[$task->module] . ' '; if($task->parent > 0) echo '' . $this->lang->task->childrenAB . ' '; diff --git a/module/task/view/activate.html.php b/module/task/view/activate.html.php index 2732fada2f..05c7c97fd2 100644 --- a/module/task/view/activate.html.php +++ b/module/task/view/activate.html.php @@ -40,6 +40,10 @@ + + + + printExtendFields($task, 'table', 'columns=2');?> diff --git a/module/task/view/assignto.html.php b/module/task/view/assignto.html.php index cc49284cc9..4b8783160d 100644 --- a/module/task/view/assignto.html.php +++ b/module/task/view/assignto.html.php @@ -43,6 +43,10 @@ + + + + printExtendFields($task, 'table', 'columns=2');?> diff --git a/module/task/view/cancel.html.php b/module/task/view/cancel.html.php index dee2fd5f2f..d13a720294 100644 --- a/module/task/view/cancel.html.php +++ b/module/task/view/cancel.html.php @@ -26,6 +26,10 @@
    - getClientLang() != 'en' ? 'zt-logo.png' : 'zt-logo-en.png');?>' /> + logoImg;?>' />

    misc->zentao->version, $config->version);?>

    my->form->lblAccount;?>
    user->account;?>account, "class='form-control' readonly='readonly'");?>account, "class='form-control' readonly='readonly'");?> user->commiter;?> commiter, "class='form-control'");?>
    productTitle;?> title, null, "style='color: $story->color'");?> planTitle;?>openedBy];?>openedBy);?> estimate;?> processStatus('story', $story);?> story->stageList, $story->stage);?>scmPath, 'http') === 0 ? html::a($build->scmPath) : $build->scmPath;?> filePath, 'http') === 0 ? html::a($build->filePath) : $build->filePath;?> date?>builder]?>builder);?> id&project=0&build=$build->id", '', 'list', 'bullhorn'); diff --git a/module/product/view/close.html.php b/module/product/view/close.html.php index 5f14c87886..b4e12dbe32 100644 --- a/module/product/view/close.html.php +++ b/module/product/view/close.html.php @@ -24,7 +24,11 @@ - printExtendFields($product, 'table', 'columns=2');?> + + + + + printExtendFields($product, 'table', 'columns=1');?> diff --git a/module/product/view/create.html.php b/module/product/view/create.html.php index 611576ddf4..b089804aec 100644 --- a/module/product/view/create.html.php +++ b/module/product/view/create.html.php @@ -61,6 +61,12 @@ + + + + + + printExtendFields('', 'table', 'columns=1');?> - printExtendFields('', 'table', 'columns=2');?> diff --git a/module/product/view/edit.html.php b/module/product/view/edit.html.php index c5dd629798..572d8b9935 100644 --- a/module/product/view/edit.html.php +++ b/module/product/view/edit.html.php @@ -58,11 +58,11 @@ + printExtendFields($product, 'table', 'columns=1');?> - printExtendFields($product, 'table', 'columns=2');?> diff --git a/module/product/view/view.html.php b/module/product/view/view.html.php index 636dbf4c3e..7f3dba8890 100644 --- a/module/product/view/view.html.php +++ b/module/product/view/view.html.php @@ -236,7 +236,7 @@ - printExtendFields($product, 'div', "position=right&divCell=false");?> + printExtendFields($product, 'div', "position=right&mode=value");?> diff --git a/module/productplan/control.php b/module/productplan/control.php index c3facf8ff2..aad001c7dc 100644 --- a/module/productplan/control.php +++ b/module/productplan/control.php @@ -165,7 +165,7 @@ class productplan extends control { $plan = $this->productplan->getById($planID); $this->productplan->delete(TABLE_PRODUCTPLAN, $planID); - + $this->productplan->updatePlanParentStatus($plan->parent); $this->executeHooks($planID); /* if ajax request, send result. */ @@ -277,7 +277,6 @@ class productplan extends control } $this->executeHooks($planID); - if($plan->parent > 0) $this->view->parentPlan = $this->productplan->getById($plan->parent); if($plan->parent == '-1') $this->view->childrenPlans = $this->productplan->getChildren($plan->id); diff --git a/module/productplan/lang/zh-tw.php b/module/productplan/lang/zh-tw.php index be1d6bb431..44b6b4df53 100644 --- a/module/productplan/lang/zh-tw.php +++ b/module/productplan/lang/zh-tw.php @@ -43,21 +43,23 @@ $lang->productplan->confirmUnlinkStory = "您確認移除該需求嗎?"; $lang->productplan->confirmUnlinkBug = "您確認移除該Bug嗎?"; $lang->productplan->noPlan = '暫時沒有計劃。'; -$lang->productplan->id = '編號'; -$lang->productplan->product = $lang->productCommon; -$lang->productplan->branch = '平台/分支'; -$lang->productplan->title = '名稱'; -$lang->productplan->desc = '描述'; -$lang->productplan->begin = '開始日期'; -$lang->productplan->end = '結束日期'; -$lang->productplan->last = '上次計劃'; -$lang->productplan->future = '待定'; -$lang->productplan->stories = '需求數'; -$lang->productplan->bugs = 'Bug數'; -$lang->productplan->hour = '工時'; -$lang->productplan->project = $lang->projectCommon; -$lang->productplan->parent = "父計劃"; -$lang->productplan->children= "子計劃"; +$lang->productplan->id = '編號'; +$lang->productplan->product = $lang->productCommon; +$lang->productplan->branch = '平台/分支'; +$lang->productplan->title = '名稱'; +$lang->productplan->desc = '描述'; +$lang->productplan->begin = '開始日期'; +$lang->productplan->end = '結束日期'; +$lang->productplan->last = '上次計劃'; +$lang->productplan->future = '待定'; +$lang->productplan->stories = '需求數'; +$lang->productplan->bugs = 'Bug數'; +$lang->productplan->hour = '工時'; +$lang->productplan->project = $lang->projectCommon; +$lang->productplan->parent = "父計劃"; +$lang->productplan->children = "子計劃"; +$lang->productplan->order = "排序"; +$lang->productplan->deleted = "已刪除"; $lang->productplan->endList[7] = '一星期'; $lang->productplan->endList[14] = '兩星期'; diff --git a/module/productplan/model.php b/module/productplan/model.php index aaf12c489b..bfa178a626 100644 --- a/module/productplan/model.php +++ b/module/productplan/model.php @@ -296,6 +296,22 @@ class productplanModel extends model return $this->dao->select('*')->from(TABLE_PRODUCTPLAN)->where('parent')->eq((int)$planID)->andWhere('deleted')->eq('0')->fetchAll(); } + /** + * updatePlanParentStatus,hasChild set parent = -1;noChild set parent = 0; + * + * @param int $planID + * @access public + * @return void + */ + public function updatePlanParentStatus($planID) + { + if($planID <= 0) return; + $childCount = count($this->getChildren($planID)); + if($childCount == 0) $status = 0; + if($childCount > 0) $status = -1; + return $this->dao->update(TABLE_PRODUCTPLAN)->set('parent')->eq($status)->where('id')->eq((int)$planID)->exec(); + } + /** * Create a plan. * diff --git a/module/productplan/view/edit.html.php b/module/productplan/view/edit.html.php index a8708a0391..3a22833ff6 100644 --- a/module/productplan/view/edit.html.php +++ b/module/productplan/view/edit.html.php @@ -52,11 +52,11 @@ + printExtendFields($plan, 'table', 'columns=1');?> - printExtendFields($plan, 'table', 'columns=3');?> - - + + + + + + printExtendFields($project, 'table', 'columns=5');?> diff --git a/module/project/view/ajaxkanbansetting.html.php b/module/project/view/ajaxkanbansetting.html.php index e129cedb95..409ebc7d2d 100644 --- a/module/project/view/ajaxkanbansetting.html.php +++ b/module/project/view/ajaxkanbansetting.html.php @@ -26,17 +26,17 @@ form {padding: 30px 0 40px;}
    product->status;?>status);?>
    comment;?>
    product->status;?>
    product->desc;?> @@ -68,7 +74,6 @@
    product->acl;?> product->aclList, 'open', "onclick='setWhite(this.value);'", 'block'));?>product->status;?> product->statusList, $product->status, "class='form-control'");?>
    product->desc;?> desc), "rows='8' class='form-control'");?>
    product->acl;?> product->aclList, $product->acl, "onclick='setWhite(this.value);'", 'block'));?> end != '2030-01-01' ? formatTime($plan->end) : '', 'class="form-control form-date"');?> productplan->endList , '', "onclick='computeEndDate(this.value)'");?>
    productplan->desc;?> desc), "rows='10' class='form-control kindeditor' hidefocus='true'");?>
    diff --git a/module/productplan/view/linkbug.html.php b/module/productplan/view/linkbug.html.php index 0b4600f80a..b1f8beaddf 100644 --- a/module/productplan/view/linkbug.html.php +++ b/module/productplan/view/linkbug.html.php @@ -44,8 +44,8 @@ bug->priList, $bug->pri, $bug->pri)?> createLink('bug', 'view', "bugID=$bug->id", '', true), $bug->title, '', "data-toggle='modal' data-type='iframe' data-width='90%'");?>openedBy];?>assignedTo];?>openedBy);?>assignedTo);?> processStatus('bug', $bug);?> diff --git a/module/project/control.php b/module/project/control.php index 3fd675c5d6..bf88055040 100644 --- a/module/project/control.php +++ b/module/project/control.php @@ -1490,22 +1490,24 @@ class project extends control $stories = $this->loadModel('story')->getProjectStories($projectID, $orderBy); $kanbanGroup = $this->project->getKanbanGroupData($stories, $tasks, $bugs, $type); - $kanbanSetting = $this->project->getKanbanSetting($projectID); + $kanbanSetting = $this->project->getKanbanSetting(); - $this->view->title = $this->lang->project->kanban; - $this->view->position[] = html::a($this->createLink('project', 'browse', "projectID=$projectID"), $project->name); - $this->view->position[] = $this->lang->project->kanban; - $this->view->stories = $stories; - $this->view->realnames = $this->loadModel('user')->getPairs('noletter'); - $this->view->storyOrder = $orderBy; - $this->view->orderBy = 'id_asc'; - $this->view->projectID = $projectID; - $this->view->browseType = ''; - $this->view->project = $project; - $this->view->type = $type; - $this->view->kanbanGroup = $kanbanGroup; - $this->view->allCols = $kanbanSetting->allCols; - $this->view->colorList = $kanbanSetting->colorList; + $this->view->title = $this->lang->project->kanban; + $this->view->position[] = html::a($this->createLink('project', 'browse', "projectID=$projectID"), $project->name); + $this->view->position[] = $this->lang->project->kanban; + $this->view->stories = $stories; + $this->view->realnames = $this->loadModel('user')->getPairs('noletter'); + $this->view->storyOrder = $orderBy; + $this->view->orderBy = 'id_asc'; + $this->view->projectID = $projectID; + $this->view->browseType = ''; + $this->view->project = $project; + $this->view->type = $type; + $this->view->kanbanGroup = $kanbanGroup; + $this->view->kanbanColumns = $this->project->getKanbanColumns($kanbanSetting); + $this->view->statusMap = $this->project->getKanbanStatusMap($kanbanSetting); + $this->view->statusList = $this->project->getKanbanStatusList($kanbanSetting); + $this->view->colorList = $this->project->getKanbanColorList($kanbanSetting); $this->display(); } @@ -2292,6 +2294,7 @@ class project extends control if(strpos(",$checkedItem,", ",{$project->id},") === false) unset($projectStats[$i]); } } + if(isset($this->config->bizVersion)) list($fields, $projectStats) = $this->loadModel('workflowfield')->appendDataFromFlow($fields, $projectStats); $this->post->set('fields', $fields); $this->post->set('rows', $projectStats); @@ -2338,11 +2341,9 @@ class project extends control } $this->app->loadLang('task'); - $kanbanSetting = $this->project->getKanbanSetting($projectID); - $this->view->allCols = $kanbanSetting->allCols; - $this->view->colorList = $kanbanSetting->colorList; - $this->view->projectID = $projectID; + $this->view->setting = $this->project->getKanbanSetting(); + $this->view->projectID = $projectID; $this->display(); } @@ -2356,7 +2357,7 @@ class project extends control */ public function ajaxResetKanban($projectID, $confirm = 'no') { - if($confirm != 'yes')die(js::confirm($this->lang->kanbanSetting->noticeReset, inlink('ajaxResetKanban', "projectID=$projectID&confirm=yes"))); + if($confirm != 'yes') die(js::confirm($this->lang->kanbanSetting->noticeReset, inlink('ajaxResetKanban', "projectID=$projectID&confirm=yes"))); $this->loadModel('setting'); @@ -2386,8 +2387,8 @@ class project extends control */ public function importPlanStories($projectID, $planID) { - $planStories = $planProducts = array(); - $planStory = $this->loadModel('story')->getPlanStories($planID); + $planStories = $planProducts = array(); + $planStory = $this->loadModel('story')->getPlanStories($planID); $count = 0; if(!empty($planStory)) { diff --git a/module/project/css/all.css b/module/project/css/all.css index 827c53d254..f0b971a934 100644 --- a/module/project/css/all.css +++ b/module/project/css/all.css @@ -1,4 +1 @@ #product_chosen .chosen-single{width:180px;} - -.thWidth{width:130px !important;} -html[lang^='zh-'] .thWidth{width:100px !important;} diff --git a/module/project/css/all.en.css b/module/project/css/all.en.css new file mode 100644 index 0000000000..82442a3745 --- /dev/null +++ b/module/project/css/all.en.css @@ -0,0 +1 @@ +.thWidth{width:130px !important;} diff --git a/module/project/css/all.zh-cn.css b/module/project/css/all.zh-cn.css new file mode 100644 index 0000000000..b0e274a3db --- /dev/null +++ b/module/project/css/all.zh-cn.css @@ -0,0 +1 @@ +.thWidth{width:100px !important;} diff --git a/module/project/css/all.zh-tw.css b/module/project/css/all.zh-tw.css new file mode 100644 index 0000000000..b0e274a3db --- /dev/null +++ b/module/project/css/all.zh-tw.css @@ -0,0 +1 @@ +.thWidth{width:100px !important;} diff --git a/module/project/css/burn.css b/module/project/css/burn.css index b3f814d982..5154777aa2 100644 --- a/module/project/css/burn.css +++ b/module/project/css/burn.css @@ -5,6 +5,3 @@ #burnLegend > div {position: relative; padding-left: 30px;} #burnLegend > div > .barline {position: absolute; width: 20px; left: 0; top: 13px; height: 3px; background: #EEEEEE;} #burnLegend .line-real .bg-primary{background: #1183fb} - -.thWidth{width:150px !important;} -html[lang^='zh-'] .thWidth{width:120px !important;} diff --git a/module/project/css/burn.en.css b/module/project/css/burn.en.css new file mode 100644 index 0000000000..6ea5450c92 --- /dev/null +++ b/module/project/css/burn.en.css @@ -0,0 +1 @@ +.thWidth{width:150px !important;} diff --git a/module/project/css/burn.zh-cn.css b/module/project/css/burn.zh-cn.css new file mode 100644 index 0000000000..62f3e6f10c --- /dev/null +++ b/module/project/css/burn.zh-cn.css @@ -0,0 +1 @@ +.thWidth{width:120px !important;} diff --git a/module/project/css/burn.zh-tw.css b/module/project/css/burn.zh-tw.css new file mode 100644 index 0000000000..62f3e6f10c --- /dev/null +++ b/module/project/css/burn.zh-tw.css @@ -0,0 +1 @@ +.thWidth{width:120px !important;} diff --git a/module/project/css/treestory.css b/module/project/css/treestory.css deleted file mode 100644 index 168c123dd1..0000000000 --- a/module/project/css/treestory.css +++ /dev/null @@ -1,2 +0,0 @@ -.thWidth{width:120px !important;} -html[lang^='zh-'] .thWidth{width:100px !important;} diff --git a/module/project/css/treestory.en.css b/module/project/css/treestory.en.css new file mode 100644 index 0000000000..62f3e6f10c --- /dev/null +++ b/module/project/css/treestory.en.css @@ -0,0 +1 @@ +.thWidth{width:120px !important;} diff --git a/module/project/css/treestory.zh-cn.css b/module/project/css/treestory.zh-cn.css new file mode 100644 index 0000000000..b0e274a3db --- /dev/null +++ b/module/project/css/treestory.zh-cn.css @@ -0,0 +1 @@ +.thWidth{width:100px !important;} diff --git a/module/project/css/treestory.zh-tw.css b/module/project/css/treestory.zh-tw.css new file mode 100644 index 0000000000..b0e274a3db --- /dev/null +++ b/module/project/css/treestory.zh-tw.css @@ -0,0 +1 @@ +.thWidth{width:100px !important;} diff --git a/module/project/css/view.css b/module/project/css/view.css index 30864b2f22..25bd885c3e 100644 --- a/module/project/css/view.css +++ b/module/project/css/view.css @@ -10,3 +10,4 @@ .block-dynamic .panel-body {height: 230px; overflow: auto; position: relative;} .block-team div.col-xs-6{white-space: nowrap; overflow: hidden;} +html[lang^='zh-'] .thWidth {width: 80px !important;} diff --git a/module/project/js/kanban.js b/module/project/js/kanban.js index e0b6116eb4..5fbdd3bed1 100644 --- a/module/project/js/kanban.js +++ b/module/project/js/kanban.js @@ -38,26 +38,7 @@ $(function() $.cookie('selfClose', 0, {expires:config.cookieLife, path:config.webRoot}); var $kanban = $('#kanban'); - var statusMap = - { - task: - { - wait : {doing: 'start', done: 'finish', cancel: 'cancel'}, - doing : {done: 'finish', pause: 'pause'}, - pause : {doing: 'activate', done: 'finish', cancel: 'cancel'}, - done : {doing: 'activate', closed: 'close'}, - cancel : {doing: 'activate', closed: 'close'}, - closed : {doing: 'activate'} - }, - bug: - { - wait : {done: 'resolve', cancel: 'resolve'}, - doing : {}, - done : {wait: 'activate', closed: 'close'}, - cancel : {wait: 'activate', closed: 'close'}, - closed : {wait: 'activate'} - } - }; + console.log(statusMap); // Get scrollbar width var getScrollbarWidth = function () @@ -196,5 +177,4 @@ $(function() }); return false; }); - setTimeout(function(){$('#kanban .c-side.has-btn').removeAttr('title');}, 500); }); diff --git a/module/project/lang/en.php b/module/project/lang/en.php index 3de3d7e13b..7ded04f922 100644 --- a/module/project/lang/en.php +++ b/module/project/lang/en.php @@ -107,7 +107,7 @@ $lang->team->limitedList['no'] = 'No'; $lang->project->basicInfo = 'Basic Information'; $lang->project->otherInfo = 'Other Information'; -/* 字段取值列表。*/ +/* Field value list. */ $lang->project->statusList['wait'] = 'Waiting'; $lang->project->statusList['doing'] = 'Doing'; $lang->project->statusList['suspended'] = 'Suspended'; @@ -115,9 +115,9 @@ $lang->project->statusList['closed'] = 'Closed'; $lang->project->aclList['open'] = "Default (Users who can visit {$lang->projectCommon} can access it.)"; $lang->project->aclList['private'] = 'Private (For team members only.)'; -$lang->project->aclList['custom'] = 'Whitelist (Team members and the whitelist users can access it.)'; +$lang->project->aclList['custom'] = 'Custom (Team members and the whitelist users can access it.)'; -/* 方法列表。*/ +/* Method list. */ $lang->project->index = "{$lang->projectCommon} Home"; $lang->project->task = 'Task List'; $lang->project->groupTask = 'Group View'; @@ -181,7 +181,7 @@ $lang->project->iteration = 'Iterations'; $lang->project->iterationInfo = '%s Iterations'; $lang->project->viewAll = 'View All'; -/* 分组浏览。*/ +/* Group browsing. */ $lang->project->allTasks = 'All'; $lang->project->assignedToMe = 'My'; $lang->project->myInvolved = 'Involved'; @@ -212,12 +212,12 @@ $lang->project->groupFilter['assignedTo']['all'] = 'All'; $lang->project->byQuery = 'Search'; -/* 查询条件列表。*/ +/* Query condition list. */ $lang->project->allProject = "All {$lang->projectCommon}s"; $lang->project->aboveAllProduct = "All the above {$lang->productCommon}s"; $lang->project->aboveAllProject = "All the above {$lang->projectCommon}s"; -/* 页面提示。*/ +/* Page prompt. */ $lang->project->linkStoryByPlanTips = "This action will link all stories in this plan to the {$lang->projectCommon}."; $lang->project->selectProject = "Select {$lang->projectCommon}"; $lang->project->beginAndEnd = 'Duration'; @@ -254,7 +254,7 @@ $lang->project->byUser = 'By User'; $lang->project->noProject = "No {$lang->projectCommon}. "; $lang->project->noMembers = 'No team members yet. '; -/* 交互提示。*/ +/* Interactive prompts. */ $lang->project->confirmDelete = "Do you want to delete the {$lang->projectCommon}[%s]?"; $lang->project->confirmUnlinkMember = "Do you want to unlink this User from {$lang->projectCommon}?"; $lang->project->confirmUnlinkStory = "Do you want to unlink this Story from {$lang->projectCommon}?"; @@ -277,7 +277,7 @@ $lang->project->action->opened = '$date, created by $actor .' $lang->project->action->managed = '$date, managed by $actor .' . "\n"; $lang->project->action->extra = "The linked {$lang->productCommon}s are %s."; -/* 统计。*/ +/* Statistics. */ $lang->project->charts = new stdclass(); $lang->project->charts->burn = new stdclass(); $lang->project->charts->burn->graph = new stdclass(); diff --git a/module/project/lang/zh-cn.php b/module/project/lang/zh-cn.php index f4e239079d..16e055d4d2 100644 --- a/module/project/lang/zh-cn.php +++ b/module/project/lang/zh-cn.php @@ -34,7 +34,7 @@ $lang->project->workHour = '工时'; $lang->project->totalHours = '可用工时'; $lang->project->totalDays = '可用工日'; $lang->project->status = $lang->projectCommon . '状态'; -$lang->project->subStatus = $lang->projectCommon . '子状态'; +$lang->project->subStatus = '子状态'; $lang->project->desc = $lang->projectCommon . '描述'; $lang->project->owner = '负责人'; $lang->project->PO = $lang->productCommon . '负责人'; diff --git a/module/project/lang/zh-tw.php b/module/project/lang/zh-tw.php index b24819ee72..be2ea33b95 100644 --- a/module/project/lang/zh-tw.php +++ b/module/project/lang/zh-tw.php @@ -12,9 +12,18 @@ /* 欄位列表。*/ $lang->project->common = $lang->projectCommon . '視圖'; $lang->project->allProjects = '所有' . $lang->projectCommon; +$lang->project->id = $lang->projectCommon . '編號'; $lang->project->type = $lang->projectCommon . '類型'; $lang->project->name = $lang->projectCommon . '名稱'; $lang->project->code = $lang->projectCommon . '代號'; +$lang->project->statge = '階段'; +$lang->project->pri = '優先順序'; +$lang->project->openedBy = '由誰創建'; +$lang->project->openedDate = '創建日期'; +$lang->project->closedBy = '由誰關閉'; +$lang->project->closedDate = '關閉日期'; +$lang->project->canceledBy = '由誰取消'; +$lang->project->canceledDate = '取消日期'; $lang->project->begin = '開始日期'; $lang->project->end = '結束日期'; $lang->project->dateRange = '起始日期'; @@ -25,6 +34,7 @@ $lang->project->workHour = '工時'; $lang->project->totalHours = '可用工時'; $lang->project->totalDays = '可用工日'; $lang->project->status = $lang->projectCommon . '狀態'; +$lang->project->subStatus = '子狀態'; $lang->project->desc = $lang->projectCommon . '描述'; $lang->project->owner = '負責人'; $lang->project->PO = $lang->productCommon . '負責人'; @@ -329,6 +339,13 @@ $lang->project->featureBar['task']['delayed'] = '已延期'; $lang->project->featureBar['task']['needconfirm'] = '需求變更'; $lang->project->featureBar['task']['status'] = $lang->project->statusSelects['']; +$lang->project->featureBar['all']['all'] = $lang->project->all; +$lang->project->featureBar['all']['undone'] = $lang->project->undone; +$lang->project->featureBar['all']['wait'] = $lang->project->statusList['wait']; +$lang->project->featureBar['all']['doing'] = $lang->project->statusList['doing']; +$lang->project->featureBar['all']['suspended'] = $lang->project->statusList['suspended']; +$lang->project->featureBar['all']['closed'] = $lang->project->statusList['closed']; + $lang->project->treeLevel = array(); $lang->project->treeLevel['all'] = '全部展開'; $lang->project->treeLevel['root'] = '全部摺疊'; diff --git a/module/project/model.php b/module/project/model.php index afc9f6bd45..535e4879d3 100644 --- a/module/project/model.php +++ b/module/project/model.php @@ -2002,6 +2002,13 @@ class projectModel extends model { foreach($taskTeam as $taskID => $team) $tasks[$taskID]->team = $team; } + + $parents = array(); + foreach($tasks as $task) + { + if($task->parent > 0) $parents[$task->parent] = $task->parent; + } + $parents = $this->dao->select('*')->from(TABLE_TASK)->where('id')->in($parents)->fetchAll('id'); foreach($tasks as $task) { @@ -2012,6 +2019,11 @@ class projectModel extends model $tasks[$task->parent]->children[$task->id] = $task; unset($tasks[$task->id]); } + else + { + $parent = $parents[$task->parent]; + $task->parentName = $parent->name; + } } } return $this->loadModel('task')->processTasks($tasks); @@ -2477,11 +2489,10 @@ class projectModel extends model /** * Get kanban setting. * - * @param int $projectID * @access public * @return object */ - public function getKanbanSetting($projectID) + public function getKanbanSetting() { $allCols = '1'; $showOption = '0'; @@ -2498,6 +2509,100 @@ class projectModel extends model return $kanbanSetting; } + /** + * Get kanban columns. + * + * @param object $kanbanSetting + * @access public + * @return array + */ + public function getKanbanColumns($kanbanSetting) + { + if($kanbanSetting->allCols) return array('wait', 'doing', 'pause', 'done', 'cancel', 'closed'); + return array('wait', 'doing', 'pause', 'done'); + } + + /** + * 获取状态和方法的映射关系,此关系决定了看板内容能否从一个泳道拖动到另一个泳道,以及拖动后执行什么方法。 + * Get the mapping between state and method. This relationship determines whether kanban content can be dragged from one lane + * to another, and what method is executed after dragging. + * + * 映射关系的基本格式为 map[$mode][$fromStatus][$toStatus] = $methodName。 + * The basic format of the mapping relationship is map[$mode][$fromStatus][$toStatus] = $methodName. + * + * @param string $mode 看板内容类型,可选值 task|bug The content mode of kanban, should be task or bug. + * @param string $fromStatus 拖动内容的来源泳道 The origin lane the content draged from. + * @param string $toStatus 拖动内容的目标泳道 The destination lane the content draged to. + * @param string $methodName 拖动到目标泳道后执行的方法名 The method to execute after draged the content. + * + * 例如 map['task']['doing']['done'] = 'close' 表示:任务(task)看板从进行中(doing)泳道拖动到已完成(done)泳道时,执行关闭(close)方法。 + * For example, map['task']['doing']['done'] = 'close' means: when the task kanban is dragged from the doing lane to the done lane, + * execute the close method. + * + * @param object $kanbanSetting This param is used in the biz version, don't remove it. + * @access public + * @return string + */ + public function getKanbanStatusMap($kanbanSetting) + { + $statusMap = array(); + $statusMap['task']['wait']['doing'] = 'start'; + $statusMap['task']['wait']['done'] = 'finish'; + $statusMap['task']['wait']['cancel'] = 'cancel'; + + $statusMap['task']['doing']['done'] = 'finish'; + $statusMap['task']['doing']['pause'] = 'pause'; + + $statusMap['task']['pause']['doing'] = 'activate'; + $statusMap['task']['pause']['done'] = 'finish'; + $statusMap['task']['pause']['cancel'] = 'cancel'; + + $statusMap['task']['done']['doing'] = 'activate'; + $statusMap['task']['done']['closed'] = 'close'; + + $statusMap['task']['cancel']['doing'] = 'activate'; + $statusMap['task']['cancel']['closed'] = 'close'; + + $statusMap['task']['closed']['doing'] = 'activate'; + + $statusMap['bug']['wait']['done'] = 'resolve'; + $statusMap['bug']['wait']['cancel'] = 'resolve'; + + $statusMap['bug']['done']['wait'] = 'activate'; + $statusMap['bug']['done']['closed'] = 'close'; + + $statusMap['bug']['cancel']['wait'] = 'activate'; + $statusMap['bug']['cancel']['closed'] = 'close'; + + $statusMap['bug']['closed']['wait'] = 'activate'; + + return $statusMap; + } + + /** + * Get status list of kanban. + * + * @param object $kanbanSetting This param is used in the biz version, don't remove it. + * @access public + * @return string + */ + public function getKanbanStatusList($kanbanSetting) + { + return $this->lang->task->statusList; + } + + /** + * Get color list of kanban. + * + * @param object $kanbanSetting + * @access public + * @return array + */ + public function getKanbanColorList($kanbanSetting) + { + return $kanbanSetting->colorList; + } + /** * Build burn data. * diff --git a/module/project/view/activate.html.php b/module/project/view/activate.html.php index 47900bd92c..9696d5ea04 100644 --- a/module/project/view/activate.html.php +++ b/module/project/view/activate.html.php @@ -49,6 +49,10 @@
    project->status;?>
    comment;?>
    - + - + - + - + processStatus('project', $project);?> - + - + - + - + @@ -252,7 +252,7 @@ - + @@ -268,7 +268,7 @@ - +
    project->kanbanHideCols?>kanbanSetting->optionList, $allCols)?>kanbanSetting->optionList, $setting->allCols)?>
    project->kanbanColsColor?>
    - $color):?> + colorList as $status => $color):?>
    diff --git a/module/project/view/all.html.php b/module/project/view/all.html.php index ff9fb8d19c..8a1f9969c6 100644 --- a/module/project/view/all.html.php +++ b/module/project/view/all.html.php @@ -73,7 +73,7 @@ ?>
    code;?>PM];?>PM);?> end;?> diff --git a/module/project/view/build.html.php b/module/project/view/build.html.php index 7765724589..7dbd60df47 100644 --- a/module/project/view/build.html.php +++ b/module/project/view/build.html.php @@ -61,7 +61,7 @@ scmPath, 'http') === 0 ? html::a($build->scmPath) : $build->scmPath;?> filePath, 'http') === 0 ? html::a($build->filePath) : $build->filePath;?> date?>builder]?>builder);?> - printExtendFields($project, 'table', 'columns=2');?> + + + + + printExtendFields($project, 'table', 'columns=1');?> diff --git a/module/project/view/create.html.php b/module/project/view/create.html.php index ae09dd74bd..0eea960508 100644 --- a/module/project/view/create.html.php +++ b/module/project/view/create.html.php @@ -55,10 +55,6 @@ - - - - - + @@ -86,6 +82,13 @@ + + + + + + + printExtendFields('', 'table', 'columns=1');?> global->flow == 'onlyTask') echo "class='hidden'";?>> - printExtendFields('', 'table', 'columns=3');?> diff --git a/module/project/view/doc.html.php b/module/project/view/doc.html.php index f4297d5351..7435db81d8 100644 --- a/module/project/view/doc.html.php +++ b/module/project/view/doc.html.php @@ -43,7 +43,7 @@ - + - printExtendFields($project, 'table', 'columns=3');?> + printExtendFields($project, 'table', 'columns=1');?> diff --git a/module/project/view/grouptask.html.php b/module/project/view/grouptask.html.php index e2d22f431b..04647a4b12 100644 --- a/module/project/view/grouptask.html.php +++ b/module/project/view/grouptask.html.php @@ -181,7 +181,7 @@ " . $groupName, '', "class='text-primary' title='$groupName'");?>
    - assignedTo])) printf($lang->project->memberHoursAB, $users[$task->assignedTo], $members[$task->assignedTo]->totalHours);?> + assignedTo])) printf($lang->project->memberHoursAB, zget($users, $task->assignedTo), $members[$task->assignedTo]->totalHours);?> project->groupSummaryAB, $groupSum, $groupWait, $groupDoing, $groupEstimate, $groupConsumed, $groupLeft);?>
    @@ -221,7 +221,7 @@ + + @@ -143,10 +139,10 @@ $account = $this->app->user->account; - + + + + printExtendFields($project, 'table', 'columns=3');?> diff --git a/module/project/view/story.html.php b/module/project/view/story.html.php index c687cbbe7a..b82cd5fa61 100644 --- a/module/project/view/story.html.php +++ b/module/project/view/story.html.php @@ -150,8 +150,8 @@ product][$story->branch])) echo "" . $branchGroups[$story->product][$story->branch] . '';?> title, null, "style='color: $story->color'");?> - - + + processStatus('story', $story);?> - + - + - + + + + + + + printExtendFields('', 'table', 'columns=1');?> - printExtendFields('', 'table', 'columns=2');?> diff --git a/module/release/view/edit.html.php b/module/release/view/edit.html.php index c256264445..d35affc5ed 100644 --- a/module/release/view/edit.html.php +++ b/module/release/view/edit.html.php @@ -47,11 +47,11 @@ + printExtendFields($release, 'table', 'columns=1');?> - printExtendFields($release, 'table', 'columns=2');?> diff --git a/module/release/view/linkbug.html.php b/module/release/view/linkbug.html.php index 1bd5495613..d0baad0a1a 100644 --- a/module/release/view/linkbug.html.php +++ b/module/release/view/linkbug.html.php @@ -48,8 +48,8 @@ $formID = $type == 'leftBug' ? 'unlinkedLeftBugsForm' : 'unlinkedBugsForm'; - - + + diff --git a/module/release/view/view.html.php b/module/release/view/view.html.php index ac3546430e..0b295c42c9 100644 --- a/module/release/view/view.html.php +++ b/module/release/view/view.html.php @@ -106,7 +106,7 @@ - + - + - + - printExtendFields($story, 'table', 'columns=2');?> + printExtendFields($story, 'table', 'columns=1');?> diff --git a/module/story/view/affected.html.php b/module/story/view/affected.html.php index e435960383..bd7acfb129 100644 --- a/module/story/view/affected.html.php +++ b/module/story/view/affected.html.php @@ -7,7 +7,7 @@
    projects as $projectID => $project):?> -
    name ?>   teams[$projectID] as $member) echo zget($users, $member->account, $member->account) . ' ';?>
    +
    name ?>   teams[$projectID] as $member) echo zget($users, $member->account) . ' ';?>
    project->status;?>
    comment;?>
    project->dateRange;?>project->endList , '', "onclick='computeEndDate(this.value)'");?>
    begin) ? $plan->begin : date('Y-m-d')), "class='form-control form-date' onchange='computeWorkDays()' placeholder='" . $lang->project->begin . "' required");?> @@ -66,7 +62,7 @@ end) ? $plan->end : ''), "class='form-control form-date' onchange='computeWorkDays()' placeholder='" . $lang->project->end . "' required");?>
    project->endList , '', "onclick='computeEndDate(this.value)'");?>
    project->days;?>project->typeList, '', "class='form-control' onchange='showTypeTips()'");?>
    project->typeDesc;?>
    project->status;?>
    project->manageProducts;?> @@ -139,7 +142,6 @@
    project->acl;?> project->aclList, $acl, "onclick='setWhite(this.value);'", 'block'));?>id)); else printf('%03d', $doc->id);?> module]))print($modules[$doc->module]);?> title);?>addedBy];?>addedBy);?> addedDate;?> project->desc;?> desc), "rows='6' class='form-control kindeditor' hidefocus='true'");?>
    project->acl;?> project->aclList, $project->acl, "onclick='setWhite(this.value);'", 'block'));?>
    - assignedTo])) printf($lang->project->memberHours, $users[$task->assignedTo], $members[$task->assignedTo]->totalHours);?> + assignedTo])) printf($lang->project->memberHours, zget($users, $task->assignedTo), $members[$task->assignedTo]->totalHours);?> project->countSummary, $groupSum, $groupDoing, $groupWait);?> project->timeSummary, $groupEstimate, $groupConsumed, $groupLeft);?>
    diff --git a/module/project/view/kanban.html.php b/module/project/view/kanban.html.php index bd27293d5a..f11ebab71d 100644 --- a/module/project/view/kanban.html.php +++ b/module/project/view/kanban.html.php @@ -9,17 +9,18 @@ */ ?> +
    task->statusList[$col];?>
    +
    - +
    tasks[$col])):?> tasks[$col] as $task):?> diff --git a/module/project/view/putoff.html.php b/module/project/view/putoff.html.php index 8a415c5bf3..2b1c26c28c 100644 --- a/module/project/view/putoff.html.php +++ b/module/project/view/putoff.html.php @@ -55,6 +55,10 @@
    project->status;?>status);?>
    comment;?>openedBy];?>assignedTo];?>openedBy);?>assignedTo);?> estimate;?> @@ -233,6 +233,8 @@ $lang->story->stageList[''] = $lang->null; foreach($lang->story->stageList as $key => $stage) { + if(empty($key)) continue; + if(strpos('tested|verified|released|closed', $key) === false) continue; $actionLink = $this->createLink('story', 'batchChangeStage', "stage=$key"); echo "
  • " . html::a('#', $stage, '', "onclick=\"setFormAction('$actionLink','hiddenwin')\"") . "
  • "; } diff --git a/module/project/view/suspend.html.php b/module/project/view/suspend.html.php index 85245e4e3a..89ef1020c8 100644 --- a/module/project/view/suspend.html.php +++ b/module/project/view/suspend.html.php @@ -24,7 +24,11 @@ - printExtendFields($project, 'table', 'columns=2');?> + + + + + printExtendFields($project, 'table', 'columns=1');?> diff --git a/module/project/view/treestory.html.php b/module/project/view/treestory.html.php index 6e6f6075c6..61eb409fe7 100644 --- a/module/project/view/treestory.html.php +++ b/module/project/view/treestory.html.php @@ -153,7 +153,7 @@ { foreach($mailto as $account) { - if(empty($account)) continue; echo "" . $users[trim($account)] . '  '; + if(empty($account)) continue; echo "" . zget($users, trim($account)) . '  '; } } ?> @@ -290,11 +290,11 @@ - + - + @@ -307,7 +307,7 @@ } else { - foreach($reviewedBy as $account) echo ' ' . $users[trim($account)]; + foreach($reviewedBy as $account) echo ' ' . zget($users, trim($account)); } ?> @@ -318,7 +318,7 @@ - + @@ -334,7 +334,7 @@ - +
    project->status;?>
    comment;?>
    story->openedBy;?>openedBy] . $lang->at . $story->openedDate;?>openedBy) . $lang->at . $story->openedDate;?>
    story->assignedTo;?>assignedTo ? $users[$story->assignedTo] . $lang->at . $story->assignedDate : $lang->noData;?>assignedTo ? zget($users, $story->assignedTo) . $lang->at . $story->assignedDate : $lang->noData;?>
    story->reviewedBy;?>
    story->closedBy;?>closedBy ? $users[$story->closedBy] . $lang->at . $story->closedDate : $lang->noData;?>closedBy ? zget($users, $story->closedBy) . $lang->at . $story->closedDate : $lang->noData;?>
    story->closedReason;?>
    story->lastEditedBy;?>lastEditedBy ? $users[$story->lastEditedBy] . $lang->at . $story->lastEditedDate : $lang->noData;?>lastEditedBy ? zget($users, $story->lastEditedBy) . $lang->at . $story->lastEditedDate : $lang->noData;?>
    diff --git a/module/project/view/view.html.php b/module/project/view/view.html.php index 6854d0e7ee..d61c02ba17 100644 --- a/module/project/view/view.html.php +++ b/module/project/view/view.html.php @@ -295,7 +295,7 @@ - printExtendFields($project, 'div', "position=right&divCell=false");?> + printExtendFields($project, 'div', "position=right&mode=value");?> diff --git a/module/release/lang/zh-cn.php b/module/release/lang/zh-cn.php index fb2a646e98..91903b68a1 100644 --- a/module/release/lang/zh-cn.php +++ b/module/release/lang/zh-cn.php @@ -28,6 +28,7 @@ $lang->release->confirmUnlinkStory = "您确认移除该需求吗?"; $lang->release->confirmUnlinkBug = "您确认移除该Bug吗?"; $lang->release->existBuild = '『版本』已经有『%s』这条记录了。您可以更改『发布名称』或者选择一个『版本』。'; $lang->release->noRelease = '暂时没有发布。'; +$lang->release->errorDate = '发布日期不能大于今天。'; $lang->release->basicInfo = '基本信息'; diff --git a/module/release/lang/zh-tw.php b/module/release/lang/zh-tw.php index 46f285d74f..b098fe82a5 100644 --- a/module/release/lang/zh-tw.php +++ b/module/release/lang/zh-tw.php @@ -40,6 +40,7 @@ $lang->release->marker = '里程碑'; $lang->release->date = '發佈日期'; $lang->release->desc = '描述'; $lang->release->status = '狀態'; +$lang->release->subStatus = '子狀態'; $lang->release->last = '上次發佈'; $lang->release->unlinkStory = '移除需求'; $lang->release->unlinkBug = '移除Bug'; diff --git a/module/release/model.php b/module/release/model.php index bb22044618..a11b44f7dd 100644 --- a/module/release/model.php +++ b/module/release/model.php @@ -106,6 +106,11 @@ class releaseModel extends model $productID = (int)$productID; $branch = (int)$branch; $buildID = 0; + + /* Check date must be not more than today. */ + if($this->post->date > date('Y-m-d')) return dao::$errors[] = $this->lang->release->errorDate; + + /* Auto create build when release is not link build. */ if($this->post->build == false && $this->post->name) { $build = $this->dao->select('*')->from(TABLE_BUILD) @@ -125,7 +130,7 @@ class releaseModel extends model ->add('builder', $this->app->user->account) ->add('branch', $branch) ->stripTags($this->config->release->editor->create['id'], $this->config->allowedTags) - ->remove('marker,build,files,labels,uid') + ->remove('marker,build,files,labels,uid,subStatus') // There is the subStatus field in the biz version. ->get(); $build = $this->loadModel('file')->processImgURL($build, $this->config->release->editor->create['id']); $this->dao->insert(TABLE_BUILD)->data($build) diff --git a/module/release/view/create.html.php b/module/release/view/create.html.php index 82fcd40458..115262cf60 100644 --- a/module/release/view/create.html.php +++ b/module/release/view/create.html.php @@ -30,20 +30,25 @@ release->last . ': ' . $lastRelease->name . ')';?>
    release->build;?>
    release->date;?>
    release->status;?>
    release->desc;?>
    files;?> fetch('file', 'buildform');?>release->status;?> release->statusList, $release->status, "class='form-control'");?>
    release->desc;?> desc), "rows=10 class='form-control kindeditor' hidefocus='true'");?>
    files;?> fetch('file', 'buildform');?> bug->priList, $bug->pri, $bug->pri)?> createLink('bug', 'view', "bugID=$bug->id", '', true), $bug->title, '', "data-toggle='modal' data-type='iframe' data-width='90%'");?>openedBy];?>resolvedBy];?>openedBy);?>resolvedBy);?> processStatus('bug', $bug);?> pri;?>' title='story->priList, $story->pri, $story->pri);?>'>story->priList, $story->pri, $story->pri);?> title, '', "class='preview'");?>openedBy];?>openedBy);?> estimate;?> processStatus('story', $story);?> @@ -181,9 +181,9 @@ processStatus('bug', $bug);?> openedBy];?>openedBy);?> openedDate, 5, 11)?>resolvedBy];?>resolvedBy);?> resolvedDate, 5, 11)?> field == 'subStatus') + { + $field = $this->workflowfield->getByField($module, 'subStatus'); + + $searchConfig['fields'][$field->field] = $field->name; + $searchConfig['params'][$field->field] = array('operator' => '=', 'control' => 'select', 'values' => $field->options); + + continue; + } + + /* The other built-in fields do not need to set their configuration. */ if($field->buildin) continue; + + /* Set configuration for user defined fields. */ $operator = ($field->control == 'input' or $field->control == 'textarea') ? 'include' : '='; + $control = ($field->control == 'select' or $field->control == 'radio' or $field->control == 'checkbox') ? 'select' : 'input'; $options = $this->workflowfield->getFieldOptions($field); - $control = ($field->control == 'select' || $field->control == 'radio' || $field->control == 'checkbox') ? 'select' : 'input'; + $searchConfig['fields'][$field->field] = $field->name; $searchConfig['params'][$field->field] = array('operator' => $operator, 'control' => $control, 'values' => $options); } diff --git a/module/sso/model.php b/module/sso/model.php index fd53fd52da..8d902b3107 100644 --- a/module/sso/model.php +++ b/module/sso/model.php @@ -61,12 +61,6 @@ class ssoModel extends model $user = $this->dao->select('*')->from(TABLE_USER)->where('account')->eq($data->account)->fetch(); if($user) die(js::alert($this->lang->sso->bindHasAccount)); - if(isset($this->config->safe->mode) and $this->user->computePasswordStrength($data->password1) < $this->config->safe->mode) - { - dao::$errors['password1'][] = $this->lang->user->weakPassword; - return false; - } - $user = new stdclass(); $user->account = $data->account; $user->password = md5($data->password1); diff --git a/module/story/control.php b/module/story/control.php index 100ccea897..a0ced2d673 100644 --- a/module/story/control.php +++ b/module/story/control.php @@ -653,9 +653,14 @@ class story extends control { if(!empty($_POST)) { - $this->story->activate($storyID); + $changes = $this->story->activate($storyID); if(dao::isError()) die(js::error(dao::getError())); - $actionID = $this->action->create('story', $storyID, 'Activated', $this->post->comment); + + if($changes) + { + $actionID = $this->action->create('story', $storyID, 'Activated', $this->post->comment); + $this->action->logHistory($actionID, $changes); + } $this->executeHooks($storyID); @@ -769,13 +774,15 @@ class story extends control { if(!empty($_POST)) { - $this->story->review($storyID); + $changes = $this->story->review($storyID); if(dao::isError()) die(js::error(dao::getError())); - $result = $this->post->result; - $actionID = $this->action->create('story', $storyID, 'Reviewed', $this->post->comment, ucfirst($result)); - if($this->post->result == 'reject') + + if($changes) { - $this->action->create('story', $storyID, 'Closed', '', ucfirst($this->post->closedReason)); + $result = $this->post->result; + $actionID = $this->action->create('story', $storyID, 'Reviewed', $this->post->comment, ucfirst($result)); + if($result == 'reject') $actionID = $this->action->create('story', $storyID, 'Closed', '', ucfirst($this->post->closedReason)); + $this->action->logHistory($actionID, $changes); } $this->executeHooks($storyID); @@ -846,8 +853,12 @@ class story extends control { $changes = $this->story->close($storyID); if(dao::isError()) die(js::error(dao::getError())); - $actionID = $this->action->create('story', $storyID, 'Closed', $this->post->comment, ucfirst($this->post->closedReason) . ($this->post->duplicateStory ? ':' . (int)$this->post->duplicateStory : '')); - $this->action->logHistory($actionID, $changes); + + if($changes) + { + $actionID = $this->action->create('story', $storyID, 'Closed', $this->post->comment, ucfirst($this->post->closedReason) . ($this->post->duplicateStory ? ':' . (int)$this->post->duplicateStory : '')); + $this->action->logHistory($actionID, $changes); + } $this->executeHooks($storyID); @@ -1654,6 +1665,8 @@ class story extends control } if(!(in_array('platform', $productsType) or in_array('branch', $productsType))) unset($fields['branch']);// If products's type are normal, unset branch field. + if(isset($this->config->bizVersion)) list($fields, $stories) = $this->loadModel('workflowfield')->appendDataFromFlow($fields, $stories); + $this->post->set('fields', $fields); $this->post->set('rows', $stories); $this->post->set('kind', 'story'); @@ -1703,4 +1716,43 @@ class story extends control if($id) die(html::select("storys[$id]", $storys, '', 'class="form-control"')); die(html::select('story', $storys, '', 'class=form-control')); } + + /** + * Ajax get story status. + * + * @param string $method + * @param string $params + * @access public + * @return void + */ + public function ajaxGetStatus($method, $params = '') + { + parse_str(str_replace(',', '&', $params), $params); + $status = ''; + if($method == 'create') + { + $status = 'draft'; + if(!empty($params['needNotReview'])) $status = 'active'; + if(!empty($params['project'])) $status = 'active'; + if($this->story->checkForceReview()) $status = 'draft'; + } + elseif($method == 'change') + { + $oldStory = $this->dao->findById((int)$params['storyID'])->from(TABLE_STORY)->fetch(); + $status = $oldStory->status; + if($params['changed'] and $oldStory->status == 'active' and empty($params['needNotReview'])) $status = 'changed'; + if($params['changed'] and $oldStory->status == 'active' and $this->story->checkForceReview()) $status = 'changed'; + if($params['changed'] and $oldStory->status == 'draft' and $params['needNotReview']) $status = 'active'; + } + elseif($method == 'review') + { + $oldStory = $this->dao->findById((int)$params['storyID'])->from(TABLE_STORY)->fetch(); + $status = $oldStory->status; + if($params['result'] == 'pass' and $oldStory->status == 'draft') $status = 'active'; + if($params['result'] == 'pass' and $oldStory->status == 'changed') $status = 'active'; + if($params['result'] == 'revert') $status = 'active'; + if($params['result'] == 'reject') $status = 'closed'; + } + die($status); + } } diff --git a/module/story/css/close.css b/module/story/css/close.css deleted file mode 100644 index feca0918c6..0000000000 --- a/module/story/css/close.css +++ /dev/null @@ -1,2 +0,0 @@ -.thWidth{width:150px !important;} -html[lang^='zh-'] .thWidth{width:80px !important;} diff --git a/module/story/css/close.en.css b/module/story/css/close.en.css new file mode 100644 index 0000000000..6ea5450c92 --- /dev/null +++ b/module/story/css/close.en.css @@ -0,0 +1 @@ +.thWidth{width:150px !important;} diff --git a/module/story/css/close.zh-cn.css b/module/story/css/close.zh-cn.css new file mode 100644 index 0000000000..585844a6f4 --- /dev/null +++ b/module/story/css/close.zh-cn.css @@ -0,0 +1 @@ +.thWidth{width:80px !important;} diff --git a/module/story/css/close.zh-tw.css b/module/story/css/close.zh-tw.css new file mode 100644 index 0000000000..585844a6f4 --- /dev/null +++ b/module/story/css/close.zh-tw.css @@ -0,0 +1 @@ +.thWidth{width:80px !important;} diff --git a/module/story/css/creat.en.css b/module/story/css/creat.en.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/module/story/css/create.zh-cn.css b/module/story/css/create.zh-cn.css new file mode 100644 index 0000000000..e69de29bb2 diff --git a/module/story/css/edit.css b/module/story/css/edit.css index 448a1e0e70..325971cb2f 100644 --- a/module/story/css/edit.css +++ b/module/story/css/edit.css @@ -1,6 +1 @@ #product_chosen .chosen-single{border-right-width:1px} - -.thWidth{width:100px !important;} -.linkThWidth{width:110px !important;} -html[lang^='zh-'] .thWidth{width:80px !important;} -html[lang^='zh-'] .linkThWidth{width:70px !important;} diff --git a/module/story/css/edit.en.css b/module/story/css/edit.en.css new file mode 100644 index 0000000000..571d243dd6 --- /dev/null +++ b/module/story/css/edit.en.css @@ -0,0 +1,2 @@ +.thWidth{width:100px !important;} +.linkThWidth{width:110px !important;} diff --git a/module/story/css/edit.zh-cn.css b/module/story/css/edit.zh-cn.css new file mode 100644 index 0000000000..433f2d837b --- /dev/null +++ b/module/story/css/edit.zh-cn.css @@ -0,0 +1,2 @@ +.thWidth{width:80px !important;} +.linkThWidth{width:70px !important;} diff --git a/module/story/css/edit.zh-tw.css b/module/story/css/edit.zh-tw.css new file mode 100644 index 0000000000..433f2d837b --- /dev/null +++ b/module/story/css/edit.zh-tw.css @@ -0,0 +1,2 @@ +.thWidth{width:80px !important;} +.linkThWidth{width:70px !important;} diff --git a/module/story/css/review.css b/module/story/css/review.css deleted file mode 100644 index ccda3106fd..0000000000 --- a/module/story/css/review.css +++ /dev/null @@ -1,2 +0,0 @@ -.thWidth{width:110px !important;} -html[lang^='zh-'] .thWidth{width:80px !important;} diff --git a/module/story/css/review.en.css b/module/story/css/review.en.css new file mode 100644 index 0000000000..b3e7551ab2 --- /dev/null +++ b/module/story/css/review.en.css @@ -0,0 +1 @@ +.thWidth{width:110px !important;} diff --git a/module/story/css/review.zh-cn.css b/module/story/css/review.zh-cn.css new file mode 100644 index 0000000000..585844a6f4 --- /dev/null +++ b/module/story/css/review.zh-cn.css @@ -0,0 +1 @@ +.thWidth{width:80px !important;} diff --git a/module/story/css/review.zh-tw.css b/module/story/css/review.zh-tw.css new file mode 100644 index 0000000000..585844a6f4 --- /dev/null +++ b/module/story/css/review.zh-tw.css @@ -0,0 +1 @@ +.thWidth{width:80px !important;} diff --git a/module/story/css/view.css b/module/story/css/view.css index 4ec3f19163..09f389c1f7 100644 --- a/module/story/css/view.css +++ b/module/story/css/view.css @@ -1,8 +1,3 @@ .side-col .cell{padding:0px;} .side-col #legendProjectAndTask .list-unstyled{padding:10px; border-top:0px; margin:0px;} .col-4 .cell .tab-content .text-top{padding-top: 1px} - -#legendLifeTime .thWidth{width:100px !important;} -#legendRelated .thWidth{width:110px !important;} -html[lang^='zh-'] #legendLifeTime .thWidth{width:70px !important;} -html[lang^='zh-'] #legendRelated .thWidth{width:70px !important;} diff --git a/module/story/css/view.en.css b/module/story/css/view.en.css new file mode 100644 index 0000000000..3daeffdbef --- /dev/null +++ b/module/story/css/view.en.css @@ -0,0 +1,2 @@ +#legendLifeTime .thWidth{width:100px !important;} +#legendRelated .thWidth{width:110px !important;} diff --git a/module/story/css/view.zh-cn.css b/module/story/css/view.zh-cn.css new file mode 100644 index 0000000000..84342de772 --- /dev/null +++ b/module/story/css/view.zh-cn.css @@ -0,0 +1,2 @@ +#legendLifeTime .thWidth{width:70px !important;} +#legendRelated .thWidth{width:70px !important;} diff --git a/module/story/css/view.zh-tw.css b/module/story/css/view.zh-tw.css new file mode 100644 index 0000000000..84342de772 --- /dev/null +++ b/module/story/css/view.zh-tw.css @@ -0,0 +1,2 @@ +#legendLifeTime .thWidth{width:70px !important;} +#legendRelated .thWidth{width:70px !important;} diff --git a/module/story/css/zerocase.css b/module/story/css/zerocase.css deleted file mode 100644 index 75f34ad64a..0000000000 --- a/module/story/css/zerocase.css +++ /dev/null @@ -1,2 +0,0 @@ -.thWidth{width:120px !important;} -html[lang^='zh-'] .thWidth{width:90px !important;} diff --git a/module/story/css/zerocase.en.css b/module/story/css/zerocase.en.css new file mode 100644 index 0000000000..62f3e6f10c --- /dev/null +++ b/module/story/css/zerocase.en.css @@ -0,0 +1 @@ +.thWidth{width:120px !important;} diff --git a/module/story/css/zerocase.zh-cn.css b/module/story/css/zerocase.zh-cn.css new file mode 100644 index 0000000000..6e60376bc6 --- /dev/null +++ b/module/story/css/zerocase.zh-cn.css @@ -0,0 +1 @@ +.thWidth{width:90px !important;} diff --git a/module/story/css/zerocase.zh-tw.css b/module/story/css/zerocase.zh-tw.css new file mode 100644 index 0000000000..6e60376bc6 --- /dev/null +++ b/module/story/css/zerocase.zh-tw.css @@ -0,0 +1 @@ +.thWidth{width:90px !important;} diff --git a/module/story/js/change.js b/module/story/js/change.js index e4b512c5a8..b94ee6d026 100644 --- a/module/story/js/change.js +++ b/module/story/js/change.js @@ -3,8 +3,30 @@ $(function() $('#needNotReview').on('change', function() { $('#assignedTo').attr('disabled', $(this).is(':checked') ? 'disabled' : null).trigger('chosen:updated'); + getStatus('change', "storyID=" + storyID + ",changed=" + changed + ",needNotReview=" + ($(this).prop('checked') ? 1 : 0)); }); $('#needNotReview').change(); + $specBox = $('#spec').closest('td').find('.ke-container iframe.ke-edit-iframe').contents().find('.article-content'); + $verifyBox = $('#verify').closest('td').find('.ke-container iframe.ke-edit-iframe').contents().find('.article-content'); + $('#title').change(function() + { + newChanged = ($(this).val() != oldStoryTitle || $specBox.html() != oldStorySpec || $verifyBox.html() != oldStoryVerify || $('.file-input-list .file-input.normal').length > 0) ? 1 : 0; + if(changed != newChanged) + { + changed = newChanged; + getStatus('change', "storyID=" + storyID + ",changed=" + changed + ",needNotReview=" + ($('#needNotReview').prop('checked') ? 1 : 0)); + } + }); + $('.ke-container iframe.ke-edit-iframe').contents().find('.article-content').keyup(function() + { + newChanged = ($('#title').val() != oldStoryTitle || $specBox.html() != oldStorySpec || $verifyBox.html() != oldStoryVerify || $('.file-input-list .file-input.normal').length > 0) ? 1 : 0; + if(changed != newChanged) + { + changed = newChanged; + getStatus('change', "storyID=" + storyID + ",changed=" + changed + ",needNotReview=" + ($('#needNotReview').prop('checked') ? 1 : 0)); + } + }); + if($('.tabs .tab-content .tab-pane.active').children().length == 0) $('.tabs .nav-tabs li.active').css('border-bottom', '1px solid #ccc'); }); diff --git a/module/story/js/common.js b/module/story/js/common.js new file mode 100644 index 0000000000..027eaae58b --- /dev/null +++ b/module/story/js/common.js @@ -0,0 +1,7 @@ +function getStatus(method, params) +{ + $.get(createLink('story', 'ajaxGetStatus', "method=" + method + '¶ms=' + params), function(status) + { + $('form #status').val(status).change(); + }); +} diff --git a/module/story/js/create.js b/module/story/js/create.js index 9c838d5288..c1f5f5bb8a 100644 --- a/module/story/js/create.js +++ b/module/story/js/create.js @@ -3,6 +3,7 @@ $(function() $('#needNotReview').on('change', function() { $('#assignedTo').attr('disabled', $(this).is(':checked') ? 'disabled' : null).trigger('chosen:updated'); + getStatus('create', "product=" + $('#product').val() + ",project=" + projectID + ",needNotReview=" + ($(this).prop('checked') ? 1 : 0)); }); $('#needNotReview').change(); diff --git a/module/story/js/review.js b/module/story/js/review.js index 3f85da5153..a609560c51 100644 --- a/module/story/js/review.js +++ b/module/story/js/review.js @@ -33,6 +33,8 @@ function switchShow(result) $('#assignedTo').val(assignedTo); $('#assignedTo').trigger("chosen:updated"); } + + getStatus('review', "storyID=" + storyID + ",result=" + result); } function setStory(reason) diff --git a/module/story/lang/en.php b/module/story/lang/en.php index f77a4aabc7..f83dac13f5 100644 --- a/module/story/lang/en.php +++ b/module/story/lang/en.php @@ -239,7 +239,7 @@ $lang->story->action->subdividestory = array('main' => '$date, decomposed b $lang->story->action->unlinkrelatedstory = array('main' => '$date, unlinked by $actor from Story $extra.'); $lang->story->action->unlinkchildstory = array('main' => '$date, unlinked by $actor Decomposed Story $extra.'); -/* 统计报表。*/ +/* Statistical statement. */ $lang->story->report = new stdclass(); $lang->story->report->common = 'Report'; $lang->story->report->select = 'Select Report Type'; diff --git a/module/story/lang/zh-tw.php b/module/story/lang/zh-tw.php index 2acaaa9946..081e073922 100644 --- a/module/story/lang/zh-tw.php +++ b/module/story/lang/zh-tw.php @@ -68,6 +68,9 @@ $lang->story->source = '需求來源'; $lang->story->sourceNote = '來源備註'; $lang->story->fromBug = '來源Bug'; $lang->story->title = '需求名稱'; +$lang->story->type = '需求類型'; +$lang->story->color = '標題顏色'; +$lang->story->toBug = '轉Bug'; $lang->story->spec = '需求描述'; $lang->story->assign = '指派給'; $lang->story->verify = '驗收標準'; @@ -76,6 +79,7 @@ $lang->story->estimate = '預計工時'; $lang->story->estimateAB = '預計'; $lang->story->hour = '小時'; $lang->story->status = '當前狀態'; +$lang->story->subStatus = '子狀態'; $lang->story->stage = '所處階段'; $lang->story->stageAB = '階段'; $lang->story->stagedBy = '設置階段者'; diff --git a/module/story/model.php b/module/story/model.php index fc077f8238..ea1384f3e3 100644 --- a/module/story/model.php +++ b/module/story/model.php @@ -749,7 +749,8 @@ class storyModel extends model $this->dao->delete()->from(TABLE_FILE)->where('objectType')->eq('story')->andWhere('objectID')->eq($storyID)->andWhere('extra')->eq($oldStory->version)->exec(); } if($this->post->result != 'reject') $this->setStage($storyID); - return true; + + return common::createChanges($oldStory, $story); } /** @@ -1163,7 +1164,8 @@ class storyModel extends model ->get(); $this->dao->update(TABLE_STORY)->data($story)->autoCheck()->where('id')->eq($storyID)->exec(); $this->setStage($storyID); - return true; + + return common::createChanges($oldStory, $story); } /** @@ -2509,9 +2511,7 @@ class storyModel extends model echo substr($story->openedDate, 5, 11); break; case 'assignedTo': - $assignedToText = zget($users, $story->assignedTo, $story->assignedTo); - $btnTextClass = ($story->assignedTo == $this->app->user->account) ? 'text-red' : ''; - echo "{$assignedToText}"; + $this->printAssignedHtml($story, $users); break; case 'assignedDate': echo substr($story->assignedDate, 5, 11); @@ -2562,6 +2562,34 @@ class storyModel extends model } } + /** + * Product module story page add assignment function. + * + * @param object $story + * @param array $users + * @access public + * @return void + */ + public function printAssignedHtml($story, $users) + { + $btnTextClass = ''; + $assignedToText = zget($users, $story->assignedTo); + + if(empty($story->assignedTo)) + { + $btnTextClass = 'text-primary'; + $assignedToText = $this->lang->task->noAssigned; + } + if($story->assignedTo == $this->app->user->account) $btnTextClass = 'text-red'; + + $btnClass = $story->assignedTo == 'closed' ? ' disabled' : ''; + $btnClass = "iframe btn btn-icon-left btn-sm {$btnClass}"; + $assignToLink = helper::createLink('story', 'assignTo', "storyID=$story->id", '', true); + $assignToHtml = html::a($assignToLink, " {$assignedToText}", '', "class='$btnClass'"); + + echo !common::hasPriv('story', 'assignTo', $story) ? "{$assignedToText}" : $assignToHtml; + } + /** * Set report condition. * diff --git a/module/story/view/activate.html.php b/module/story/view/activate.html.php index 4ebed040f0..aacb0bb91d 100644 --- a/module/story/view/activate.html.php +++ b/module/story/view/activate.html.php @@ -38,7 +38,7 @@ ?>
    story->comment;?>
    @@ -25,7 +25,7 @@ - + @@ -59,10 +59,10 @@ - - + + - + @@ -87,8 +87,8 @@ - - + + diff --git a/module/story/view/assignto.html.php b/module/story/view/assignto.html.php index c298f7032b..ba8cc09ff1 100644 --- a/module/story/view/assignto.html.php +++ b/module/story/view/assignto.html.php @@ -29,7 +29,11 @@ - printExtendFields($story, 'table', 'columns=2');?> + + + + + printExtendFields($story, 'table', 'columns=1');?> diff --git a/module/story/view/change.html.php b/module/story/view/change.html.php index b8821e3f05..a828a4d006 100644 --- a/module/story/view/change.html.php +++ b/module/story/view/change.html.php @@ -24,8 +24,8 @@
    id;?> createLink('task', 'view', "taskID=$task->id"), $task->name, '_blank');?>assignedTo];?>assignedTo);?> processStatus('task', $task);?> processStatus('bug', $bug);?> openedBy];?>resolvedBy];?>openedBy);?>resolvedBy);?> bug->resolutionList[$bug->resolution];?>lastEditedBy];?>lastEditedBy);?>
    processStatus('testcase', $case);?> openedBy];?>lastEditedBy];?>openedBy);?>lastEditedBy);?>
    story->assign;?> assignedTo, "class='form-control chosen'");?>
    story->status;?>status);?>
    comment;?>
    - + - - - - - - - - - - - - - - - + + + printExtendFields($story, 'table', 'columns=1');?> + + + + + + + + + + + + + + + + - + - + - - printExtendFields($story, 'table', 'columns=2');?> + + + + + printExtendFields($story, 'table', 'columns=1');?> diff --git a/module/story/view/create.html.php b/module/story/view/create.html.php index f46123ae39..a630dbaf74 100644 --- a/module/story/view/create.html.php +++ b/module/story/view/create.html.php @@ -173,7 +173,11 @@ - printExtendFields('', 'table', 'columns=4');?> + + + + + printExtendFields('', 'table', 'columns=1');?> @@ -210,5 +214,6 @@ +story->module);?> diff --git a/module/story/view/edit.html.php b/module/story/view/edit.html.php index 96473dcb3a..7b29c31993 100644 --- a/module/story/view/edit.html.php +++ b/module/story/view/edit.html.php @@ -122,7 +122,10 @@ - + status != 'draft'):?> @@ -171,8 +174,8 @@
    story->legendLifeTime;?>
    story->reviewedBy;?> -
    +
    +
    reviewedBy, 'class="form-control chosen"');?> story->checkForceReview()):?> @@ -34,35 +34,40 @@
    story->title;?>title, 'class="form-control"');?>
    story->spec;?>spec), 'rows=8 class="form-control"');?>story->specTemplate;?>
    story->verify;?>verify), 'rows=6 class="form-control"');?>
    story->comment;?>
    story->status;?>status);?>
    story->title;?>title, 'class="form-control"');?>
    story->spec;?>spec), 'rows=8 class="form-control"');?>story->specTemplate;?>
    story->verify;?>verify), 'rows=6 class="form-control"');?>
    story->comment;?>
    attatch;?>fetch('file', 'buildform');?>fetch('file', 'buildform');?>
    story->checkAffection;?>
    + lastEditedDate); echo html::submitButton(); @@ -78,4 +83,9 @@ +id);?> +title);?> +spec);?> +verify);?> + diff --git a/module/story/view/close.html.php b/module/story/view/close.html.php index 3208de9fc9..872d185444 100644 --- a/module/story/view/close.html.php +++ b/module/story/view/close.html.php @@ -36,7 +36,11 @@ story->childStories;?>
    story->status;?>
    story->comment;?>
    story->status;?>
    story->legendAttatch;?> fetch('file', 'buildform');?>
    story->status;?>processStatus('story', $story);?> + processStatus('story', $story);?> + status);?> +
    - - + + diff --git a/module/story/view/review.html.php b/module/story/view/review.html.php index 7e548c22f8..fa3703d339 100644 --- a/module/story/view/review.html.php +++ b/module/story/view/review.html.php @@ -64,11 +64,15 @@ var assignedTo = 'lastEditedBy ? print($story->lastEditedBy) : pri + + + + + printExtendFields($story, 'table', 'columns=1');?> - printExtendFields($story, 'table', 'columns=2');?> @@ -89,4 +93,5 @@ var assignedTo = 'lastEditedBy ? print($story->lastEditedBy) : pri
    +id);?> diff --git a/module/story/view/tasks.html.php b/module/story/view/tasks.html.php index 08ba9c6051..5f85b5299c 100644 --- a/module/story/view/tasks.html.php +++ b/module/story/view/tasks.html.php @@ -37,6 +37,25 @@ include '../../common/view/chart.html.php'; + children)):?> + + children as $key => $child):?> + + children)) ? ' table-child-bottom' : '';?> + + + + + + + + + + + + + + diff --git a/module/story/view/view.html.php b/module/story/view/view.html.php index 06ca7f37a0..eb9982657b 100644 --- a/module/story/view/view.html.php +++ b/module/story/view/view.html.php @@ -226,7 +226,7 @@ - +
    story->openedBy;?>openedBy];?>story->openedBy;?>openedBy);?>
    story->assignedTo;?>story->assignedTo;?> lastEditedBy ? $story->lastEditedBy : $story->openedBy, "class='form-control chosen'");?>
    story->status;?>status);?>
    story->reviewedBy;?> user->account, "class='form-control' multiple data-placeholder='{$lang->story->chosen->reviewedBy}'");?>
    story->comment;?> left;?>
    id;?>lang->task->children . '">' . $this->lang->task->childrenAB . '' ?>name;?>task->priList, $child->pri, $child->pri)?>'>pri == '0' ? '' : zget($lang->task->priList, $child->pri, $child->pri);?>processStatus('task', $child);?>assignedTo, $child->assignedTo);?>estimate;?>consumed;?>left;?>
    story->legendMailto;?>mailto); foreach($mailto as $account) {if(empty($account)) continue; echo "" . $users[trim($account)] . '  '; }?>mailto); foreach($mailto as $account) {if(empty($account)) continue; echo "" . zget($users, trim($account)) . '  '; }?>
    @@ -236,15 +236,15 @@
    story->openedBy;?>openedBy] . $lang->at . $story->openedDate;?>openedBy) . $lang->at . $story->openedDate;?>
    story->assignedTo;?>assignedTo) echo $users[$story->assignedTo] . $lang->at . $story->assignedDate;?>assignedTo) echo zget($users, $story->assignedTo) . $lang->at . $story->assignedDate;?>
    story->reviewedBy;?>reviewedBy); foreach($reviewedBy as $account) echo ' ' . $users[trim($account)]; ?>reviewedBy); foreach($reviewedBy as $account) echo ' ' . zget($users, trim($account)); ?>
    story->reviewedDate;?>
    story->closedBy;?>closedBy) echo $users[$story->closedBy] . $lang->at . $story->closedDate;?>closedBy) echo zget($users, $story->closedBy) . $lang->at . $story->closedDate;?>
    story->closedReason;?>
    story->lastEditedBy;?>lastEditedBy) echo $users[$story->lastEditedBy] . $lang->at . $story->lastEditedDate;?>lastEditedBy) echo zget($users, $story->lastEditedBy) . $lang->at . $story->lastEditedDate;?>
    @@ -387,7 +387,7 @@ - printExtendFields($story, 'div', "position=right&divCell=true");?> + printExtendFields($story, 'div', "position=right&mode=value");?> diff --git a/module/story/view/zerocase.html.php b/module/story/view/zerocase.html.php index 6617c1c291..30dd5da12c 100644 --- a/module/story/view/zerocase.html.php +++ b/module/story/view/zerocase.html.php @@ -59,8 +59,8 @@
    title);?> planTitle;?> story->sourceList[$story->source];?>openedBy];?>assignedTo];?>openedBy);?>assignedTo);?> estimate;?> processStatus('story', $story);?> story->stageList, $story->stage);?>
    task->status;?>
    comment;?>
    left, "class='form-control'");?> task->hour;?>
    task->status;?>status);?>
    comment;?>
    + + + + printExtendFields($task, 'table', 'columns=1');?> diff --git a/module/task/view/close.html.php b/module/task/view/close.html.php index 1341e7cd4b..8031ccfa13 100644 --- a/module/task/view/close.html.php +++ b/module/task/view/close.html.php @@ -26,6 +26,10 @@
    task->status;?>
    comment;?>
    + + + + printExtendFields($task, 'table', 'columns=1');?> diff --git a/module/task/view/create.html.php b/module/task/view/create.html.php index 289c7c5765..fda31fb51f 100644 --- a/module/task/view/create.html.php +++ b/module/task/view/create.html.php @@ -59,6 +59,11 @@ + + + + + printExtendFields('', 'table', 'columns=1');?> global->flow != 'onlyTask' and $project->type != 'ops'):?> @@ -205,7 +210,6 @@ desc, "rows='10' class='form-control'");?> - printExtendFields('', 'table', 'columns=3');?> diff --git a/module/task/view/edit.html.php b/module/task/view/edit.html.php index 9e4ab2682d..d3d786e9d2 100644 --- a/module/task/view/edit.html.php +++ b/module/task/view/edit.html.php @@ -179,7 +179,7 @@
    task->status;?>
    comment;?>
    task->status;?>
    task->story;?>
    files;?> fetch('file', 'buildform');?>
    - + diff --git a/module/task/view/finish.html.php b/module/task/view/finish.html.php index 1489dc40f0..e756408374 100644 --- a/module/task/view/finish.html.php +++ b/module/task/view/finish.html.php @@ -69,6 +69,10 @@ + + + + printExtendFields($task, 'table', 'columns=2');?> diff --git a/module/task/view/pause.html.php b/module/task/view/pause.html.php index 97a66e7377..6f1af85d72 100644 --- a/module/task/view/pause.html.php +++ b/module/task/view/pause.html.php @@ -34,6 +34,10 @@
    task->openedBy;?>openedBy];?>openedBy);?>
    task->realStarted;?>task->finishedDate;?>
    task->status;?>
    files;?>
    + + + + printExtendFields($task, 'table', 'columns=1');?> diff --git a/module/task/view/start.html.php b/module/task/view/start.html.php index 66f330cfce..78ed65c9ec 100644 --- a/module/task/view/start.html.php +++ b/module/task/view/start.html.php @@ -61,6 +61,10 @@ + + + + printExtendFields($task, 'table', 'columns=2');?> diff --git a/module/task/view/view.html.php b/module/task/view/view.html.php index d30c456c50..7c2ad104c9 100644 --- a/module/task/view/view.html.php +++ b/module/task/view/view.html.php @@ -120,7 +120,7 @@ - + @@ -376,7 +376,7 @@ - printExtendFields($task, 'div', "position=right&divCell=true");?> + printExtendFields($task, 'div', "position=right&mode=value");?> diff --git a/module/testcase/control.php b/module/testcase/control.php index ec5ae4e553..62438778e3 100644 --- a/module/testcase/control.php +++ b/module/testcase/control.php @@ -776,10 +776,15 @@ class testcase extends control { if($_POST) { - $this->testcase->review($caseID); + $changes = $this->testcase->review($caseID); if(dao::isError()) die(js::error(dao::getError())); - $result = $this->post->result; - $this->loadModel('action')->create('case', $caseID, 'Reviewed', $this->post->comment, ucfirst($result)); + + if($changes) + { + $result = $this->post->result; + $actionID = $this->loadModel('action')->create('case', $caseID, 'Reviewed', $this->post->comment, ucfirst($result)); + $this->action->logHistory($actionID, $changes); + } $this->executeHooks($caseID); @@ -1240,6 +1245,7 @@ class testcase extends control $case->linkCase = join("; \n", $tmpLinkCases); } } + if(isset($this->config->bizVersion)) list($fields, $cases) = $this->loadModel('workflowfield')->appendDataFromFlow($fields, $cases); $this->post->set('fields', $fields); $this->post->set('rows', $cases); @@ -1664,4 +1670,19 @@ class testcase extends control $moduleID = !empty($story) ? $story->module : 0; die(json_encode(array('moduleID'=> $moduleID))); } + + /** + * Get status by ajax. + * + * @param string $methodName + * @param int $caseID + * @access public + * @return void + */ + public function ajaxGetStatus($methodName, $caseID = 0) + { + $status = $this->testcase->getStatus($methodName, $caseID); + + die($status); + } } diff --git a/module/testcase/css/view.css b/module/testcase/css/view.css index 097ea7a91e..8c667e34d5 100644 --- a/module/testcase/css/view.css +++ b/module/testcase/css/view.css @@ -4,8 +4,3 @@ .outer .col-side .side-handle{right:0px;top:10px;} .outer.hide-side .main-side{display:none;} .table-fixed td{white-space: unset;} - -.thWidth{width:90px !important;} -.lifeThWidth{width:100px !important;} -html[lang^='zh-'] .thWidth{width:60px !important;} -html[lang^='zh-'] .lifeThWidth{width:60px !important;} diff --git a/module/testcase/css/view.en.css b/module/testcase/css/view.en.css new file mode 100644 index 0000000000..3b04fa1321 --- /dev/null +++ b/module/testcase/css/view.en.css @@ -0,0 +1,2 @@ +.thWidth{width:90px !important;} +.lifeThWidth{width:100px !important;} diff --git a/module/testcase/css/view.zh-cn.css b/module/testcase/css/view.zh-cn.css new file mode 100644 index 0000000000..2d131540f7 --- /dev/null +++ b/module/testcase/css/view.zh-cn.css @@ -0,0 +1,2 @@ +.thWidth{width:60px !important;} +.lifeThWidth{width:60px !important;} diff --git a/module/testcase/css/view.zh-tw.css b/module/testcase/css/view.zh-tw.css new file mode 100644 index 0000000000..2d131540f7 --- /dev/null +++ b/module/testcase/css/view.zh-tw.css @@ -0,0 +1,2 @@ +.thWidth{width:60px !important;} +.lifeThWidth{width:60px !important;} diff --git a/module/testcase/js/create.js b/module/testcase/js/create.js index 0e9a809652..e3a0f6d06a 100644 --- a/module/testcase/js/create.js +++ b/module/testcase/js/create.js @@ -144,4 +144,9 @@ $(function() var value = $select.val(); $selector.find('.pri-text').html('' + value + ''); }); + + $.get(createLink('testcase', 'ajaxGetStatus', 'methodName=create'), function(status) + { + $('#status').val(status).change(); + }); }); diff --git a/module/testcase/js/edit.js b/module/testcase/js/edit.js index 9768a4ee9a..c3d8f439ac 100644 --- a/module/testcase/js/edit.js +++ b/module/testcase/js/edit.js @@ -16,6 +16,21 @@ function getList() $(document).ready(function() { $("#story").chosen(); + + $(document).on('change', '[name^=steps], [name^=expects]', function() + { + var steps = []; + var expects = []; + var status = $('#status').val(); + + $('[name^=steps]').each(function(){ steps.push($(this).val()); }); + $('[name^=expects]').each(function(){ expects.push($(this).val()); }); + + $.post(createLink('testcase', 'ajaxGetStatus', 'methodName=update&caseID=' + caseID), {status : status, steps : steps, expects : expects}, function(status) + { + $('#status').val(status).change(); + }); + }); initSteps(); }); diff --git a/module/testcase/js/review.js b/module/testcase/js/review.js new file mode 100644 index 0000000000..0fca8a6732 --- /dev/null +++ b/module/testcase/js/review.js @@ -0,0 +1,10 @@ +$(function() +{ + $('#result').change(function() + { + $.post(createLink('testcase', 'ajaxGetStatus', 'methodName=review&caseID=' + caseID), {result : $(this).val()}, function(status) + { + $('#status').val(status).change(); + }); + }); +}) diff --git a/module/testcase/lang/en.php b/module/testcase/lang/en.php index 3a0f388ddb..7174ebf558 100644 --- a/module/testcase/lang/en.php +++ b/module/testcase/lang/en.php @@ -16,6 +16,9 @@ $lang->testcase->lib = "Case Library"; $lang->testcase->branch = "Branch/Platform"; $lang->testcase->moduleAB = 'Module'; $lang->testcase->story = 'Story'; +$lang->testcase->storyVersion = 'Story Version'; +$lang->testcase->color = 'Color'; +$lang->testcase->order = 'Order'; $lang->testcase->title = 'Title'; $lang->testcase->precondition = 'Prerequisite'; $lang->testcase->pri = 'Priority'; @@ -65,10 +68,11 @@ $lang->testcase->stepNumberAB = 'S'; $lang->testcase->createBug = 'Report Bug'; $lang->testcase->fromModule = 'Source Module'; $lang->testcase->fromCase = 'Source Case'; -$lang->testcase->sync = 'Sync. Case'; +$lang->testcase->sync = 'Synchronize Case'; $lang->testcase->ignore = 'Ignore'; $lang->testcase->fromTesttask = 'From Test Request'; -$lang->testcase->fromCaselib = 'From CaseLib'; +$lang->testcase->fromCaselib = 'From Case Library'; +$lang->testcase->deleted = 'Deleted'; $lang->case = $lang->testcase; // For dao checking using. Because 'case' is a php keywords, so the module name is testcase, table name is still case. $lang->testcase->stepID = 'ID'; @@ -114,7 +118,7 @@ $lang->testcase->copy = 'Copy Case'; $lang->testcase->group = 'Group'; $lang->testcase->groupName = 'Group Name'; $lang->testcase->step = 'Steps'; -$lang->testcase->stepChild = 'Child Step'; +$lang->testcase->stepChild = 'Child Steps'; $lang->testcase->viewAll = 'All Cases'; $lang->testcase->new = 'New'; @@ -139,7 +143,7 @@ $lang->testcase->lblTypeValue = 'Type Value'; $lang->testcase->lblStageValue = 'Phase Value'; $lang->testcase->lblStatusValue = 'Status Value'; -$lang->testcase->legendBasicInfo = 'Basic Info'; +$lang->testcase->legendBasicInfo = 'Basic Information'; $lang->testcase->legendAttatch = 'Files'; $lang->testcase->legendLinkBugs = 'Bugs'; $lang->testcase->legendOpenAndEdit = 'Create/Edit'; @@ -164,8 +168,8 @@ $lang->testcase->priList[4] = 4; $lang->testcase->typeList[''] = ''; $lang->testcase->typeList['feature'] = 'Feature'; $lang->testcase->typeList['performance'] = 'Performance'; -$lang->testcase->typeList['config'] = 'Config'; -$lang->testcase->typeList['install'] = 'Install'; +$lang->testcase->typeList['config'] = 'Configuration'; +$lang->testcase->typeList['install'] = 'Installation'; $lang->testcase->typeList['security'] = 'Security'; $lang->testcase->typeList['interface'] = 'Interface'; $lang->testcase->typeList['other'] = 'Others'; diff --git a/module/testcase/lang/zh-cn.php b/module/testcase/lang/zh-cn.php index a602e98974..acb7cfc6b5 100644 --- a/module/testcase/lang/zh-cn.php +++ b/module/testcase/lang/zh-cn.php @@ -16,12 +16,15 @@ $lang->testcase->lib = "所属库"; $lang->testcase->branch = "分支/平台"; $lang->testcase->moduleAB = '模块'; $lang->testcase->story = '相关需求'; +$lang->testcase->storyVersion = '需求版本'; +$lang->testcase->color = '标题颜色'; +$lang->testcase->order = '排序'; $lang->testcase->title = '用例标题'; $lang->testcase->precondition = '前置条件'; $lang->testcase->pri = '优先级'; $lang->testcase->type = '用例类型'; $lang->testcase->status = '用例状态'; -$lang->testcase->subStatus = '用例子状态'; +$lang->testcase->subStatus = '子状态'; $lang->testcase->steps = '用例步骤'; $lang->testcase->openedBy = '由谁创建'; $lang->testcase->openedDate = '创建日期'; @@ -69,6 +72,7 @@ $lang->testcase->sync = '同步'; $lang->testcase->ignore = '忽略'; $lang->testcase->fromTesttask = '来自测试单用例'; $lang->testcase->fromCaselib = '来自用例库用例'; +$lang->testcase->deleted = '是否删除'; $lang->case = $lang->testcase; // 用于DAO检查时使用。因为case是系统关键字,所以无法定义该模块为case,只能使用testcase,但表还是使用的case。 $lang->testcase->stepID = '编号'; diff --git a/module/testcase/lang/zh-tw.php b/module/testcase/lang/zh-tw.php index 9b340e66fe..1623a51f1a 100644 --- a/module/testcase/lang/zh-tw.php +++ b/module/testcase/lang/zh-tw.php @@ -16,11 +16,15 @@ $lang->testcase->lib = "所屬庫"; $lang->testcase->branch = "分支/平台"; $lang->testcase->moduleAB = '模組'; $lang->testcase->story = '相關需求'; +$lang->testcase->storyVersion = '需求版本'; +$lang->testcase->color = '標題顏色'; +$lang->testcase->order = '排序'; $lang->testcase->title = '用例標題'; $lang->testcase->precondition = '前置條件'; $lang->testcase->pri = '優先順序'; $lang->testcase->type = '用例類型'; $lang->testcase->status = '用例狀態'; +$lang->testcase->subStatus = '子狀態'; $lang->testcase->steps = '用例步驟'; $lang->testcase->openedBy = '由誰創建'; $lang->testcase->openedDate = '創建日期'; @@ -68,6 +72,7 @@ $lang->testcase->sync = '同步'; $lang->testcase->ignore = '忽略'; $lang->testcase->fromTesttask = '來自測試單用例'; $lang->testcase->fromCaselib = '來自用例庫用例'; +$lang->testcase->deleted = '是否刪除'; $lang->case = $lang->testcase; // 用於DAO檢查時使用。因為case是系統關鍵字,所以無法定義該模組為case,只能使用testcase,但表還是使用的case。 $lang->testcase->stepID = '編號'; diff --git a/module/testcase/model.php b/module/testcase/model.php index dfbe69b5a1..541f0cde08 100644 --- a/module/testcase/model.php +++ b/module/testcase/model.php @@ -183,9 +183,10 @@ class testcaseModel extends model */ function create($bugID) { - $now = helper::now(); - $case = fixer::input('post') - ->add('status', $this->forceNotReview() || $this->post->forceNotReview ? 'normal' : 'wait') + $now = helper::now(); + $status = $this->getStatus('create'); + $case = fixer::input('post') + ->add('status', $status) ->add('version', 1) ->add('fromBug', $bugID) ->setDefault('openedBy', $this->app->user->account) @@ -608,12 +609,13 @@ class testcaseModel extends model * Update a case. * * @param int $caseID + * @param bool $getStatus * @access public * @return void */ - public function update($caseID) + public function update($caseID, $getStatus = false) { - $oldCase = $this->getById($caseID); + $oldCase = $this->getById($caseID); if(!empty($_POST['lastEditedDate']) and $oldCase->lastEditedDate != $this->post->lastEditedDate) { dao::$errors[] = $this->lang->error->editedByOther; @@ -659,12 +661,16 @@ class testcaseModel extends model ->setIF($this->post->story != false and $this->post->story != $oldCase->story, 'storyVersion', $this->loadModel('story')->getVersion($this->post->story)) ->setDefault('lastEditedBy', $this->app->user->account) ->add('lastEditedDate', $now) - ->setDefault('story,branch', 0) + ->setDefault('story,branch', 0) ->join('stage', ',') ->join('linkCase', ',') ->remove('comment,steps,expects,files,labels,stepType') ->get(); if(!$this->forceNotReview() and $stepChanged) $case->status = 'wait'; + + /* Get status by ajax. */ + if($getStatus) return $case->status; + $this->dao->update(TABLE_CASE)->data($case)->autoCheck()->batchCheck($this->config->testcase->edit->requiredFields, 'notempty')->where('id')->eq((int)$caseID)->exec(); if(!$this->dao->isError()) { @@ -715,25 +721,30 @@ class testcaseModel extends model * * @param int $caseID * @access public - * @return bool + * @return bool | array */ public function review($caseID) { - if($this->post->result == false) die(js::alert($this->lang->testcase->mustChooseResult)); + if($this->post->result == false) die(js::alert($this->lang->testcase->mustChooseResult)); - $oldCase = $this->dao->findById($caseID)->from(TABLE_CASE)->fetch(); - $now = helper::now(); - $case = fixer::input('post') + $oldCase = $this->getById($caseID); + + $now = helper::now(); + $status = $this->getStatus('review', $caseID); + $case = fixer::input('post') ->remove('result,comment') ->setDefault('reviewedDate', substr($now, 0, 10)) ->setDefault('lastEditedBy', $this->app->user->account) ->setDefault('lastEditedDate', $now) - ->setIF($this->post->result == 'pass', 'status', 'normal') + ->setForce('status', $status) ->join('reviewedBy', ',') ->get(); $this->dao->update(TABLE_CASE)->data($case)->autoCheck()->where('id')->eq($caseID)->exec(); - return true; + + if(dao::isError()) return false; + + return common::createChanges($oldCase, $case); } /** @@ -1079,12 +1090,13 @@ class testcaseModel extends model foreach($requiredFields as $requiredField) { $requiredField = trim($requiredField); - if(empty($caseData->$requiredField)) die(js::alert(sprintf($this->lang->testcase->noRequire, $key, $this->lang->testcase->$requiredField))); + if(empty($caseData->$requiredField)) dao::$errors[] = sprintf($this->lang->testcase->noRequire, $key, $this->lang->testcase->$requiredField); } } $cases[$key] = $caseData; } + if(dao::isError()) die(js::error(dao::getError())); $forceNotReview = $this->forceNotReview(); foreach($cases as $key => $caseData) @@ -1571,4 +1583,28 @@ class testcaseModel extends model return sprintf($this->lang->testcase->summary, count($cases), $executed); } + + /** + * Get status for different method. + * + * @param string $methodName + * @param int $caseID + * @access public + * @return string + */ + public function getStatus($methodName, $caseID = 0) + { + $status = ''; + + if($methodName == 'create') $status = ($this->forceNotReview() || $this->post->forceNotReview) ? 'normal' : 'wait'; + if($methodName == 'update') $status = $this->update($caseID, $getStatus = true); + if($methodName == 'review') + { + $case = $this->dao->findById($caseID)->from(TABLE_CASE)->fetch(); + if($case) $status = $case->status; + if($this->post->result == 'pass') $status = 'normal'; + } + + return $status; + } } diff --git a/module/testcase/view/create.html.php b/module/testcase/view/create.html.php index 4b5315191c..fd99d6d02d 100644 --- a/module/testcase/view/create.html.php +++ b/module/testcase/view/create.html.php @@ -206,7 +206,11 @@ - printExtendFields('', 'table', 'columns=2');?> + + + + + printExtendFields('', 'table', 'columns=1');?> diff --git a/module/testcase/view/edit.html.php b/module/testcase/view/edit.html.php index 40d60dc641..f43d592c4a 100644 --- a/module/testcase/view/edit.html.php +++ b/module/testcase/view/edit.html.php @@ -15,6 +15,7 @@ testcase->deleteStep);?> testcase->insertBefore);?> testcase->insertAfter);?> +id);?>

    @@ -253,11 +254,11 @@

    task->status;?>
    comment;?>
    task->status;?>
    comment;?> id", '', true); ?>">name;?> deadline;?>assignedTo])) echo $users[$child->assignedTo];?>assignedTo);?> processStatus('task', $child);?> consumed;?> left;?>
    testcase->status;?>
    testcase->files;?> fetch('file', 'buildform');?>
    - + - +
    testcase->openedBy;?>openedBy] . $lang->at . $case->openedDate;?>openedBy) . $lang->at . $case->openedDate;?>
    testcase->lblLastEdited;?>lastEditedBy) echo $users[$case->lastEditedBy] . $lang->at . $case->lastEditedDate;?>lastEditedBy) echo zget($users, $case->lastEditedBy) . $lang->at . $case->lastEditedDate;?>
    diff --git a/module/testcase/view/linkcases.html.php b/module/testcase/view/linkcases.html.php index eba66b6da4..e0877ea3bd 100644 --- a/module/testcase/view/linkcases.html.php +++ b/module/testcase/view/linkcases.html.php @@ -55,7 +55,7 @@ createLink('product', 'browse', "productID={$case2Link->product}&branch={$case2Link->branch}"), $products[$case2Link->product], '_blank');?> createLink('testcase', 'view', "caseID=$case2Link->id"), $case2Link->title, '_blank');?> testcase->typeList[$case2Link->type];?> - openedBy];?> + openedBy);?> processStatus('testcase', $case2Link);?> diff --git a/module/testcase/view/review.html.php b/module/testcase/view/review.html.php index 5ea37f73e1..2f037d5cb1 100644 --- a/module/testcase/view/review.html.php +++ b/module/testcase/view/review.html.php @@ -14,6 +14,7 @@ +id);?>

    @@ -31,11 +32,15 @@ testcase->reviewResultAB;?> testcase->reviewResultList, '', 'class=form-control');?> + + testcase->status;?> + status);?> + + printExtendFields($case, 'table', 'columns=1');?> testcase->reviewedByAB;?> user->account, "class='form-control chosen' multiple");?> - printExtendFields($case, 'table', 'columns=2');?> comment;?> diff --git a/module/testcase/view/view.html.php b/module/testcase/view/view.html.php index 9f08d6d554..d74247c4cb 100644 --- a/module/testcase/view/view.html.php +++ b/module/testcase/view/view.html.php @@ -307,12 +307,12 @@ - + testcase->needReview or !empty($config->testcase->forceReview)):?> - + @@ -321,7 +321,7 @@ - +
    testcase->openedBy;?>openedBy] . $lang->at . $case->openedDate;?>openedBy) . $lang->at . $case->openedDate;?>
    testcase->reviewedBy;?>reviewedBy); foreach($reviewedBy as $account) echo ' ' . $users[trim($account)]; ?>reviewedBy); foreach($reviewedBy as $account) echo ' ' . zget($users, trim($account)); ?>
    testcase->reviewedDate;?>
    testcase->lblLastEdited;?>lastEditedBy) echo $users[$case->lastEditedBy] . $lang->at . $case->lastEditedDate;?>lastEditedBy) echo zget($users, $case->lastEditedBy) . $lang->at . $case->lastEditedDate;?>

    diff --git a/module/testreport/lang/en.php b/module/testreport/lang/en.php index f624a69f4b..68fc389dbd 100644 --- a/module/testreport/lang/en.php +++ b/module/testreport/lang/en.php @@ -10,6 +10,7 @@ $lang->testreport->view = 'Report Detail'; $lang->testreport->recreate = 'ReCreate'; $lang->testreport->title = 'Title'; +$lang->testreport->product = $lang->productCommon; $lang->testreport->bugTitle = 'Bug'; $lang->testreport->storyTitle = 'Story'; $lang->testreport->project = 'Project'; @@ -28,9 +29,11 @@ $lang->testreport->cases = 'Case'; $lang->testreport->bugInfo = 'Bug Distribution'; $lang->testreport->report = 'Summary'; $lang->testreport->legacyBugs = 'Left Bugs'; +$lang->testreport->createdBy = 'CreatedBy'; $lang->testreport->createdDate = 'CreatedDate'; $lang->testreport->objectID = 'Object'; $lang->testreport->profile = 'Profile'; +$lang->testreport->objectType = 'Object Type'; $lang->testreport->value = 'Value'; $lang->testreport->none = 'None'; $lang->testreport->all = 'All Reports'; diff --git a/module/testreport/lang/zh-cn.php b/module/testreport/lang/zh-cn.php index 2434557c78..f72c32dee3 100644 --- a/module/testreport/lang/zh-cn.php +++ b/module/testreport/lang/zh-cn.php @@ -10,6 +10,7 @@ $lang->testreport->view = '报告详情'; $lang->testreport->recreate = '重新生成报告'; $lang->testreport->title = '标题'; +$lang->testreport->product = "所属{$lang->productCommon}"; $lang->testreport->bugTitle = 'Bug 标题'; $lang->testreport->storyTitle = '需求标题'; $lang->testreport->project = '所属项目'; @@ -28,8 +29,10 @@ $lang->testreport->cases = '用例'; $lang->testreport->bugInfo = 'Bug分布'; $lang->testreport->report = '总结'; $lang->testreport->legacyBugs = '遗留的Bug'; +$lang->testreport->createdBy = '由谁创建'; $lang->testreport->createdDate = '创建时间'; $lang->testreport->objectID = '所属对象'; +$lang->testreport->objectType = '对象类型'; $lang->testreport->profile = '概况'; $lang->testreport->value = '值'; $lang->testreport->none = '无'; diff --git a/module/testreport/lang/zh-tw.php b/module/testreport/lang/zh-tw.php index 12f7d13946..54ccfd4bff 100644 --- a/module/testreport/lang/zh-tw.php +++ b/module/testreport/lang/zh-tw.php @@ -10,6 +10,7 @@ $lang->testreport->view = '報告詳情'; $lang->testreport->recreate = '重新生成報告'; $lang->testreport->title = '標題'; +$lang->testreport->product = "所屬{$lang->productCommon}"; $lang->testreport->bugTitle = 'Bug 標題'; $lang->testreport->storyTitle = '需求標題'; $lang->testreport->project = '所屬項目'; @@ -28,8 +29,10 @@ $lang->testreport->cases = '用例'; $lang->testreport->bugInfo = 'Bug分佈'; $lang->testreport->report = '總結'; $lang->testreport->legacyBugs = '遺留的Bug'; +$lang->testreport->createdBy = '由誰創建'; $lang->testreport->createdDate = '創建時間'; $lang->testreport->objectID = '所屬對象'; +$lang->testreport->objectType = '對象類型'; $lang->testreport->profile = '概況'; $lang->testreport->value = '值'; $lang->testreport->none = '無'; @@ -47,7 +50,7 @@ $lang->testreport->legendComment = '總結'; $lang->testreport->legendMore = '更多功能'; $lang->testreport->bugSeverityGroups = 'Bug嚴重級別分佈'; -$lang->testreport->bugTypeGroups = 'Bug類型別分佈'; +$lang->testreport->bugTypeGroups = 'Bug類型分佈'; $lang->testreport->bugStatusGroups = 'Bug狀態分佈'; $lang->testreport->bugOpenedByGroups = 'Bug創建者分佈'; $lang->testreport->bugResolvedByGroups = 'Bug解決者分佈'; diff --git a/module/testsuite/control.php b/module/testsuite/control.php index cffacb98dd..f97162dd4d 100644 --- a/module/testsuite/control.php +++ b/module/testsuite/control.php @@ -659,6 +659,7 @@ class testsuite extends control $this->view->position[] = $this->lang->testsuite->view; $this->view->lib = $lib; + $this->view->users = $this->loadModel('user')->getPairs('noclosed|noletter'); $this->view->actions = $this->loadModel('action')->getList('caselib', $libID); $this->display(); } diff --git a/module/testsuite/lang/en.php b/module/testsuite/lang/en.php index 34f510fe39..12b8e00358 100644 --- a/module/testsuite/lang/en.php +++ b/module/testsuite/lang/en.php @@ -28,13 +28,17 @@ $lang->testsuite->importAction = 'Import Case'; $lang->testsuite->showImport = 'Imported Data'; $lang->testsuite->successSaved = 'Saved'; +$lang->testsuite->id = 'ID'; $lang->testsuite->common = 'Test Suite'; $lang->testsuite->product = $lang->productCommon; $lang->testsuite->name = 'Name'; +$lang->testsuite->type = 'Type'; $lang->testsuite->desc = 'Description'; $lang->testsuite->author = 'Access Control'; $lang->testsuite->addedBy = 'CreatedBy'; $lang->testsuite->addedDate = 'CreatedDate'; +$lang->testsuite->lastEditedBy = 'LastEditedBy'; +$lang->testsuite->lastEditedDate = 'LastEditedDate'; $lang->testsuite->legendDesc = 'Description'; $lang->testsuite->legendBasicInfo = 'Basic Info'; diff --git a/module/testsuite/lang/zh-cn.php b/module/testsuite/lang/zh-cn.php index d589cf0277..097bdc9db0 100644 --- a/module/testsuite/lang/zh-cn.php +++ b/module/testsuite/lang/zh-cn.php @@ -28,13 +28,17 @@ $lang->testsuite->importAction = '导入用例'; $lang->testsuite->showImport = '显示导入数据'; $lang->testsuite->successSaved = '保存成功'; +$lang->testsuite->id = '编号'; $lang->testsuite->common = '套件'; $lang->testsuite->product = '所属' . $lang->productCommon; $lang->testsuite->name = '名称'; +$lang->testsuite->type = '类型'; $lang->testsuite->desc = '描述'; $lang->testsuite->author = '访问权限'; $lang->testsuite->addedBy = '由谁创建'; $lang->testsuite->addedDate = '创建时间'; +$lang->testsuite->lastEditedBy = '最后编辑人'; +$lang->testsuite->lastEditedDate = '最后编辑时间'; $lang->testsuite->legendDesc = '描述'; $lang->testsuite->legendBasicInfo = '基本信息'; diff --git a/module/testsuite/lang/zh-tw.php b/module/testsuite/lang/zh-tw.php index cf47d1a137..14edd8b4a3 100644 --- a/module/testsuite/lang/zh-tw.php +++ b/module/testsuite/lang/zh-tw.php @@ -28,13 +28,17 @@ $lang->testsuite->importAction = '導入用例'; $lang->testsuite->showImport = '顯示導入數據'; $lang->testsuite->successSaved = '保存成功'; +$lang->testsuite->id = '編號'; $lang->testsuite->common = '套件'; $lang->testsuite->product = '所屬' . $lang->productCommon; $lang->testsuite->name = '名稱'; +$lang->testsuite->type = '類型'; $lang->testsuite->desc = '描述'; $lang->testsuite->author = '訪問權限'; $lang->testsuite->addedBy = '由誰創建'; $lang->testsuite->addedDate = '創建時間'; +$lang->testsuite->lastEditedBy = '最後編輯人'; +$lang->testsuite->lastEditedDate = '最後編輯時間'; $lang->testsuite->legendDesc = '描述'; $lang->testsuite->legendBasicInfo = '基本信息'; diff --git a/module/testsuite/model.php b/module/testsuite/model.php index 95a4e77f81..9bada58ab6 100644 --- a/module/testsuite/model.php +++ b/module/testsuite/model.php @@ -720,12 +720,13 @@ class testsuiteModel extends model foreach($requiredFields as $requiredField) { $requiredField = trim($requiredField); - if(empty($caseData->$requiredField)) die(js::alert(sprintf($this->lang->testcase->noRequire, $key, $this->lang->testcase->$requiredField))); + if(empty($caseData->$requiredField)) dao::$errors[] = sprintf($this->lang->testcase->noRequire, $key, $this->lang->testcase->$requiredField); } } $cases[$key] = $caseData; } + if(dao::isError()) die(js::error(dao::getError())); $forceNotReview = $this->testcase->forceNotReview(); foreach($cases as $key => $caseData) diff --git a/module/testsuite/view/library.html.php b/module/testsuite/view/library.html.php index eb308dd9b3..1f1cee3ef4 100644 --- a/module/testsuite/view/library.html.php +++ b/module/testsuite/view/library.html.php @@ -136,7 +136,7 @@ js::set('flow', $config->global->flow); title, null, "style='color: $case->color'");?> testcase->typeList[$case->type];?> - openedBy];?> + openedBy);?> processStatus('testcase', $case);?> view->build = $build; $this->view->stories = $stories; $this->view->bugs = $bugs; - $this->display(); } @@ -499,8 +498,6 @@ class testtask extends control */ public function start($taskID) { - $actions = $this->loadModel('action')->getList('testtask', $taskID); - if(!empty($_POST)) { $changes = $this->testtask->start($taskID); @@ -529,7 +526,8 @@ class testtask extends control $this->view->title = $testtask->name . $this->lang->colon . $this->lang->testtask->start; $this->view->position[] = $this->lang->testtask->common; $this->view->position[] = $this->lang->testtask->start; - $this->view->actions = $actions; + $this->view->users = $this->loadModel('user')->getPairs('nodeleted', $testtask->owner); + $this->view->actions = $this->loadModel('action')->getList('testtask', $taskID); $this->display(); } @@ -542,8 +540,6 @@ class testtask extends control */ public function activate($taskID) { - $actions = $this->loadModel('action')->getList('testtask', $taskID); - if(!empty($_POST)) { $changes = $this->testtask->activate($taskID); @@ -572,7 +568,8 @@ class testtask extends control $this->view->title = $testtask->name . $this->lang->colon . $this->lang->testtask->start; $this->view->position[] = $this->lang->testtask->common; $this->view->position[] = $this->lang->testtask->activate; - $this->view->actions = $actions; + $this->view->users = $this->loadModel('user')->getPairs('nodeleted', $testtask->owner); + $this->view->actions = $this->loadModel('action')->getList('testtask', $taskID); $this->display(); } @@ -585,8 +582,6 @@ class testtask extends control */ public function close($taskID) { - $actions = $this->loadModel('action')->getList('testtask', $taskID); - if(!empty($_POST)) { $changes = $this->testtask->close($taskID); @@ -615,7 +610,7 @@ class testtask extends control $this->view->title = $testtask->name . $this->lang->colon . $this->lang->close; $this->view->position[] = $this->lang->testtask->common; $this->view->position[] = $this->lang->close; - $this->view->actions = $actions; + $this->view->actions = $this->loadModel('action')->getList('testtask', $taskID); $this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted|qdfirst'); $this->view->contactLists = $this->user->getContactLists($this->app->user->account, 'withnote'); $this->display(); @@ -630,8 +625,6 @@ class testtask extends control */ public function block($taskID) { - $actions = $this->loadModel('action')->getList('testtask', $taskID); - if(!empty($_POST)) { $changes = $this->testtask->block($taskID); @@ -660,7 +653,8 @@ class testtask extends control $this->view->title = $testtask->name . $this->lang->colon . $this->lang->testtask->start; $this->view->position[] = $this->lang->testtask->common; $this->view->position[] = $this->lang->testtask->block; - $this->view->actions = $actions; + $this->view->users = $this->loadModel('user')->getPairs('nodeleted', $testtask->owner); + $this->view->actions = $this->loadModel('action')->getList('testtask', $taskID); $this->display(); } @@ -930,7 +924,6 @@ class testtask extends control $caseIDList = $this->post->caseIDList ? $this->post->caseIDList : die(js::locate($url, 'parent')); $caseIDList = array_unique($caseIDList); - /* The case of tasks of qa. */ if($productID) { @@ -952,6 +945,7 @@ class testtask extends control ->leftJoin(TABLE_CASE)->alias('t2')->on('t1.case=t2.id') ->where('t2.id')->in($caseIDList) ->andWhere('t1.version=t2.version') + ->andWhere('t2.status')->ne('wait') ->fetchGroup('case', 'id'); $this->view->caseIDList = $caseIDList; diff --git a/module/testtask/js/create.js b/module/testtask/js/create.js index ae1a8ceb76..68dc6a806e 100755 --- a/module/testtask/js/create.js +++ b/module/testtask/js/create.js @@ -1,3 +1,32 @@ +/** + * load builds of selected product project. + * + * @param productID $productID + * @access public + * @return void + */ +function loadProductRelated(productID) +{ + projectID = $('#project').val(); + loadProductProjectBuilds(productID, projectID); +} + +/** + * loadProductProjectBuilds + * + * @param productID $productID + * @param projectID $projectID + * @access public + * @return void + */ +function loadProductProjectBuilds(productID, projectID) +{ + selectedBuild = $('#build').val(); + if(!selectedBuild) selectedBuild = 0; + link = createLink('build', 'ajaxGetProjectBuilds', 'projectID=' + projectID + '&productID=' + productID + '&varName=testTaskBuild&build=' + selectedBuild); + $('#buildBox').load(link, function(){$('#build').chosen();}); +} + /** * Load project related builds * @@ -62,4 +91,10 @@ function suitEndDate() $(function() { adjustPriBoxWidth(); + if($('#project').val()) + { + productID = $('#product').val(); + projectID = $('#project').val(); + loadProductProjectBuilds(productID, projectID); + } }); diff --git a/module/testtask/js/groupcase.js b/module/testtask/js/groupcase.js index 25edbaec4d..8157df3154 100644 --- a/module/testtask/js/groupcase.js +++ b/module/testtask/js/groupcase.js @@ -1,5 +1,4 @@ $(document).ready(function() { $('#' + browseType + 'Tab').addClass('active'); - $('.c-side.has-btn').removeAttr('title'); }); diff --git a/module/testtask/lang/en.php b/module/testtask/lang/en.php index ae33694809..d4783e6c80 100644 --- a/module/testtask/lang/en.php +++ b/module/testtask/lang/en.php @@ -110,7 +110,7 @@ $lang->testtask->showFail = 'Failed %s tim $lang->testtask->confirmDelete = 'Do you want to delete this build?'; $lang->testtask->confirmUnlinkCase = 'Do you want to unlink this case?'; -$lang->testtask->noticeNoOther = 'There are no test requests for this product'; +$lang->testtask->noticeNoOther = 'No test builds for this product.'; $lang->testtask->noTesttask = 'No requests. '; $lang->testtask->checkLinked = "Please check whether the product that the test request is linked to has been linked to a project."; @@ -141,7 +141,7 @@ $lang->testtask->action->testtaskclosed = '$date, $actor comp $lang->testtask->unexecuted = 'Pending'; -/* 统计报表。*/ +/* Statistical statement. */ $lang->testtask->report = new stdclass(); $lang->testtask->report->common = 'Report'; $lang->testtask->report->select = 'Select Report Type'; diff --git a/module/testtask/lang/zh-tw.php b/module/testtask/lang/zh-tw.php index 4b7950fadd..9d680e704c 100644 --- a/module/testtask/lang/zh-tw.php +++ b/module/testtask/lang/zh-tw.php @@ -63,6 +63,7 @@ $lang->testtask->end = '結束日期'; $lang->testtask->desc = '描述'; $lang->testtask->mailto = '抄送給'; $lang->testtask->status = '當前狀態'; +$lang->testtask->subStatus = '子狀態'; $lang->testtask->assignedTo = '指派給'; $lang->testtask->linkVersion = '版本'; $lang->testtask->lastRunAccount = '執行人'; @@ -162,3 +163,9 @@ $lang->testtask->report->options->graph = new stdclass(); $lang->testtask->report->options->type = 'pie'; $lang->testtask->report->options->width = 500; $lang->testtask->report->options->height = 140; + +$lang->testtask->featureBar['browse']['totalStatus'] = $lang->testtask->totalStatus; +$lang->testtask->featureBar['browse']['wait'] = $lang->testtask->wait; +$lang->testtask->featureBar['browse']['doing'] = $lang->testtask->testing; +$lang->testtask->featureBar['browse']['blocked'] = $lang->testtask->blocked; +$lang->testtask->featureBar['browse']['done'] = $lang->testtask->done; diff --git a/module/testtask/model.php b/module/testtask/model.php index dd1a16f5ec..a937a5cc83 100644 --- a/module/testtask/model.php +++ b/module/testtask/model.php @@ -992,6 +992,7 @@ class testtaskModel extends model ->leftJoin(TABLE_CASE)->alias('t2')->on('t1.case = t2.id') ->where('t1.case')->in($caseIdList) ->andWhere('t1.version=t2.version') + ->andWhere('t2.status')->ne('wait') ->fetchGroup('case', 'id'); $now = helper::now(); @@ -1157,7 +1158,7 @@ class testtaskModel extends model if($action == 'block') return ($testtask->status == 'doing' || $testtask->status == 'wait'); if($action == 'activate') return ($testtask->status == 'blocked' || $testtask->status == 'done'); if($action == 'close') return $testtask->status != 'done'; - + if($action == 'runcase') return $testtask->status != 'wait'; return true; } @@ -1390,4 +1391,5 @@ class testtaskModel extends model } return array($toList, $ccList); } + } diff --git a/module/testtask/view/activate.html.php b/module/testtask/view/activate.html.php index 097dbeef64..958cb7c25a 100644 --- a/module/testtask/view/activate.html.php +++ b/module/testtask/view/activate.html.php @@ -23,7 +23,11 @@
    - printExtendFields($task, 'table', 'columns=1');?> + + + + + printExtendFields($testtask, 'table', 'columns=1');?> diff --git a/module/testtask/view/batchrun.html.php b/module/testtask/view/batchrun.html.php index 8a8c3abd24..6d4a76d03b 100644 --- a/module/testtask/view/batchrun.html.php +++ b/module/testtask/view/batchrun.html.php @@ -29,6 +29,7 @@ + status == 'wait') continue;?> loadModel('tree')->getOptionMenu($cases[$caseID]->product, $viewType = 'case', $startModuleID = 0);?> diff --git a/module/testtask/view/block.html.php b/module/testtask/view/block.html.php index e7ec34fff1..05301610cf 100644 --- a/module/testtask/view/block.html.php +++ b/module/testtask/view/block.html.php @@ -24,7 +24,11 @@
    testtask->status;?>
    comment;?>
    version)?>
    - printExtendFields($task, 'table', 'columns=1');?> + + + + + printExtendFields($testtask, 'table', 'columns=1');?> diff --git a/module/testtask/view/close.html.php b/module/testtask/view/close.html.php index 23758c500e..aa42a83333 100644 --- a/module/testtask/view/close.html.php +++ b/module/testtask/view/close.html.php @@ -23,7 +23,11 @@
    testtask->status;?>
    comment;?>
    - printExtendFields($task, 'table', 'columns=1');?> + + + + + printExtendFields($testtask, 'table', 'columns=1');?> diff --git a/module/testtask/view/create.html.php b/module/testtask/view/create.html.php index 504dfdb255..a82c0ede2d 100644 --- a/module/testtask/view/create.html.php +++ b/module/testtask/view/create.html.php @@ -24,7 +24,7 @@ - + @@ -94,7 +94,7 @@ - printExtendFields('', 'table', 'columns=2');?> + printExtendFields('', 'table', 'columns=1');?> - printExtendFields($task, 'table', 'columns=2');?> + printExtendFields($task, 'table', 'columns=1');?> - + diff --git a/module/testtask/view/runcase.html.php b/module/testtask/view/runcase.html.php index 69a131c422..72f16e2a34 100644 --- a/module/testtask/view/runcase.html.php +++ b/module/testtask/view/runcase.html.php @@ -84,7 +84,7 @@
    testtask->status;?>
    comment;?>
    testtask->product;?>
    diff --git a/module/testtask/view/edit.html.php b/module/testtask/view/edit.html.php index 46a039505f..d920c5bc30 100644 --- a/module/testtask/view/edit.html.php +++ b/module/testtask/view/edit.html.php @@ -83,7 +83,7 @@
    diff --git a/module/testtask/view/results.html.php b/module/testtask/view/results.html.php index 60f8545008..24c5053e0d 100644 --- a/module/testtask/view/results.html.php +++ b/module/testtask/view/results.html.php @@ -40,7 +40,7 @@
      #id?> date;?>lastRunner] . ' ' . $lang->testtask->runCase;?>lastRunner) . ' ' . $lang->testtask->runCase;?> build, '');?> testcase->resultList[$result->caseResult]?> files)) echo html::a("#caseResult{$result->id}", $lang->files . $fileCount, '', "data-toggle='modal' data-type='iframe'")?> testtask->pre, '', "id='pre' class='btn btn-wide'"); - echo html::submitButton(); + if($run->case->status != 'wait') echo html::submitButton(); if($nextCase) echo ' ' . html::a(inlink('runCase', "runID={$nextCase['runID']}&caseID={$nextCase['caseID']}&version={$nextCase['version']}"), $lang->testtask->next, '', "id='next' class='btn btn-wide'"); echo html::hidden('case', $run->case->id); echo html::hidden('version', $run->case->currentVersion); diff --git a/module/testtask/view/start.html.php b/module/testtask/view/start.html.php index 124b51940c..f43b5dc55f 100644 --- a/module/testtask/view/start.html.php +++ b/module/testtask/view/start.html.php @@ -25,7 +25,11 @@ - printExtendFields($task, 'table', 'columns=1');?> + + + + + printExtendFields($testtask, 'table', 'columns=1');?> diff --git a/module/testtask/view/view.html.php b/module/testtask/view/view.html.php index 60cbcbbf49..ab463683da 100644 --- a/module/testtask/view/view.html.php +++ b/module/testtask/view/view.html.php @@ -124,7 +124,7 @@ - printExtendFields($task, 'div', "position=right&divCell=true");?> + printExtendFields($task, 'div', "position=right&mode=value");?> diff --git a/module/todo/control.php b/module/todo/control.php index c64bade578..1f2638062d 100644 --- a/module/todo/control.php +++ b/module/todo/control.php @@ -528,6 +528,7 @@ class todo extends control unset($todo->idvalue); unset($todo->private); } + if(isset($this->config->bizVersion)) list($fields, $todos) = $this->loadModel('workflowfield')->appendDataFromFlow($fields, $todos); $this->post->set('fields', $fields); $this->post->set('rows', $todos); diff --git a/module/todo/css/create.css b/module/todo/css/create.css index 79bfeb460a..2a9a6facd0 100644 --- a/module/todo/css/create.css +++ b/module/todo/css/create.css @@ -3,8 +3,3 @@ #end_chosen .chosen-single{border-left: none;} .cycleConfig .checkbox-primary{float:left; width:100px;} .cycleConfig .tab-pane{padding:8px 0px;} - -.thWidth{width:110px !important;} -.inputGroupWidth{width:270px !important;} -html[lang^='zh-'] .thWidth{width:80px !important;} -html[lang^='zh-'] .inputGroupWidth{width:200px !important;} diff --git a/module/todo/css/create.en.css b/module/todo/css/create.en.css new file mode 100644 index 0000000000..db36066e9e --- /dev/null +++ b/module/todo/css/create.en.css @@ -0,0 +1,2 @@ +.thWidth{width:110px !important;} +.inputGroupWidth{width:270px !important;} diff --git a/module/todo/css/create.zh-cn.css b/module/todo/css/create.zh-cn.css new file mode 100644 index 0000000000..5dbcc35dcf --- /dev/null +++ b/module/todo/css/create.zh-cn.css @@ -0,0 +1,2 @@ +.thWidth{width:80px !important;} +.inputGroupWidth{width:200px !important;} diff --git a/module/todo/css/create.zh-tw.css b/module/todo/css/create.zh-tw.css new file mode 100644 index 0000000000..5dbcc35dcf --- /dev/null +++ b/module/todo/css/create.zh-tw.css @@ -0,0 +1,2 @@ +.thWidth{width:80px !important;} +.inputGroupWidth{width:200px !important;} diff --git a/module/todo/css/view.css b/module/todo/css/view.css index 3b85559125..b978984d1f 100644 --- a/module/todo/css/view.css +++ b/module/todo/css/view.css @@ -1,5 +1,2 @@ #projectModal .modal-dialog, #productModal .modal-dialog {top: auto!important; bottom: 90px;} .body-modal #projectModal .modal-dialog, .body-modal #productModal .modal-dialog {top: auto!important; bottom: 55px;} - -.thWidth{width:100px !important;} -html[lang^='zh-'] .thWidth{width:80px !important;} diff --git a/module/todo/css/view.en.css b/module/todo/css/view.en.css new file mode 100644 index 0000000000..b0e274a3db --- /dev/null +++ b/module/todo/css/view.en.css @@ -0,0 +1 @@ +.thWidth{width:100px !important;} diff --git a/module/todo/css/view.zh-cn.css b/module/todo/css/view.zh-cn.css new file mode 100644 index 0000000000..585844a6f4 --- /dev/null +++ b/module/todo/css/view.zh-cn.css @@ -0,0 +1 @@ +.thWidth{width:80px !important;} diff --git a/module/todo/css/view.zh-tw.css b/module/todo/css/view.zh-tw.css new file mode 100644 index 0000000000..585844a6f4 --- /dev/null +++ b/module/todo/css/view.zh-tw.css @@ -0,0 +1 @@ +.thWidth{width:80px !important;} diff --git a/module/todo/lang/en.php b/module/todo/lang/en.php index 9128af4401..7585d76b86 100644 --- a/module/todo/lang/en.php +++ b/module/todo/lang/en.php @@ -38,25 +38,31 @@ $lang->todo->reasonList['task'] = "Convert to Task"; $lang->todo->reasonList['bug'] = "Convert to Bug"; $lang->todo->reasonList['done'] = "Done"; -$lang->todo->id = 'ID'; -$lang->todo->account = 'Owner'; -$lang->todo->date = 'Date'; -$lang->todo->begin = 'Begin'; -$lang->todo->end = 'End'; -$lang->todo->beginAB = 'Begin'; -$lang->todo->endAB = 'End'; -$lang->todo->beginAndEnd = 'Begin and End'; -$lang->todo->idvalue = 'Link ID'; -$lang->todo->type = 'Type'; -$lang->todo->pri = 'Priority'; -$lang->todo->name = 'Title'; -$lang->todo->status = 'Status'; -$lang->todo->desc = 'Description'; -$lang->todo->private = 'Private'; -$lang->todo->cycleDay = 'Day'; -$lang->todo->cycleWeek = 'Week'; -$lang->todo->cycleMonth = 'Month'; -$lang->todo->deadline = 'Expiration'; +$lang->todo->id = 'ID'; +$lang->todo->account = 'Owner'; +$lang->todo->date = 'Date'; +$lang->todo->begin = 'Begin'; +$lang->todo->end = 'End'; +$lang->todo->beginAB = 'Begin'; +$lang->todo->endAB = 'End'; +$lang->todo->beginAndEnd = 'Begin and End'; +$lang->todo->idvalue = 'Link ID'; +$lang->todo->type = 'Type'; +$lang->todo->pri = 'Priority'; +$lang->todo->name = 'Title'; +$lang->todo->status = 'Status'; +$lang->todo->desc = 'Description'; +$lang->todo->private = 'Private'; +$lang->todo->cycleDay = 'Day'; +$lang->todo->cycleWeek = 'Week'; +$lang->todo->cycleMonth = 'Month'; +$lang->todo->assignedTo = 'AssignedTo'; +$lang->todo->assignedBy = 'AssignedBy'; +$lang->todo->finishedBy = 'FinishedBy'; +$lang->todo->finishedDate = 'FinishedDate'; +$lang->todo->closedBy = 'ClosedBy'; +$lang->todo->closedDate = 'ClosedDate'; +$lang->todo->deadline = 'Expiration'; $lang->todo->every = 'Every'; $lang->todo->beforeDays = "Auto create the todo%sdays before"; diff --git a/module/todo/lang/zh-cn.php b/module/todo/lang/zh-cn.php index cd5f327a3f..b49e2b4936 100644 --- a/module/todo/lang/zh-cn.php +++ b/module/todo/lang/zh-cn.php @@ -38,25 +38,31 @@ $lang->todo->reasonList['task'] = "转任务"; $lang->todo->reasonList['bug'] = "转Bug"; $lang->todo->reasonList['done'] = "完成"; -$lang->todo->id = '编号'; -$lang->todo->account = '所有者'; -$lang->todo->date = '日期'; -$lang->todo->begin = '开始'; -$lang->todo->end = '结束'; -$lang->todo->beginAB = '开始'; -$lang->todo->endAB = '结束'; -$lang->todo->beginAndEnd = '起止时间'; -$lang->todo->idvalue = '关联编号'; -$lang->todo->type = '类型'; -$lang->todo->pri = '优先级'; -$lang->todo->name = '待办名称'; -$lang->todo->status = '状态'; -$lang->todo->desc = '描述'; -$lang->todo->private = '私人事务'; -$lang->todo->cycleDay = '天'; -$lang->todo->cycleWeek = '周'; -$lang->todo->cycleMonth = '月'; -$lang->todo->deadline = '过期时间'; +$lang->todo->id = '编号'; +$lang->todo->account = '所有者'; +$lang->todo->date = '日期'; +$lang->todo->begin = '开始'; +$lang->todo->end = '结束'; +$lang->todo->beginAB = '开始'; +$lang->todo->endAB = '结束'; +$lang->todo->beginAndEnd = '起止时间'; +$lang->todo->idvalue = '关联编号'; +$lang->todo->type = '类型'; +$lang->todo->pri = '优先级'; +$lang->todo->name = '待办名称'; +$lang->todo->status = '状态'; +$lang->todo->desc = '描述'; +$lang->todo->private = '私人事务'; +$lang->todo->cycleDay = '天'; +$lang->todo->cycleWeek = '周'; +$lang->todo->cycleMonth = '月'; +$lang->todo->assignedTo = '指派给'; +$lang->todo->assignedBy = '由谁指派'; +$lang->todo->finishedBy = '由谁完成'; +$lang->todo->finishedDate = '完成时间'; +$lang->todo->closedBy = '由谁关闭'; +$lang->todo->closedDate = '关闭时间'; +$lang->todo->deadline = '过期时间'; $lang->todo->every = '间隔'; $lang->todo->beforeDays = "提前%s天生成待办"; diff --git a/module/todo/lang/zh-tw.php b/module/todo/lang/zh-tw.php index d6b6a88936..e5e2b7da52 100644 --- a/module/todo/lang/zh-tw.php +++ b/module/todo/lang/zh-tw.php @@ -38,25 +38,31 @@ $lang->todo->reasonList['task'] = "轉任務"; $lang->todo->reasonList['bug'] = "轉Bug"; $lang->todo->reasonList['done'] = "完成"; -$lang->todo->id = '編號'; -$lang->todo->account = '所有者'; -$lang->todo->date = '日期'; -$lang->todo->begin = '開始'; -$lang->todo->end = '結束'; -$lang->todo->beginAB = '開始'; -$lang->todo->endAB = '結束'; -$lang->todo->beginAndEnd = '起止時間'; -$lang->todo->idvalue = '關聯編號'; -$lang->todo->type = '類型'; -$lang->todo->pri = '優先順序'; -$lang->todo->name = '待辦名稱'; -$lang->todo->status = '狀態'; -$lang->todo->desc = '描述'; -$lang->todo->private = '私人事務'; -$lang->todo->cycleDay = '天'; -$lang->todo->cycleWeek = '周'; -$lang->todo->cycleMonth = '月'; -$lang->todo->deadline = '過期時間'; +$lang->todo->id = '編號'; +$lang->todo->account = '所有者'; +$lang->todo->date = '日期'; +$lang->todo->begin = '開始'; +$lang->todo->end = '結束'; +$lang->todo->beginAB = '開始'; +$lang->todo->endAB = '結束'; +$lang->todo->beginAndEnd = '起止時間'; +$lang->todo->idvalue = '關聯編號'; +$lang->todo->type = '類型'; +$lang->todo->pri = '優先順序'; +$lang->todo->name = '待辦名稱'; +$lang->todo->status = '狀態'; +$lang->todo->desc = '描述'; +$lang->todo->private = '私人事務'; +$lang->todo->cycleDay = '天'; +$lang->todo->cycleWeek = '周'; +$lang->todo->cycleMonth = '月'; +$lang->todo->assignedTo = '指派給'; +$lang->todo->assignedBy = '由誰指派'; +$lang->todo->finishedBy = '由誰完成'; +$lang->todo->finishedDate = '完成時間'; +$lang->todo->closedBy = '由誰關閉'; +$lang->todo->closedDate = '關閉時間'; +$lang->todo->deadline = '過期時間'; $lang->todo->every = '間隔'; $lang->todo->beforeDays = "提前%s天生成待辦"; diff --git a/module/translate/control.php b/module/translate/control.php index 6a34f92896..c07ec5632c 100644 --- a/module/translate/control.php +++ b/module/translate/control.php @@ -29,7 +29,7 @@ class translate extends control if(!$this->active and $this->app->getMethodName() != 'index') { $this->app->loadLang('editor'); - die($this->display('translate', 'deny')); +// die($this->display('translate', 'deny')); } } diff --git a/module/translate/css/choosemodule.css b/module/translate/css/choosemodule.css deleted file mode 100644 index fec930329c..0000000000 --- a/module/translate/css/choosemodule.css +++ /dev/null @@ -1,2 +0,0 @@ -.thWidth{width:150px !important;} -html[lang^='zh-'] .thWidth{width:110px !important;} diff --git a/module/translate/css/choosemodule.en.css b/module/translate/css/choosemodule.en.css new file mode 100644 index 0000000000..6ea5450c92 --- /dev/null +++ b/module/translate/css/choosemodule.en.css @@ -0,0 +1 @@ +.thWidth{width:150px !important;} diff --git a/module/translate/css/choosemodule.zh-cn.css b/module/translate/css/choosemodule.zh-cn.css new file mode 100644 index 0000000000..b3e7551ab2 --- /dev/null +++ b/module/translate/css/choosemodule.zh-cn.css @@ -0,0 +1 @@ +.thWidth{width:110px !important;} diff --git a/module/translate/css/choosemodule.zh-tw.css b/module/translate/css/choosemodule.zh-tw.css new file mode 100644 index 0000000000..b3e7551ab2 --- /dev/null +++ b/module/translate/css/choosemodule.zh-tw.css @@ -0,0 +1 @@ +.thWidth{width:110px !important;} diff --git a/module/translate/css/index.css b/module/translate/css/index.css index 4724f3d925..36d02bab5f 100644 --- a/module/translate/css/index.css +++ b/module/translate/css/index.css @@ -14,6 +14,3 @@ #finishedLangs .item{height:30px;} #finishedLangs .item h4{margin:0; height:100%; line-height:30px;} #finishedLangs .item .pull-right{color:#999; line-height:30px;} - -.thWidth{width:130px !important;} -html[lang^='zh-'] .thWidth{width:95px !important;} diff --git a/module/translate/css/index.en.css b/module/translate/css/index.en.css new file mode 100644 index 0000000000..82442a3745 --- /dev/null +++ b/module/translate/css/index.en.css @@ -0,0 +1 @@ +.thWidth{width:130px !important;} diff --git a/module/translate/css/index.zh-cn.css b/module/translate/css/index.zh-cn.css new file mode 100644 index 0000000000..d6f932be53 --- /dev/null +++ b/module/translate/css/index.zh-cn.css @@ -0,0 +1 @@ +.thWidth{width:95px !important;} diff --git a/module/translate/css/index.zh-tw.css b/module/translate/css/index.zh-tw.css new file mode 100644 index 0000000000..d6f932be53 --- /dev/null +++ b/module/translate/css/index.zh-tw.css @@ -0,0 +1 @@ +.thWidth{width:95px !important;} diff --git a/module/translate/model.php b/module/translate/model.php index fc2b70e49f..e990466815 100644 --- a/module/translate/model.php +++ b/module/translate/model.php @@ -23,7 +23,7 @@ class translateModel extends model $data = fixer::input('post')->add('createdBy', $this->app->user->account)->get(); if(empty($data->name)) dao::$errors['name'] = sprintf($this->lang->error->notempty, $this->lang->translate->name); if(empty($data->code)) dao::$errors['code'] = sprintf($this->lang->error->notempty, $this->lang->translate->code); - if(!baseValidater::checkREG($data->code, '|^[A-Za-z0-9_]+$|')) dao::$errors['code'] = $this->lang->translate->notice->failRuleCode; + if(!baseValidater::checkREG($data->code, '|^[a-z0-9_]+$|')) dao::$errors['code'] = $this->lang->translate->notice->failRuleCode; if(dao::isError()) return false; $langs = empty($this->config->global->langs) ? array() : json_decode($this->config->global->langs, true); @@ -612,7 +612,9 @@ class translateModel extends model $preFirst = $firstLetter; $preLast = $lastLetter; } - if(!$isJoin and strpos("\'|\"", $value{0}) === false) $value = '"' . addslashes($value) . '"'; + $firstLetter = $value{0}; + $lastLetter = $value{strlen($value) - 1}; + if(!$isJoin and !(strpos("\'|\"", $firstLetter) !== false and $firstLetter == $lastLetter)) $value = '"' . addslashes($value) . '"'; } } $content .= $key . " = $value;\n"; @@ -638,7 +640,8 @@ class translateModel extends model $result = true; $tolowerValue = strtolower($value); if($tolowerValue == 'new stdclass()' or $tolowerValue == 'new stdclass') $result = false; - if(strpos($value, '$') === 0 and strpos($value, '$lang->productCommon') === false and strpos($value, '$lang->projectCommon') === false and strpos($value, '.') === false and !preg_match('/[^\$\-\>\w\'\"\[\]]/', $value)) $result = false; + /* Check for only php variable. */ + if(strpos($value, '$') === 0 and $value != '$' and strpos($value, '$lang->productCommon') === false and strpos($value, '$lang->projectCommon') === false and strpos($value, '.') === false and !preg_match('/[^\$\-\>\w\'\"\[\]]/', $value)) $result = false; if($value == '$lang->productCommon' or $value == '$lang->projectCommon') $result = false; return $result; diff --git a/module/tree/css/edit.css b/module/tree/css/edit.css index 5fffac811f..0037a851da 100644 --- a/module/tree/css/edit.css +++ b/module/tree/css/edit.css @@ -1,4 +1 @@ body{background:white; overflow:none} - -.thWidth{width:120px !important;} -html[lang^='zh-'] .thWidth{width:80px !important;} diff --git a/module/tree/css/edit.en.css b/module/tree/css/edit.en.css new file mode 100644 index 0000000000..62f3e6f10c --- /dev/null +++ b/module/tree/css/edit.en.css @@ -0,0 +1 @@ +.thWidth{width:120px !important;} diff --git a/module/tree/css/edit.zh-cn.css b/module/tree/css/edit.zh-cn.css new file mode 100644 index 0000000000..585844a6f4 --- /dev/null +++ b/module/tree/css/edit.zh-cn.css @@ -0,0 +1 @@ +.thWidth{width:80px !important;} diff --git a/module/tree/css/edit.zh-tw.css b/module/tree/css/edit.zh-tw.css new file mode 100644 index 0000000000..585844a6f4 --- /dev/null +++ b/module/tree/css/edit.zh-tw.css @@ -0,0 +1 @@ +.thWidth{width:80px !important;} diff --git a/module/tree/view/browse.html.php b/module/tree/view/browse.html.php index 1d2bc30d71..5327ed74b5 100644 --- a/module/tree/view/browse.html.php +++ b/module/tree/view/browse.html.php @@ -242,6 +242,8 @@ $(function() $('#modulesTree').find('li:not(.tree-action-item)').each(function() { var $li = $(this); + if($li.hasClass('tree-item-branch')) return; + var item = $li.data(); orders['orders[' + item.id + ']'] = $li.attr('data-order') || item.order; }); diff --git a/module/tutorial/control.php b/module/tutorial/control.php index 6c98ca423a..8cd151406b 100644 --- a/module/tutorial/control.php +++ b/module/tutorial/control.php @@ -71,7 +71,7 @@ class tutorial extends control { $this->session->set('tutorialMode', false); $this->loadModel('setting')->setItem($this->app->user->account . '.common.global.novice', 0); - if(empty($referer)) $referer = $this->createLink('index'); + if(empty($referer)) $referer = helper::safe64Encode(helper::createLink('my', 'index', '', 'html')); die(js::locate(helper::safe64Decode($referer), 'parent')); } diff --git a/module/tutorial/view/index.html.php b/module/tutorial/view/index.html.php index 8b48a0cff0..6675547e4f 100644 --- a/module/tutorial/view/index.html.php +++ b/module/tutorial/view/index.html.php @@ -12,7 +12,7 @@ ?> - +
    @@ -22,7 +22,7 @@

    tutorial->congratulation ?>

    -   tutorial->exit ?> +   ' class='btn btn-success'> tutorial->exit ?>
    @@ -36,7 +36,7 @@

    tutorial->common ?>

    diff --git a/module/upgrade/css/afterexec.css b/module/upgrade/css/afterexec.css index d25a8583a6..88647422e9 100644 --- a/module/upgrade/css/afterexec.css +++ b/module/upgrade/css/afterexec.css @@ -46,7 +46,6 @@ .card>.card-reveal>.card-heading{padding:20px 10px} .card:hover>.card-reveal{top:0} -.card.ad{margin-bottom:0px;} .card.ad > .img-wrapper { background-position: center; background-repeat: no-repeat; diff --git a/module/upgrade/view/afterexec.html.php b/module/upgrade/view/afterexec.html.php index 24632e4e80..f8189dfd31 100644 --- a/module/upgrade/view/afterexec.html.php +++ b/module/upgrade/view/afterexec.html.php @@ -24,7 +24,7 @@
    install->promotion?>
    install->product as $product):?> -
    +
    diff --git a/module/user/control.php b/module/user/control.php index 6718ac3213..0ae554abab 100644 --- a/module/user/control.php +++ b/module/user/control.php @@ -372,14 +372,17 @@ class user extends control */ public function setReferer($referer = '') { - if(!empty($referer)) - { - $this->referer = helper::safe64Decode($referer); - } - else - { - $this->referer = $this->server->http_referer ? $this->server->http_referer: ''; - } + $this->referer = $this->server->http_referer ? $this->server->http_referer: ''; + if(!empty($referer)) $this->referer = helper::safe64Decode($referer); + + /* Build zentao link regular. */ + $webRoot = $this->config->webRoot; + $linkReg = $webRoot . 'index.php?' . $this->config->moduleVar . '=\w+&' . $this->config->methodVar . '=\w+'; + if($this->config->requestType == 'PATH_INFO') $linkReg = $webRoot . '\w+' . $this->config->requestFix . '\w+'; + $linkReg = str_replace(array('/', '.', '?', '-'), array('\/', '\.', '\?', '\-'), $linkReg); + + /* Check zentao link by regular. */ + $this->referer = preg_match('/^' . $linkReg . '/', $this->referer) ? $this->referer : $webRoot; } /** diff --git a/module/user/css/batchcreate.css b/module/user/css/batchcreate.css index 54a34a9262..a00d948957 100644 --- a/module/user/css/batchcreate.css +++ b/module/user/css/batchcreate.css @@ -1,6 +1 @@ th.required:after {position: relative; right: 10px;} - -.accountThWidth{width:200px !important;} -.genderThWidth{width:140px !important;} -html[lang^='zh-'] .accountThWidth{width:180px !important;} -html[lang^='zh-'] .genderThWidth{width:90px !important;} diff --git a/module/user/css/batchcreate.en.css b/module/user/css/batchcreate.en.css new file mode 100644 index 0000000000..a3d9df2c27 --- /dev/null +++ b/module/user/css/batchcreate.en.css @@ -0,0 +1,2 @@ +.accountThWidth{width:200px !important;} +.genderThWidth{width:140px !important;} diff --git a/module/user/css/batchcreate.zh-cn.css b/module/user/css/batchcreate.zh-cn.css new file mode 100644 index 0000000000..fa09b2cae3 --- /dev/null +++ b/module/user/css/batchcreate.zh-cn.css @@ -0,0 +1,2 @@ +.accountThWidth{width:180px !important;} +.genderThWidth{width:90px !important;} diff --git a/module/user/css/batchcreate.zh-tw.css b/module/user/css/batchcreate.zh-tw.css new file mode 100644 index 0000000000..fa09b2cae3 --- /dev/null +++ b/module/user/css/batchcreate.zh-tw.css @@ -0,0 +1,2 @@ +.accountThWidth{width:180px !important;} +.genderThWidth{width:90px !important;} diff --git a/module/user/js/batchcreate.js b/module/user/js/batchcreate.js index 570f4b526e..bce0dc7c6b 100644 --- a/module/user/js/batchcreate.js +++ b/module/user/js/batchcreate.js @@ -10,15 +10,26 @@ function changeGroup(role, i) } $('#group' + i).trigger('chosen:updated'); } + function toggleCheck(obj, i) { - if($(obj).val() == '') + var $this = $(obj); + var password = $this.val(); + var $ditto = $('#ditto' + i); + var $passwordStrength = $this.closest('.input-group').find('.passwordStrength'); + if(password == '') { - $('#ditto' + i).attr('checked', true); + $ditto.attr('checked', true); + $ditto.closest('.input-group-addon').show(); + $passwordStrength.hide(); + $passwordStrength.html(''); } else { - $('#ditto' + i).removeAttr('checked'); + $ditto.removeAttr('checked'); + $ditto.closest('.input-group-addon').hide(); + $passwordStrength.html(passwordStrengthList[computePasswordStrength(password)]); + $passwordStrength.show(); } } diff --git a/module/user/js/login.js b/module/user/js/login.js index c3eb257456..4a59b47655 100644 --- a/module/user/js/login.js +++ b/module/user/js/login.js @@ -26,7 +26,10 @@ $(document).ready(function() { var password = $('input:password').val().trim(); var passwordStrength = computePasswordStrength(password); - $('#submit').after(""); + + if($('#loginPanel #passwordStrength').length == 0) $(this).after(""); + $('#loginPanel #passwordStrength').val(passwordStrength); + var rand = $('input#verifyRand').val(); if(password.length != 32 && typeof(md5) == 'function') $('input:password').val(md5(md5(password) + rand)); }); diff --git a/module/user/lang/de.php b/module/user/lang/de.php index a2fd9e07f3..0e7b194816 100644 --- a/module/user/lang/de.php +++ b/module/user/lang/de.php @@ -81,6 +81,7 @@ $lang->user->setTemplateTitle = 'Please enter the title of template.'; $lang->user->applyTemplate = 'Templates'; $lang->user->confirmDeleteTemplate = 'Do you want to delete this template?'; $lang->user->setPublicTemplate = 'Set as Public Template'; +$lang->user->tplContentNotEmpty = 'Vorlageninhalt darf nicht leer sein!'; $lang->user->profile = 'Profil'; $lang->user->project = $lang->projectCommon; diff --git a/module/user/lang/en.php b/module/user/lang/en.php index 9c2d8fb668..2187cff7b9 100644 --- a/module/user/lang/en.php +++ b/module/user/lang/en.php @@ -48,6 +48,7 @@ $lang->user->originalPassword = 'Old Password'; $lang->user->newPassword = 'New Password'; $lang->user->verifyPassword = 'Password'; $lang->user->resetPassword = 'Forgot Password?'; +$lang->user->score = 'Score'; $lang->user->legendBasic = 'Basic Information'; $lang->user->legendContribution = 'Contribution'; @@ -81,6 +82,7 @@ $lang->user->setTemplateTitle = 'Please enter the title of template.'; $lang->user->applyTemplate = 'Templates'; $lang->user->confirmDeleteTemplate = 'Do you want to delete this template?'; $lang->user->setPublicTemplate = 'Set as Public Template'; +$lang->user->tplContentNotEmpty = 'The template content cannot be empty!'; $lang->user->profile = 'Profile'; $lang->user->project = $lang->projectCommon . 's'; diff --git a/module/user/lang/zh-cn.php b/module/user/lang/zh-cn.php index f88379afa4..5b70b18831 100644 --- a/module/user/lang/zh-cn.php +++ b/module/user/lang/zh-cn.php @@ -48,6 +48,7 @@ $lang->user->originalPassword = '原密码'; $lang->user->newPassword = '新密码'; $lang->user->verifyPassword = '您的密码'; $lang->user->resetPassword = '忘记密码'; +$lang->user->score = '分数'; $lang->user->legendBasic = '基本资料'; $lang->user->legendContribution = '个人贡献'; @@ -81,6 +82,7 @@ $lang->user->setTemplateTitle = '请输入模板标题'; $lang->user->applyTemplate = '应用模板'; $lang->user->confirmDeleteTemplate = '您确认要删除该模板吗?'; $lang->user->setPublicTemplate = '设为公共模板'; +$lang->user->tplContentNotEmpty = '模板内容不能为空!'; $lang->user->profile = '档案'; $lang->user->project = $lang->projectCommon; @@ -111,6 +113,7 @@ $lang->user->loginFailed = "登录失败,请检查您的用户名或密码是 $lang->user->lockWarning = "您还有%s次尝试机会。"; $lang->user->loginLocked = "密码尝试次数太多,请联系管理员解锁,或%s分钟后重试。"; $lang->user->weakPassword = "您的密码强度小于系统设定。"; +$lang->user->errorWeak = "密码不能使用【%s】这些常用弱口令。"; $lang->user->roleList[''] = ''; $lang->user->roleList['dev'] = '研发'; @@ -169,6 +172,8 @@ $lang->user->error->realname = "【ID %s】的真实姓名必须填写"; $lang->user->error->password = "【ID %s】的密码必须为六位以上"; $lang->user->error->mail = "【ID %s】的邮箱地址不正确"; $lang->user->error->reserved = "【ID %s】的用户名已被系统预留"; +$lang->user->error->weakPassword = "【ID %s】的密码强度小于系统设定。"; +$lang->user->error->commonWeak = "【ID %s】的密码不能使用【%s】这些常用若口令。"; $lang->user->error->verifyPassword = "验证失败,请检查您的系统登录密码是否正确"; $lang->user->error->originalPassword = "原密码不正确"; diff --git a/module/user/lang/zh-tw.php b/module/user/lang/zh-tw.php index f51e5b105d..83d7b15301 100644 --- a/module/user/lang/zh-tw.php +++ b/module/user/lang/zh-tw.php @@ -46,8 +46,9 @@ $lang->user->ranzhi = '然之帳號'; $lang->user->ditto = '同上'; $lang->user->originalPassword = '原密碼'; $lang->user->newPassword = '新密碼'; -$lang->user->verifyPassword = '您的系統登錄密碼'; +$lang->user->verifyPassword = '您的密碼'; $lang->user->resetPassword = '忘記密碼'; +$lang->user->score = '分數'; $lang->user->legendBasic = '基本資料'; $lang->user->legendContribution = '個人貢獻'; @@ -81,6 +82,7 @@ $lang->user->setTemplateTitle = '請輸入模板標題'; $lang->user->applyTemplate = '應用模板'; $lang->user->confirmDeleteTemplate = '您確認要刪除該模板嗎?'; $lang->user->setPublicTemplate = '設為公共模板'; +$lang->user->tplContentNotEmpty = '模板內容不能為空!'; $lang->user->profile = '檔案'; $lang->user->project = $lang->projectCommon; diff --git a/module/user/model.php b/module/user/model.php index 069be4698e..40d737f1f9 100644 --- a/module/user/model.php +++ b/module/user/model.php @@ -220,12 +220,6 @@ class userModel extends model ->remove('group, password1, password2, verifyPassword') ->get(); - if(isset($this->config->safe->mode) and $this->computePasswordStrength($this->post->password1) < $this->config->safe->mode) - { - dao::$errors['password1'][] = $this->lang->user->weakPassword; - return false; - } - if(empty($_POST['verifyPassword']) or $this->post->verifyPassword != md5($this->app->user->password . $this->session->rand)) { dao::$errors['verifyPassword'][] = $this->lang->user->error->verifyPassword; @@ -276,17 +270,21 @@ class userModel extends model $users->account[$i] = trim($users->account[$i]); if($users->account[$i] != '') { - if(strtolower($users->account[$i]) == 'guest') die(js::error(sprintf($this->lang->user->error->reserved, $i+1))); + if(strtolower($users->account[$i]) == 'guest') die(js::error(sprintf($this->lang->user->error->reserved, $i + 1))); $account = $this->dao->select('account')->from(TABLE_USER)->where('account')->eq($users->account[$i])->fetch(); - if($account) die(js::error(sprintf($this->lang->user->error->accountDupl, $i+1))); - if(in_array($users->account[$i], $accounts)) die(js::error(sprintf($this->lang->user->error->accountDupl, $i+1))); - if(!validater::checkAccount($users->account[$i])) die(js::error(sprintf($this->lang->user->error->account, $i+1))); - if($users->realname[$i] == '') die(js::error(sprintf($this->lang->user->error->realname, $i+1))); - if($users->email[$i] and !validater::checkEmail($users->email[$i])) die(js::error(sprintf($this->lang->user->error->mail, $i+1))); + if($account) die(js::error(sprintf($this->lang->user->error->accountDupl, $i + 1))); + if(in_array($users->account[$i], $accounts)) die(js::error(sprintf($this->lang->user->error->accountDupl, $i + 1))); + if(!validater::checkAccount($users->account[$i])) die(js::error(sprintf($this->lang->user->error->account, $i + 1))); + if($users->realname[$i] == '') die(js::error(sprintf($this->lang->user->error->realname, $i + 1))); + if($users->email[$i] and !validater::checkEmail($users->email[$i])) die(js::error(sprintf($this->lang->user->error->mail, $i + 1))); $users->password[$i] = (isset($prev['password']) and $users->ditto[$i] == 'on' and empty($users->password[$i])) ? $prev['password'] : $users->password[$i]; - if(!validater::checkReg($users->password[$i], '|(.){6,}|')) die(js::error(sprintf($this->lang->user->error->password, $i+1))); + if(!validater::checkReg($users->password[$i], '|(.){6,}|')) die(js::error(sprintf($this->lang->user->error->password, $i + 1))); $role = $users->role[$i] == 'ditto' ? (isset($prev['role']) ? $prev['role'] : '') : $users->role[$i]; + /* Check weak and common weak password. */ + if(isset($this->config->safe->mode) and $this->computePasswordStrength($users->password[$i]) < $this->config->safe->mode) die(js::error(sprintf($this->lang->user->error->weakPassword, $i + 1))); + if(!empty($this->config->safe->changeWeak) and strpos(",{$this->config->safe->weak},", ",{$this->post->password1},") !== false) die(js::error(sprintf($this->lang->user->error->commonWeak, $i + 1, $this->config->safe->weak))); + $data[$i] = new stdclass(); $data[$i]->dept = $users->dept[$i] == 'ditto' ? (isset($prev['dept']) ? $prev['dept'] : 0) : $users->dept[$i]; $data[$i]->account = $users->account[$i]; @@ -377,12 +375,6 @@ class userModel extends model ->remove('password1, password2, groups,verifyPassword') ->get(); - if(isset($this->config->safe->mode) and isset($user->password) and $this->computePasswordStrength($this->post->password1) < $this->config->safe->mode) - { - dao::$errors['password1'][] = $this->lang->user->weakPassword; - return false; - } - if(empty($_POST['verifyPassword']) or $this->post->verifyPassword != md5($this->app->user->password . $this->session->rand)) { dao::$errors['verifyPassword'][] = $this->lang->user->error->verifyPassword; @@ -560,12 +552,6 @@ class userModel extends model ->remove('account, password1, password2, originalPassword') ->get(); - if(isset($this->config->safe->mode) and $this->computePasswordStrength($this->post->password1) < $this->config->safe->mode) - { - dao::$errors['password1'][] = $this->lang->user->weakPassword; - return false; - } - if(empty($_POST['originalPassword']) or md5($this->post->originalPassword) != $this->app->user->password) { dao::$errors['originalPassword'][] = $this->lang->user->error->originalPassword; @@ -595,12 +581,6 @@ class userModel extends model if(!$user) return false; $password = md5($this->post->password1); - if(isset($this->config->safe->mode) and $this->computePasswordStrength($this->post->password1) < $this->config->safe->mode) - { - dao::$errors['password1'][] = $this->lang->user->weakPassword; - return false; - } - $this->dao->update(TABLE_USER)->set('password')->eq($password)->autoCheck()->where('account')->eq($this->post->account)->exec(); return !dao::isError(); } @@ -620,6 +600,9 @@ class userModel extends model { if($this->post->password1 != $this->post->password2) dao::$errors['password'][] = $this->lang->error->passwordsame; if(!validater::checkReg($this->post->password1, '|(.){6,}|')) dao::$errors['password'][] = $this->lang->error->passwordrule; + + if(isset($this->config->safe->mode) and $this->computePasswordStrength($this->post->password1) < $this->config->safe->mode) dao::$errors['password1'][] = $this->lang->user->weakPassword; + if(!empty($this->config->safe->changeWeak) and strpos(",{$this->config->safe->weak},", ",{$this->post->password1},") !== false) dao::$errors['password1'][] = sprintf($this->lang->user->errorWeak, $this->config->safe->weak); } return !dao::isError(); } diff --git a/module/user/view/ajaxprinttemplates.html.php b/module/user/view/ajaxprinttemplates.html.php index 33eba63bea..c779460e82 100644 --- a/module/user/view/ajaxprinttemplates.html.php +++ b/module/user/view/ajaxprinttemplates.html.php @@ -102,7 +102,16 @@ function hideXIcon(templateID) $(function() { $('#saveTplModal').on('hide.zui.modal', function(){$(this).find('#title').val('');}); - $('#saveTplBtn').click(function(){$('#saveTplModal').modal('show');}); + $('#saveTplBtn').click(function() + { + var content = editor[''].html(); + if(!content) + { + bootAlert("user->tplContentNotEmpty ?>"); + return; + } + $('#saveTplModal').modal('show'); + }); $('#saveTplModal #templateSubmit').click(function() { var $inputGroup = $('#saveTplModal div.input-group'); diff --git a/module/user/view/batchcreate.html.php b/module/user/view/batchcreate.html.php index 877dedbe87..990e55b5cb 100644 --- a/module/user/view/batchcreate.html.php +++ b/module/user/view/batchcreate.html.php @@ -76,6 +76,7 @@
    "; if($i != 0) echo " 0 ? "checked" : '') . " /> {$lang->user->ditto}"; ?>
    @@ -116,4 +117,5 @@
    +user->passwordStrengthList)?> diff --git a/module/user/view/deny.html.php b/module/user/view/deny.html.php index 9154c56a6b..a2e6a035e9 100644 --- a/module/user/view/deny.html.php +++ b/module/user/view/deny.html.php @@ -32,6 +32,25 @@ include '../../common/view/header.lite.html.php'; $methodName = isset($tmpLang[$method]) ? $tmpLang[$method] : $method; } + /* set moduleName = caselib if method = caselibmethod. */ + $lowerMethod = strtolower($method); + if($module == 'testsuite') + { + $this->app->loadLang('group'); + $caselibMethods = array(); + foreach($lang->resource->caselib as $caselibMethod => $caselibMethodName) + { + $lowerCaselibMethod = strtolower($caselibMethod); + $caselibMethods[$lowerCaselibMethod] = $caselibMethodName; + } + + if(isset($caselibMethods[$lowerMethod]) && $lowerMethod != 'edit') + { + $this->app->loadLang('action'); + $moduleName = $lang->action->objectTypes['caselib']; + } + } + printf($lang->user->errorDeny, $moduleName, $methodName); ?>
    diff --git a/module/user/view/testcase.html.php b/module/user/view/testcase.html.php index 8932530a56..7648ef036b 100755 --- a/module/user/view/testcase.html.php +++ b/module/user/view/testcase.html.php @@ -54,8 +54,8 @@
    - - + + diff --git a/module/webhook/css/create.css b/module/webhook/css/create.css index 7d7140893c..3cc7643665 100644 --- a/module/webhook/css/create.css +++ b/module/webhook/css/create.css @@ -3,6 +3,3 @@ .objectType {margin-right: 5px !important;} #paramsTR th{padding-left:25px;} #paramsTR th label{font-weight:bold; padding-left:25px;} - -.thWidth{width:120px !important;} -html[lang^='zh-'] .thWidth{width:90px !important;} diff --git a/module/webhook/css/create.en.css b/module/webhook/css/create.en.css new file mode 100644 index 0000000000..62f3e6f10c --- /dev/null +++ b/module/webhook/css/create.en.css @@ -0,0 +1 @@ +.thWidth{width:120px !important;} diff --git a/module/webhook/css/create.zh-cn.css b/module/webhook/css/create.zh-cn.css new file mode 100644 index 0000000000..6e60376bc6 --- /dev/null +++ b/module/webhook/css/create.zh-cn.css @@ -0,0 +1 @@ +.thWidth{width:90px !important;} diff --git a/module/webhook/css/create.zh-tw.css b/module/webhook/css/create.zh-tw.css new file mode 100644 index 0000000000..6e60376bc6 --- /dev/null +++ b/module/webhook/css/create.zh-tw.css @@ -0,0 +1 @@ +.thWidth{width:90px !important;} diff --git a/module/webhook/css/edit.css b/module/webhook/css/edit.css index 7d7140893c..3cc7643665 100644 --- a/module/webhook/css/edit.css +++ b/module/webhook/css/edit.css @@ -3,6 +3,3 @@ .objectType {margin-right: 5px !important;} #paramsTR th{padding-left:25px;} #paramsTR th label{font-weight:bold; padding-left:25px;} - -.thWidth{width:120px !important;} -html[lang^='zh-'] .thWidth{width:90px !important;} diff --git a/module/webhook/css/edit.en.css b/module/webhook/css/edit.en.css new file mode 100644 index 0000000000..62f3e6f10c --- /dev/null +++ b/module/webhook/css/edit.en.css @@ -0,0 +1 @@ +.thWidth{width:120px !important;} diff --git a/module/webhook/css/edit.zh-cn.css b/module/webhook/css/edit.zh-cn.css new file mode 100644 index 0000000000..6e60376bc6 --- /dev/null +++ b/module/webhook/css/edit.zh-cn.css @@ -0,0 +1 @@ +.thWidth{width:90px !important;} diff --git a/module/webhook/css/edit.zh-tw.css b/module/webhook/css/edit.zh-tw.css new file mode 100644 index 0000000000..6e60376bc6 --- /dev/null +++ b/module/webhook/css/edit.zh-tw.css @@ -0,0 +1 @@ +.thWidth{width:90px !important;} diff --git a/www/js/my.full.js b/www/js/my.full.js index 3323ac1790..49c6a867c2 100644 --- a/www/js/my.full.js +++ b/www/js/my.full.js @@ -91,17 +91,39 @@ function setFormAction(actionLink, hiddenwin, obj) * @access public * @return void */ -function setImageSize(image, maxWidth) +function setImageSize(image, maxWidth, maxHeight) { + var $image = $(image); + if($image.parent().prop('tagName').toLowerCase() == 'a') return; + /* If not set maxWidth, set it auto. */ if(!maxWidth) { bodyWidth = $('body').width(); maxWidth = bodyWidth - 470; // The side bar's width is 336, and add some margins. } + if(!maxHeight) maxHeight = $(top.window).height(); - if($(image).width() > maxWidth) $(image).attr('width', maxWidth); - $(image).wrap(''); + setTimeout(function() + { + maxHeightStyle = $image.height() > 0 ? 'max-height:' + maxHeight + 'px' : ''; + if($image.width() > 0 && $image.width() > maxWidth) $image.attr('width', maxWidth); + $image.wrap(''); + if($image.height() > 0 && $image.height() > maxHeight) $image.closest('a').append("" + lang.expand + " "); + }, 50); +} + +/** + * Show more image when image is too height. + * + * @param obj $obj + * @access public + * @return void + */ +function showMoreImage(obj) +{ + $(obj).parents('a').css('max-height', 'none'); + $(obj).remove(); } /** @@ -734,10 +756,10 @@ function convertURL() $('.article-content, .article>.content').each(function() { - var aTags = []; + var aTags = []; var iframeTags = []; - var imgTags = []; - var content = $(this).html(); + var imgTags = []; + var content = $(this).html(); $(this).find('a').each(function(i) { aTags[i] = $(this).prop('outerHTML'); diff --git a/www/theme/default/style.css b/www/theme/default/style.css index f9ddf54bad..8beaab96c0 100644 --- a/www/theme/default/style.css +++ b/www/theme/default/style.css @@ -24,6 +24,9 @@ #dropMenu.show-right-col .col-right>.list-group{width:250px;max-width:260px;} #dropMenu .col-footer{width:230px;} +.main-actions .btn-toolbar .divider {margin-right:8px !important; margin-left: 8px !important;} +.main-actions .btn-toolbar .btn + .btn {margin-left: 8px !important;} + /* Pager v-align. */ .pager>li>.pager-label { padding: 2px; line-height: 21px; } @@ -33,3 +36,17 @@ .modal-title{font-size: 14px;} .fixed-footer .text {color: #fff;} + +a.showMoreImage { +display: block; +height: 30px; +line-height: 30px; +background: #888; +position: absolute; +bottom: 0px; +width: 100%; +opacity: 0.7; +text-align: center; +color:red; +} +a.showMoreImage:hover{opacity: 1;} diff --git a/www/upgrade.php.tmp b/www/upgrade.php.tmp index 609ed1c84b..13abaab89e 100644 --- a/www/upgrade.php.tmp +++ b/www/upgrade.php.tmp @@ -12,9 +12,9 @@ /* Judge my.php exists or not. */ define('IN_UPGRADE', true); $dbConfig = dirname(dirname(__FILE__)) . '/config/db.php'; +$myConfig = dirname(dirname(__FILE__)) . '/config/my.php'; if(file_exists($dbConfig)) { - $myConfig = dirname(dirname(__FILE__)) . '/config/my.php'; if(file_exists($myConfig)) { $myContent = trim(file_get_contents($myConfig)); @@ -35,6 +35,7 @@ if(file_exists($dbConfig)) file_put_contents($myConfig, $myContent); } } +if(!file_exists($myConfig)) die(header('location: install.php')); error_reporting(0); diff --git a/xuanxuan/module/chat/ext/model/class/xuanxuan.class.php b/xuanxuan/module/chat/ext/model/class/xuanxuan.class.php index 1392498605..728e0799a5 100644 --- a/xuanxuan/module/chat/ext/model/class/xuanxuan.class.php +++ b/xuanxuan/module/chat/ext/model/class/xuanxuan.class.php @@ -92,7 +92,7 @@ class xuanxuanChat extends chatModel $position = strrpos($host, ':'); $port = $position === false ? '' : substr($host, $position + 1); $server = $this->config->xuanxuan->server; - if($port and strpos($server, ":$port") === false) + if($port and strpos($server, ":") === false) { $server = rtrim($server, '/'); $server = "{$server}:{$port}";
    testtask->status;?>
    comment;?> testcase->priList, $case->pri, $case->pri)?>'>testcase->priList, $case->pri, $case->pri)?> createLink('testcase', 'view', "testcaseID=$caseID&version=$case->version"), $case->title);?> testcase->typeList[$case->type];?>openedBy];?>lastRunner];?>openedBy);?>lastRunner);?> lastRunDate)) echo date(DT_MONTHTIME1, strtotime($case->lastRunDate));?> lastRunResult) echo $lang->testcase->resultList[$case->lastRunResult];?> processStatus('testcase', $case);?>