diff --git a/VERSION b/VERSION index 9a7c1e503f..ab67491a00 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -20.0 +20.0.beta2 diff --git a/config/config.php b/config/config.php index 594c0ce8d8..e896ed64a2 100644 --- a/config/config.php +++ b/config/config.php @@ -16,7 +16,7 @@ if(!class_exists('config')){class config{}} if(!function_exists('getWebRoot')){function getWebRoot(){}} /* 基本设置。Basic settings. */ -$config->version = '20.0'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it. +$config->version = '20.0.beta2'; // ZenTaoPHP的版本。 The version of ZenTaoPHP. Don't change it. $config->liteVersion = '1.2'; // 迅捷版版本。 The version of Lite. $config->charset = 'UTF-8'; // ZenTaoPHP的编码。 The encoding of ZenTaoPHP. $config->cookieLife = time() + 2592000; // Cookie的生存时间。The cookie life time. diff --git a/doc/CHANGELOG b/doc/CHANGELOG index 866286c2ac..5608531451 100644 --- a/doc/CHANGELOG +++ b/doc/CHANGELOG @@ -1,4 +1,4 @@ -2024-02-29 20.0 +2024-02-29 20.0.beta2 2024-02-20 18.11 完成的需求 diff --git a/extension/lite/story/ext/ui/batchcreate.html.php b/extension/lite/story/ext/ui/batchcreate.html.php index 7e2fa4be51..7d4202fdd7 100644 --- a/extension/lite/story/ext/ui/batchcreate.html.php +++ b/extension/lite/story/ext/ui/batchcreate.html.php @@ -21,13 +21,13 @@ foreach($fields as $fieldKey => $fieldConfig) } /* Generate fields for the batch create form. */ -$fnGenerateFields = function() use ($lang, $fields) +$fnGenerateFields = function() use ($lang, $fields, $config) { /* Generate fields with the appropriate properties. */ $items = array(); $items[] = array('name' => 'id', 'label' => $lang->idAB, 'control' => 'index', 'width' => '32px'); - return array_merge($items, array_map(function($name, $field) + $cols = array_merge($items, array_map(function($name, $field) { $field['name'] = $name; if(!empty($field['options'])) $field['items'] = $field['options']; @@ -37,6 +37,14 @@ $fnGenerateFields = function() use ($lang, $fields) return $field; }, array_keys($fields), array_values($fields))); + + foreach($cols as $index => $col) + { + $colName = $col['name']; + if(str_contains(",{$config->story->create->requiredFields},", ",{$colName},")) $cols[$index]['required'] = true; + } + + return $cols; }; formBatchPanel diff --git a/lib/form/form.class.php b/lib/form/form.class.php index 2d14675daa..4adecd1a5a 100644 --- a/lib/form/form.class.php +++ b/lib/form/form.class.php @@ -171,8 +171,8 @@ class form extends fixer { global $app; - $rowDataList = array(); - $baseField = ''; + $rowDataList = array(); + $baseField = ''; foreach($fieldConfigs as $field => $config) { @@ -214,7 +214,7 @@ class form extends fixer if(isset($config['filter'])) $rowData->$field = $this->filter($rowData->$field, $config['filter']); /* 检查必填字段。Check required fields. */ - if(isset($config['required']) && $config['required'] && $this->checkEmpty($rowData->$field)) + if(isset($config['required']) && $config['required'] && empty($rowData->$field)) { $errorKey = isset($config['type']) && $config['type'] == 'array' ? "{$field}[{$rowIndex}][]" : "{$field}[{$rowIndex}]"; $fieldName = isset($app->lang->{$app->rawModule}->$field) ? $app->lang->{$app->rawModule}->$field : $field; @@ -229,21 +229,6 @@ class form extends fixer $this->dataList = $rowDataList; } - /** - * 检查为空。 - * Empty checking. - * - * @param mixed $data - * @return bool - */ - public function checkEmpty(mixed $data): bool - { - if(is_array($data)) return empty($data); - - $data = (string)$data; - return empty(strlen($data)); - } - /** * 获取$_POST的数据。 * Get the data of $_POST. @@ -283,7 +268,7 @@ class form extends fixer if(isset($config['filter'])) $data = $this->filter($data, $config['filter']); - if(isset($config['required']) && $config['required'] && isset($data) && $this->checkEmpty($data)) + if(isset($config['required']) && $config['required'] && empty($data)) { $errorKey = isset($config['type']) && $config['type'] == 'array' ? "{$field}[]" : $field; $fieldName = isset($app->lang->{$app->rawModule}->$field) ? $app->lang->{$app->rawModule}->$field : $field; diff --git a/lib/zin/wg/backbtn/v1.php b/lib/zin/wg/backbtn/v1.php index f2ac1be29f..1209e309cc 100644 --- a/lib/zin/wg/backbtn/v1.php +++ b/lib/zin/wg/backbtn/v1.php @@ -49,7 +49,7 @@ class backBtn extends btn 'testcase' => 'testcase-browse,project-testcase,my-work,my-contribute,execution-testcase,testtask-cases,testsuite-view,product-browse,testcase-view,qa-index,caselib-browse,product-track', 'testsuite' => 'testsuite-browse,testsuite-view,', 'testtask' => 'testtask-browse,testtask-cases,qa-index,testcase-browse,', - 'testreport' => 'testreport-browse,project-testreport,execution-testreport,', + 'testreport' => 'testreport-browse,project-testreport,execution-testreport,execution-testtask', 'tree' => 'product-browse,project-browse,execution-task,bug-browse,projectstory-story,host-browse,execution-story,feedback-admin,', 'doc' => 'doc-mySpace,doc-productSpace,doc-projectSpace,doc-teamSpace,doc-view,execution-doc', 'design' => 'design-browse', diff --git a/lib/zin/wg/input/v1.php b/lib/zin/wg/input/v1.php index a222c79d2c..720b616b01 100644 --- a/lib/zin/wg/input/v1.php +++ b/lib/zin/wg/input/v1.php @@ -14,7 +14,8 @@ class input extends wg 'placeholder?: string', 'autofocus?: bool', 'autocomplete?: bool=false', - 'disabled?: bool' + 'disabled?: bool', + 'min?: int' /* type为number时设置min */ ); protected static array $defaultProps = array diff --git a/lib/zin/wg/pastedialog/js/v1.js b/lib/zin/wg/pastedialog/js/v1.js index 0bfa1a4a2a..20362c5345 100644 --- a/lib/zin/wg/pastedialog/js/v1.js +++ b/lib/zin/wg/pastedialog/js/v1.js @@ -1,4 +1,4 @@ -function importLines(target, field) +window.importLines = function(target, field) { const $modal = $(target).closest('.modal'); const $dialog = $modal.find('.modal-dialog'); diff --git a/lib/zin/wg/pastedialog/v1.php b/lib/zin/wg/pastedialog/v1.php index 78264ceb4f..375e47b187 100644 --- a/lib/zin/wg/pastedialog/v1.php +++ b/lib/zin/wg/pastedialog/v1.php @@ -40,7 +40,7 @@ class pasteDialog extends wg btn ( setClass('btn btn-wide primary'), - on::click("importLines(target, '$field')"), + on::click("window.importLines(target, '$field')"), $lang->save ) ) diff --git a/module/bug/config/table.php b/module/bug/config/table.php index 65ff037673..ee22eea79e 100644 --- a/module/bug/config/table.php +++ b/module/bug/config/table.php @@ -73,6 +73,7 @@ $config->bug->dtable->fieldList['plan']['title'] = $lang->bug->plan; $config->bug->dtable->fieldList['plan']['width'] = 120; $config->bug->dtable->fieldList['plan']['group'] = 3; $config->bug->dtable->fieldList['plan']['sortType'] = true; +$config->bug->dtable->fieldList['plan']['hint'] = true; $config->bug->dtable->fieldList['openedBuild']['title'] = $lang->bug->openedBuild; $config->bug->dtable->fieldList['openedBuild']['type'] = 'text'; diff --git a/module/bug/ui/browse.html.php b/module/bug/ui/browse.html.php index 2ef92a1602..b104081d35 100644 --- a/module/bug/ui/browse.html.php +++ b/module/bug/ui/browse.html.php @@ -172,7 +172,7 @@ if($canBatchAction) } $cols = $this->loadModel('datatable')->getSetting('bug'); -if(isset($cols['branch'])) $cols['branch']['map'] = array('') + $branchTagOption; +if(isset($cols['branch'])) $cols['branch']['map'] = array(BRANCH_MAIN => $lang->trunk) + $branchTagOption; if(isset($cols['project'])) $cols['project']['map'] = array('') + $projectPairs; if(isset($cols['execution'])) $cols['execution']['map'] = array('') + $executions; if(isset($cols['plan'])) $cols['plan']['map'] = array('') + $plans; diff --git a/module/custom/css/required.ui.css b/module/custom/css/required.ui.css deleted file mode 100644 index 1031aac645..0000000000 --- a/module/custom/css/required.ui.css +++ /dev/null @@ -1,2 +0,0 @@ -#requiredForm .form-group {padding-left: 8rem;} -#requiredForm .form-group .form-label {width: 8rem;} diff --git a/module/custom/ui/required.html.php b/module/custom/ui/required.html.php index a04caa9b79..5331ebd410 100644 --- a/module/custom/ui/required.html.php +++ b/module/custom/ui/required.html.php @@ -25,7 +25,9 @@ foreach($requiredFields as $method => $requiredField) ( set::width('1/2'), set::label($actionTitle . $lang->custom->page), + set::labelProps(array('title' => $actionTitle . $lang->custom->page)), set::labelClass('font-bold'), + set::labelWidth('8rem'), picker ( set::name("requiredFields[{$method}][]"), diff --git a/module/datatable/model.php b/module/datatable/model.php index 7a8827da75..d306426879 100644 --- a/module/datatable/model.php +++ b/module/datatable/model.php @@ -116,15 +116,13 @@ class datatableModel extends model { foreach($fieldSetting as $field => $set) { - if(isset($fieldList[$field])) + if(!$showAll && empty($set['required']) && empty($set['show'])) { - foreach($fieldList[$field] as $key => $value) - { - if(!isset($set[$key])) $fieldSetting[$field][$key] = $value; - } + unset($fieldSetting[$field]); + continue; } - if(!$showAll && empty($set['required']) && empty($set['show'])) + if(isset($set['display']) && $set['display'] === false) { unset($fieldSetting[$field]); continue; @@ -136,11 +134,20 @@ class datatableModel extends model continue; } + if(isset($fieldList[$field])) + { + foreach($fieldList[$field] as $key => $value) + { + if(!isset($set[$key])) $fieldSetting[$field][$key] = $value; + } + } + if(!isset($set['name'])) $fieldSetting[$field]['name'] = $field; if($module == 'testcase' && $field == 'id') $fieldSetting[$field]['name'] = 'caseID'; if($field == 'actions' && empty($fieldSetting[$field]['width'])) $fieldSetting[$field]['width'] = $fieldList[$field]['width']; - if(in_array($module, array('product', 'project', 'execution')) and empty($this->config->setCode)) unset($fieldSetting['code']); } + + if(in_array($module, array('product', 'project', 'execution')) and empty($this->config->setCode)) unset($fieldSetting['code']); } uasort($fieldSetting, array('datatableModel', 'sortCols')); @@ -260,7 +267,7 @@ class datatableModel extends model usort($setting, array('datatableModel', 'sortOldCols')); - return $setting; + return $fieldSetting; } /** diff --git a/module/dev/control.php b/module/dev/control.php index 2f7b9d5f6d..0dd891c2fc 100644 --- a/module/dev/control.php +++ b/module/dev/control.php @@ -200,10 +200,11 @@ class dev extends control if($oldValue) { $oldValue = json_decode($oldValue); - $_POST = array(); - $_POST['SRName'] = zget($oldValue, 'defaultSRName', $oldValue->SRName); - $_POST['URName'] = zget($oldValue, 'defaultURName', $oldValue->URName); - $this->custom->updateURAndSR($this->config->custom->URSR, $language); + $setting = array( + 'SRName' => zget($oldValue, 'defaultSRName', $oldValue->SRName), + 'URName' => zget($oldValue, 'defaultURName', $oldValue->URName) + ); + $this->custom->updateURAndSR($this->config->custom->URSR, $language, $setting); } } diff --git a/module/dev/model.php b/module/dev/model.php index 09712e5266..7f1d424dbd 100644 --- a/module/dev/model.php +++ b/module/dev/model.php @@ -1034,9 +1034,6 @@ class devModel extends model if($type == 'common' and $this->config->custom->URSR) { - $post = $_POST; - $_POST = array(); - $oldValue = $this->dao->select('*')->from(TABLE_LANG)->where('`key`')->eq($this->config->custom->URSR)->andWhere('section')->eq('URSRList')->andWhere('lang')->eq($language)->andWhere('module')->eq('custom')->fetch('value'); $URSRList = $this->loadModel('custom')->getItems("lang={$language}&module=custom§ion=URSRList&key={$this->config->custom->URSR}&vision={$this->config->vision}"); if(empty($URSRList)) $URSRList = $this->custom->getItems("lang={$language}&module=custom§ion=URSRList&vision={$this->config->vision}"); @@ -1045,11 +1042,11 @@ class devModel extends model $this->config->custom->URSR = $URSRList->key; $oldValue = json_decode($URSRList->value); - $_POST['SRName'] = !empty($post['common_SRCommon']) ? $post['common_SRCommon'] : zget($oldValue, 'defaultSRName', $oldValue->SRName); - $_POST['URName'] = !empty($post['common_URCommon']) ? $post['common_URCommon'] : zget($oldValue, 'defaultURName', $oldValue->URName); - $this->custom->updateURAndSR($this->config->custom->URSR, $language); - - $_POST = $post; + $setting = array( + 'SRName' => $this->post->common_SRCommon !== false ? $this->post->common_SRCommon : zget($oldValue, 'defaultSRName', $oldValue->SRName), + 'URName' => $this->post->common_URCommon !== false ? $this->post->common_URCommon : zget($oldValue, 'defaultURName', $oldValue->URName) + ); + $this->custom->updateURAndSR($this->config->custom->URSR, $language, $setting); } } diff --git a/module/doc/css/showfiles.ui.css b/module/doc/css/showfiles.ui.css index cc4cc72c82..df7ba8aa40 100644 --- a/module/doc/css/showfiles.ui.css +++ b/module/doc/css/showfiles.ui.css @@ -2,5 +2,6 @@ .actions-menu .searchBox {width: 120px;} .actions-menu .searchBox .input-control-suffix {padding-right: 0;} .actions-menu .btn-group .switchBtn {padding: 6px 10px;} +#table-doc-showfiles [data-type='title'] .dtable-cell-html {display: flex; align-items: center;} #table-doc-showfiles [data-type='title'] .dtable-cell-html img {max-height: 36px;} -#table-doc-showfiles [data-type='title'] .file-name {vertical-align: text-bottom;} +#table-doc-showfiles [data-type='title'] .file-name {display: flex; justify-content: center; align-items: center;} diff --git a/module/execution/ui/ajaxgetcopyprojectexecutions.html.php b/module/execution/ui/ajaxgetcopyprojectexecutions.html.php index 41f3b4eee6..8e4846a267 100644 --- a/module/execution/ui/ajaxgetcopyprojectexecutions.html.php +++ b/module/execution/ui/ajaxgetcopyprojectexecutions.html.php @@ -42,7 +42,7 @@ else setClass('text-gray'), $lang->icons[$execution->type] ), - span($execution->name) + span(setClass('text-left'), $execution->name) ); } } diff --git a/module/file/control.php b/module/file/control.php index 383279f131..c700e48b55 100755 --- a/module/file/control.php +++ b/module/file/control.php @@ -32,6 +32,16 @@ class file extends control $this->display(); } + public function buildOldForm(int $fileCount = 1, float $percent = 0.9, string $filesName = "files", string $labelsName = "labels") + { + if(!file_exists($this->file->savePath)) return printf($this->lang->file->errorNotExists, $this->file->savePath); + if(!is_writable($this->file->savePath)) return printf($this->lang->file->errorCanNotWrite, $this->file->savePath, $this->file->savePath); + + $this->view->filesName = $filesName; + $this->view->labelsName = $labelsName; + $this->display(); + } + /** * Build the old upload form. * diff --git a/module/install/css/step5.ui.en.css b/module/install/css/step5.ui.en.css new file mode 100644 index 0000000000..90e65ae44b --- /dev/null +++ b/module/install/css/step5.ui.en.css @@ -0,0 +1 @@ +.form {--form-horz-label-width: 7rem;} diff --git a/module/kanban/ui/setwip.html.php b/module/kanban/ui/setwip.html.php index 9cbe3034e5..a2faabafc2 100644 --- a/module/kanban/ui/setwip.html.php +++ b/module/kanban/ui/setwip.html.php @@ -38,7 +38,7 @@ formPanel set::label($lang->kanban->WIPCount), inputGroup ( - input(set::name('limit'), set::disabled($column->limit == -1), set::value($column->limit != -1 ? $column->limit : '')), + input(set::name('limit'), set::type('number'), set::min(1), set::disabled($column->limit == -1), set::value($column->limit != -1 ? $column->limit : '')), span ( set('class', 'input-group-addon'), diff --git a/module/misc/lang/de.php b/module/misc/lang/de.php index e0947229cc..571b87c698 100644 --- a/module/misc/lang/de.php +++ b/module/misc/lang/de.php @@ -113,7 +113,7 @@ $lang->misc->feature->promptExecImage = 'theme/default/images/main/prompt_exec $lang->misc->feature->promptLearnMore = 'https://www.zentao.net/book/zentaopms/1097.html'; /* Release Date. */ -$lang->misc->releaseDate['20.0'] = '2024-02-29'; +$lang->misc->releaseDate['20.0.beta2'] = '2024-03-07'; $lang->misc->releaseDate['18.11'] = '2024-02-28'; $lang->misc->releaseDate['18.10.1'] = '2024-01-17'; $lang->misc->releaseDate['20.0.beta1'] = '2024-01-26'; @@ -173,7 +173,7 @@ $lang->misc->releaseDate['12.5.3'] = '2021-01-06'; $lang->misc->releaseDate['12.5.2'] = '2020-12-18'; $lang->misc->releaseDate['12.5.1'] = '2020-11-30'; $lang->misc->releaseDate['12.5.stable'] = '2020-11-19'; -$lang->misc->releaseDate['20.0.alpha1'] = '2020-10-30'; +// $lang->misc->releaseDate['20.0.alpha1'] = '2020-10-30'; $lang->misc->releaseDate['12.4.4'] = '2020-10-30'; $lang->misc->releaseDate['12.4.3'] = '2020-10-13'; $lang->misc->releaseDate['12.4.2'] = '2020-09-18'; @@ -224,7 +224,7 @@ $lang->misc->releaseDate['7.1.stable'] = '2015-03-07'; $lang->misc->releaseDate['6.3.stable'] = '2014-11-07'; /* Release Detail. */ -$lang->misc->feature->all['20.0'][] = array('title' => '', 'desc' => ''); +$lang->misc->feature->all['20.0.beta2'][] = array('title' => '', 'desc' => ''); $lang->misc->feature->all['18.11'][] = array('title' => "We have successfully implemented AI mini-program functionality, integrating measurement metrics and global filtering capabilities into the large-screen display. Additionally, we have added feedback functionality to the OR interface. Furthermore, we have enabled the inclusion of keywords in the Requirement Management Hub, allowing for the redistribution of requirements in the Requirement Management Hub once a user's requirement has been withdrawn.", 'desc' => ''); $lang->misc->feature->all['18.10.1'][] = array('title' => 'The Requirement Management Hub (RM Hub) now includes notification functionality, supports product line features, and allows for distributing a single requirement to multiple products.', 'desc' => ''); $lang->misc->feature->all['20.0.beta1'][] = array('title' => 'This release mainly involves a large-scale refactoring of the code and a brand new upgrade to the user interface (UI), bringing better product performance, stronger security, and a more user-friendly experience.', 'desc' => ''); diff --git a/module/misc/lang/en.php b/module/misc/lang/en.php index 6df78b9a6c..ce5e11e1fc 100644 --- a/module/misc/lang/en.php +++ b/module/misc/lang/en.php @@ -113,7 +113,7 @@ $lang->misc->feature->promptExecImage = 'theme/default/images/main/prompt_exec $lang->misc->feature->promptLearnMore = 'https://www.zentao.net/book/zentaopms/1097.html'; /* Release Date. */ -$lang->misc->releaseDate['20.0'] = '2024-02-29'; +$lang->misc->releaseDate['20.0.beta2'] = '2024-03-07'; $lang->misc->releaseDate['18.11'] = '2024-02-28'; $lang->misc->releaseDate['18.10.1'] = '2024-01-17'; $lang->misc->releaseDate['20.0.beta1'] = '2024-01-26'; @@ -173,7 +173,7 @@ $lang->misc->releaseDate['12.5.3'] = '2021-01-06'; $lang->misc->releaseDate['12.5.2'] = '2020-12-18'; $lang->misc->releaseDate['12.5.1'] = '2020-11-30'; $lang->misc->releaseDate['12.5.stable'] = '2020-11-19'; -$lang->misc->releaseDate['20.0.alpha1'] = '2020-10-30'; +// $lang->misc->releaseDate['20.0.alpha1'] = '2020-10-30'; $lang->misc->releaseDate['12.4.4'] = '2020-10-30'; $lang->misc->releaseDate['12.4.3'] = '2020-10-13'; $lang->misc->releaseDate['12.4.2'] = '2020-09-18'; @@ -224,7 +224,7 @@ $lang->misc->releaseDate['7.1.stable'] = '2015-03-07'; $lang->misc->releaseDate['6.3.stable'] = '2014-11-07'; /* Release Detail. */ -$lang->misc->feature->all['20.0'][] = array('title' => '', 'desc' => ''); +$lang->misc->feature->all['20.0.beta2'][] = array('title' => '', 'desc' => ''); $lang->misc->feature->all['18.11'][] = array('title' => "We have successfully implemented AI mini-program functionality, integrating measurement metrics and global filtering capabilities into the large-screen display. Additionally, we have added feedback functionality to the OR interface. Furthermore, we have enabled the inclusion of keywords in the Requirement Management Hub, allowing for the redistribution of requirements in the Requirement Management Hub once a user's requirement has been withdrawn.", 'desc' => ''); $lang->misc->feature->all['18.10.1'][] = array('title' => 'The Requirement Management Hub (RM Hub) now includes notification functionality, supports product line features, and allows for distributing a single requirement to multiple products.', 'desc' => ''); $lang->misc->feature->all['20.0.beta1'][] = array('title' => 'This release mainly involves a large-scale refactoring of the code and a brand new upgrade to the user interface (UI), bringing better product performance, stronger security, and a more user-friendly experience.', 'desc' => ''); diff --git a/module/misc/lang/fr.php b/module/misc/lang/fr.php index a945f3d277..9e99f3f665 100644 --- a/module/misc/lang/fr.php +++ b/module/misc/lang/fr.php @@ -113,7 +113,7 @@ $lang->misc->feature->promptExecImage = 'theme/default/images/main/prompt_exec $lang->misc->feature->promptLearnMore = 'https://www.zentao.net/book/zentaopms/1097.html'; /* Release Date. */ -$lang->misc->releaseDate['20.0'] = '2024-02-29'; +$lang->misc->releaseDate['20.0.beta2'] = '2024-03-07'; $lang->misc->releaseDate['18.11'] = '2024-02-28'; $lang->misc->releaseDate['18.10.1'] = '2024-01-17'; $lang->misc->releaseDate['20.0.beta1'] = '2024-01-26'; @@ -173,7 +173,7 @@ $lang->misc->releaseDate['12.5.3'] = '2021-01-06'; $lang->misc->releaseDate['12.5.2'] = '2020-12-18'; $lang->misc->releaseDate['12.5.1'] = '2020-11-30'; $lang->misc->releaseDate['12.5.stable'] = '2020-11-19'; -$lang->misc->releaseDate['20.0.alpha1'] = '2020-10-30'; +// $lang->misc->releaseDate['20.0.alpha1'] = '2020-10-30'; $lang->misc->releaseDate['12.4.4'] = '2020-10-30'; $lang->misc->releaseDate['12.4.3'] = '2020-10-13'; $lang->misc->releaseDate['12.4.2'] = '2020-09-18'; @@ -224,7 +224,7 @@ $lang->misc->releaseDate['7.1.stable'] = '2015-03-07'; $lang->misc->releaseDate['6.3.stable'] = '2014-11-07'; /* Release Detail. */ -$lang->misc->feature->all['20.0'][] = array('title' => '', 'desc' => ''); +$lang->misc->feature->all['20.0.beta2'][] = array('title' => '', 'desc' => ''); $lang->misc->feature->all['18.11'][] = array('title' => "We have successfully implemented AI mini-program functionality, integrating measurement metrics and global filtering capabilities into the large-screen display. Additionally, we have added feedback functionality to the OR interface. Furthermore, we have enabled the inclusion of keywords in the Requirement Management Hub, allowing for the redistribution of requirements in the Requirement Management Hub once a user's requirement has been withdrawn.", 'desc' => ''); $lang->misc->feature->all['18.10.1'][] = array('title' => 'The Requirement Management Hub (RM Hub) now includes notification functionality, supports product line features, and allows for distributing a single requirement to multiple products.', 'desc' => ''); $lang->misc->feature->all['20.0.beta1'][] = array('title' => 'This release mainly involves a large-scale refactoring of the code and a brand new upgrade to the user interface (UI), bringing better product performance, stronger security, and a more user-friendly experience.', 'desc' => ''); diff --git a/module/misc/lang/zh-cn.php b/module/misc/lang/zh-cn.php index 98190cc1fd..b1a34ea060 100644 --- a/module/misc/lang/zh-cn.php +++ b/module/misc/lang/zh-cn.php @@ -113,7 +113,7 @@ $lang->misc->feature->promptExecImage = 'theme/default/images/main/prompt_exec $lang->misc->feature->promptLearnMore = 'https://www.zentao.net/book/zentaopms/1097.html'; /* Release Date. */ -$lang->misc->releaseDate['20.0'] = '2024-02-29'; +$lang->misc->releaseDate['20.0.beta2'] = '2024-03-07'; $lang->misc->releaseDate['18.11'] = '2024-02-28'; $lang->misc->releaseDate['18.10.1'] = '2024-01-17'; $lang->misc->releaseDate['20.0.beta1'] = '2024-01-26'; @@ -173,7 +173,7 @@ $lang->misc->releaseDate['12.5.3'] = '2021-01-06'; $lang->misc->releaseDate['12.5.2'] = '2020-12-18'; $lang->misc->releaseDate['12.5.1'] = '2020-11-30'; $lang->misc->releaseDate['12.5.stable'] = '2020-11-19'; -$lang->misc->releaseDate['20.0.alpha1'] = '2020-10-30'; +// $lang->misc->releaseDate['20.0.alpha1'] = '2020-10-30'; $lang->misc->releaseDate['12.4.4'] = '2020-10-30'; $lang->misc->releaseDate['12.4.3'] = '2020-10-13'; $lang->misc->releaseDate['12.4.2'] = '2020-09-18'; @@ -224,7 +224,7 @@ $lang->misc->releaseDate['7.1.stable'] = '2015-03-07'; $lang->misc->releaseDate['6.3.stable'] = '2014-11-07'; /* Release Detail. */ -$lang->misc->feature->all['20.0'][] = array('title' => '', 'desc' => ''); +$lang->misc->feature->all['20.0.beta2'][] = array('title' => '', 'desc' => ''); $lang->misc->feature->all['18.11'][] = array('title' => '实现AI小程序功能,实现大屏引用度量项、全局筛选器功能,OR界面实现反馈功能,需求池需求增加关键词,撤回用户需求后需求池需求可以再次分发。', 'desc' => ''); $lang->misc->feature->all['18.10.1'][] = array('title' => '需求池增加通知功能,支持产品线功能,支持一个需求分发到多个产品。', 'desc' => ''); $lang->misc->feature->all['20.0.beta1'][] = array('title' => '本次发布主要对代码进行了大规模重构,同时对用户界面(UI)进行了全新升级,带来了更好的产品性能、更强的安全性和更友好的用户体验。', 'desc' => ''); diff --git a/module/mr/control.php b/module/mr/control.php index dc1e5aabdb..2bfc5299d1 100644 --- a/module/mr/control.php +++ b/module/mr/control.php @@ -550,6 +550,7 @@ class mr extends control $this->view->title = $this->lang->mr->common . $this->lang->colon . $this->lang->mr->link; $this->view->MR = $MR; + $this->view->repoID = $MR->repoID; $this->view->users = $this->loadModel('user')->getPairs('noletter'); $this->view->stories = $stories; $this->view->bugs = $bugs; diff --git a/module/mr/js/link.ui.js b/module/mr/js/link.ui.js index 44c152fc6a..c8d70395dc 100644 --- a/module/mr/js/link.ui.js +++ b/module/mr/js/link.ui.js @@ -39,3 +39,9 @@ window.showLink = function(obj) const link = $tabContent.find('.link').data('url'); $tabContent.load(link); }; + +window.onSearchLinks = function(type, result) +{ + loadTarget(result.load, type, {partial: true}) + return false; +}; diff --git a/module/mr/ui/linkbug.html.php b/module/mr/ui/linkbug.html.php index 110829f33b..358c5a2b35 100644 --- a/module/mr/ui/linkbug.html.php +++ b/module/mr/ui/linkbug.html.php @@ -32,7 +32,9 @@ searchForm ( set::module('bug'), set::simple(true), - set::show(true) + set::show(true), + set::extraHeight('+144') + set::onSearch(jsRaw("window.onSearchLinks.bind(null, 'mr-bug')")) ); div @@ -46,7 +48,7 @@ div ) ); $cols = array(); -foreach($config->release->dtable->defaultFields['linkBug'] as $field) $cols[$field] = zget($config->bug->dtable->fieldList, $field, array()); +foreach($config->release->dtable->defaultFields['linkBug']['bug'] as $field) $cols[$field] = zget($config->bug->dtable->fieldList, $field, array()); $data = array_values($allBugs); $cols['title']['data-toggle'] = ''; $cols['title']['link'] = array('module' => 'bug', 'method' => 'view', 'params' => 'bugID={id}', 'target' => '_blank'); diff --git a/module/mr/ui/linkstory.html.php b/module/mr/ui/linkstory.html.php index 4e8b6a686d..caf25ea95f 100644 --- a/module/mr/ui/linkstory.html.php +++ b/module/mr/ui/linkstory.html.php @@ -31,7 +31,9 @@ searchForm ( set::module('story'), set::simple(true), - set::show(true) + set::show(true), + set::extraHeight('+144') + set::onSearch(jsRaw("window.onSearchLinks.bind(null, 'mr-story')")) ); div diff --git a/module/mr/ui/linktask.html.php b/module/mr/ui/linktask.html.php index f666413176..1896c2ee82 100644 --- a/module/mr/ui/linktask.html.php +++ b/module/mr/ui/linktask.html.php @@ -31,7 +31,9 @@ searchForm ( set::module('task'), set::simple(true), - set::show(true) + set::show(true), + set::extraHeight('+144') + set::onSearch(jsRaw("window.onSearchLinks.bind(null, 'mr-task')")) ); div diff --git a/module/mr/zen.php b/module/mr/zen.php index 20a7fdfda1..0dcc7b1e09 100644 --- a/module/mr/zen.php +++ b/module/mr/zen.php @@ -182,7 +182,7 @@ class mrZen extends mr { $modules = $this->loadModel('tree')->getOptionMenu($product->id, 'task'); - $this->config->execution->search['actionURL'] = $this->createLink('mr', 'linkTask', "MRID={$MRID}&product->id={$product->id}&browseType=bySearch¶m=myQueryID&orderBy={$orderBy}"); + $this->config->execution->search['actionURL'] = $this->createLink('mr', 'linkTask', "MRID={$MRID}&productID={$product->id}&browseType=bySearch¶m=myQueryID&orderBy={$orderBy}"); $this->config->execution->search['queryID'] = $queryID; $this->config->execution->search['params']['module']['values'] = $modules; $this->config->execution->search['params']['execution']['values'] = array_filter($productExecutions); diff --git a/module/my/ui/todo.html.php b/module/my/ui/todo.html.php index bd6b45499e..222cae6365 100644 --- a/module/my/ui/todo.html.php +++ b/module/my/ui/todo.html.php @@ -117,6 +117,7 @@ dtable set::emptyTip($lang->my->noTodo), set::createTip($lang->todo->create), set::createLink($canCreate ? createLink('todo', 'create') : ''), + set::createAttr('data-toggle="modal"'), set::footToolbar($footToolbar), set::footPager(usePager()), set::footer(array('checkbox', 'toolbar', hasPriv('todo', 'import2Today') && $type != 'today' ? jsRaw('window.generateHtml') : '', 'checkedInfo', 'flex', 'pager')) diff --git a/module/productplan/config.php b/module/productplan/config.php index e0f80937f2..558792cd55 100644 --- a/module/productplan/config.php +++ b/module/productplan/config.php @@ -47,7 +47,7 @@ $config->productplan->actionList['activate']['hint'] = $lang->productpla $config->productplan->actionList['activate']['text'] = $lang->productplan->activate; $config->productplan->actionList['activate']['url'] = helper::createLink('productplan', 'activate', 'planID={id}'); $config->productplan->actionList['activate']['data-confirm'] = $lang->productplan->confirmActivate; -$config->productplan->actionList['activate']['className'] = 'ajax-submit'; +$config->productplan->actionList['activate']['innerClass'] = 'ajax-submit'; $config->productplan->actionList['createExecution']['icon'] = 'plus'; $config->productplan->actionList['createExecution']['hint'] = $lang->productplan->createExecution; diff --git a/module/productplan/js/browse.ui.js b/module/productplan/js/browse.ui.js index 96e245ddc5..b98dd78c6d 100644 --- a/module/productplan/js/browse.ui.js +++ b/module/productplan/js/browse.ui.js @@ -110,7 +110,7 @@ window.deleteProductPlan = function(planID) }); } -$(document).off('click', '.batch-btn').on('click', '.batch-btn', function() +$(document).off('click', '#table-productplan-browse .batch-btn').on('click', '#table-productplan-browse .batch-btn', function() { const dtable = zui.DTable.query($(this).target); const checkedList = dtable.$.getChecks(); diff --git a/module/productplan/ui/browsebylist.html.php b/module/productplan/ui/browsebylist.html.php index dae3cc5e97..80278fc6ff 100644 --- a/module/productplan/ui/browsebylist.html.php +++ b/module/productplan/ui/browsebylist.html.php @@ -49,7 +49,7 @@ foreach($tableData as $plan) if($plan->status == 'wait') return $action; return null; }, explode(',', str_replace('other:', '', $plan->actions[1])))); - $plan->actions[1] = 'other:' . implode(',', $otherActions); + if($otherActions) $plan->actions[1] = 'other:' . implode(',', $otherActions); } $canBatchEdit = common::hasPriv('productplan', 'batchEdit'); diff --git a/module/project/js/browse.ui.js b/module/project/js/browse.ui.js index e809571a0c..469fcc1652 100644 --- a/module/project/js/browse.ui.js +++ b/module/project/js/browse.ui.js @@ -20,7 +20,7 @@ window.renderCell = function(result, {col, row}) return result; } -$(document).off('click', '.batch-btn').on('click', '.batch-btn', function() +$(document).off('click', '#table-project-browse .batch-btn').on('click', '#table-project-browse .batch-btn', function() { const dtable = zui.DTable.query($(this).target); const checkedList = dtable.$.getChecks(); diff --git a/module/project/ui/batchedit.html.php b/module/project/ui/batchedit.html.php index 84c5263859..1c3a89eade 100644 --- a/module/project/ui/batchedit.html.php +++ b/module/project/ui/batchedit.html.php @@ -91,7 +91,7 @@ formBatchPanel set::control(array ( 'control' => 'date', - 'format' => jsRaw("(value) => (value === '" . LONG_TIME . "' ? '" . $lang->project->longTime . "' : zui.formatDate(value, 'yyyy-MM-dd'))"), + 'display' => jsRaw("(value) => (value === '" . LONG_TIME . "' ? '" . $lang->project->longTime . "' : zui.formatDate(value, 'yyyy-MM-dd'))"), 'actions' => array ( array('text' => $lang->datepicker->dpText->TEXT_TODAY, 'data-set-date' => helper::today()), diff --git a/module/search/model.php b/module/search/model.php index c21a32342b..9098f45bc8 100644 --- a/module/search/model.php +++ b/module/search/model.php @@ -347,6 +347,7 @@ class searchModel extends model $querySessionName = $module . 'Query'; $formSessionName = $module . 'Form'; + $queryID = (int)$queryID; if($queryID) { $query = $this->getQuery($queryID); diff --git a/module/story/model.php b/module/story/model.php index 576bd380ec..689218ea7d 100644 --- a/module/story/model.php +++ b/module/story/model.php @@ -3679,8 +3679,8 @@ class storyModel extends model $estimates = array(); foreach($data->account as $key => $account) { - if(!empty($data->estimate[$key]) and !is_numeric($data->estimate[$key])) dao::$errors[] = $this->lang->story->estimateMustBeNumber; - if(!empty($data->estimate[$key]) and $data->estimate[$key] < 0) dao::$errors[] = $this->lang->story->estimateMustBePlus; + if(!empty($data->estimate[$key]) and !is_numeric($data->estimate[$key])) dao::$errors['estimate'] = $this->lang->story->estimateMustBeNumber; + if(!empty($data->estimate[$key]) and $data->estimate[$key] < 0) dao::$errors['estimate'] = $this->lang->story->estimateMustBePlus; if(dao::isError()) return; $estimates[$account]['account'] = $account; diff --git a/module/story/ui/create.html.php b/module/story/ui/create.html.php index f4bb636dca..aec5d12394 100644 --- a/module/story/ui/create.html.php +++ b/module/story/ui/create.html.php @@ -127,7 +127,7 @@ formGridPanel ( array('text' => $lang->save, 'data-status' => 'active', 'class' => 'primary', 'btnType' => 'submit'), array('text' => $lang->story->saveDraft, 'data-status' => 'draft', 'class' => 'secondary', 'btnType' => 'submit'), - array('text' => $lang->goback, 'data-back' => 'APP', 'class' => 'open-url') + array('text' => $lang->goback, 'back' => true) )), set::fields($createFields), on::click('#loadURS', "loadURS"), diff --git a/module/task/ui/view.html.php b/module/task/ui/view.html.php index 7f13dc2675..729cb0f687 100644 --- a/module/task/ui/view.html.php +++ b/module/task/ui/view.html.php @@ -164,7 +164,7 @@ foreach($linkMRTitles as $MRID => $linkMRTitle) ( set::href(createLink('mr', 'view', "MRID=$MRID")), "#$MRID $linkMRTitle", - setData(array('app' => $app->tab)) + setData('app', 'devops') ) : div("#$MRID $linkMRTitle"); } @@ -179,7 +179,7 @@ foreach($linkCommits as $commit) ( set::href(createLink('repo', 'revision', "repoID={$commit->repo}&objectID={$task->execution}&revision={$commit->revision}")), "#$revision", - setData(array('app' => $app->tab)) + setData('app', 'devops') ) : div($revision . ' ' . $commit->comment); } diff --git a/module/tree/ui/edit.html.php b/module/tree/ui/edit.html.php index 782ab1bc1b..73a67692c7 100644 --- a/module/tree/ui/edit.html.php +++ b/module/tree/ui/edit.html.php @@ -44,10 +44,10 @@ formPanel on::change('loadBranches') ) ), - $product->type != 'normal' ? formGroup + formGroup ( set::width('1/3'), - setClass('branchBox'), + setClass('branchBox', $product->type == 'normal' ? 'hidden' : ''), control ( set::type('picker'), @@ -57,7 +57,7 @@ formPanel set::required(true), on::change('loadModules') ) - ) : null + ) ) : null, $type == 'doc' ? formGroup ( diff --git a/module/upgrade/lang/version.php b/module/upgrade/lang/version.php index afede75f57..e5daa17f48 100644 --- a/module/upgrade/lang/version.php +++ b/module/upgrade/lang/version.php @@ -189,7 +189,7 @@ $lang->upgrade->fromVersions['18_10_1'] = '18.10.1'; $lang->upgrade->fromVersions['18_11'] = '18.11'; $lang->upgrade->fromVersions['20_0_alpha1'] = '20.0.alpha1'; $lang->upgrade->fromVersions['20_0_beta1'] = '20.0.beta1'; -$lang->upgrade->fromVersions['20_0'] = '20.0'; // pms insert position. +$lang->upgrade->fromVersions['20_0_beta2'] = '20.0.beta2'; // pms insert position. global $config; /* Lite. */ diff --git a/module/user/ui/profile.html.php b/module/user/ui/profile.html.php index 91f53ffe8a..dbfd558b10 100644 --- a/module/user/ui/profile.html.php +++ b/module/user/ui/profile.html.php @@ -28,21 +28,25 @@ div setClass('bg-white m-auto p-5 mb-4'), div ( - setClass('flex items-center pb-5'), + setClass('flex items-center pb-5 col'), cell ( set::width('50%'), - setClass('text-right pr-3'), - userAvatar(set::user($user)) + userAvatar(set::user($user), set::size('lg')) ), cell ( + setClass('row'), set::width('50%'), - div(setClass('user-name text-md font-bold'), $user->realname), - zget($lang->user->roleList, $user->role, '') == '' ? null : div + span ( - setClass('user-role text-gray'), - zget($lang->user->roleList, $user->role) + setClass('user-name font-bold center'), + $user->realname + ), + zget($lang->user->roleList, $user->role, '') == '' ? null : span + ( + setClass('user-role text-gray center ml-1'), + '(' . zget($lang->user->roleList, $user->role) . ')' ) ) ),