From 47780015f8d6d404fb8463cfe58173e959be3999 Mon Sep 17 00:00:00 2001 From: tianshujie Date: Thu, 6 Apr 2023 10:27:21 +0800 Subject: [PATCH 1/2] =?UTF-8?q?*=20Fixed=20the=20bottom=20paging=20style?= =?UTF-8?q?=20problem=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- module/api/css/releases.css | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/module/api/css/releases.css b/module/api/css/releases.css index 24e4509c99..2d9d871192 100644 --- a/module/api/css/releases.css +++ b/module/api/css/releases.css @@ -1,6 +1,4 @@ .c-date {width: 150px;} .c-actions {width: 60px;} -tbody tr td {white-space:nowrap; overflow:hidden; text-overflow:ellipsis;} - -.m-api-releases {padding-bottom: 0px !important;} +tbody tr td {white-space: nowrap; overflow: hidden; text-overflow: clip;} From 56791f12efb494003d85ca63494024c3ce367dc2 Mon Sep 17 00:00:00 2001 From: wangyidong Date: Thu, 6 Apr 2023 10:29:23 +0800 Subject: [PATCH 2/2] * code for task #89916. --- module/common/model.php | 171 ++++++++++++------------ module/doc/control.php | 86 +++++++++--- module/doc/js/common.js | 9 +- module/doc/js/selectlibtype.js | 33 +---- module/doc/lang/zh-cn.php | 16 ++- module/doc/model.php | 15 ++- module/doc/view/createtexttype.html.php | 4 +- module/doc/view/selectlibtype.html.php | 124 +++++++++++++++-- 8 files changed, 297 insertions(+), 161 deletions(-) diff --git a/module/common/model.php b/module/common/model.php index d583121d92..677d16ae56 100644 --- a/module/common/model.php +++ b/module/common/model.php @@ -605,102 +605,99 @@ class commonModel extends model if($objectType == 'kanbanspace') $createMethod = 'createSpace'; if(strpos('|bug|execution|kanbanspace|', "|$objectType|") !== false) $needPrintDivider = true; - if(common::hasPriv($module, $createMethod)) + if($objectType == 'doc' and !common::hasPriv('doc', 'tableContents')) continue; + + $hasPriv = common::hasPriv($module, $createMethod); + if($objectType == 'doc' and !$hasPriv and common::hasPriv('api', 'create')) $hasPriv = true; + if(!$hasPriv) continue; + + /* Determines whether to print a divider. */ + if($needPrintDivider and $showCreateList) { - if($objectType == 'doc' and !common::hasPriv('doc', 'tableContents')) continue; + $html .= '
  • '; + $needPrintDivider = false; + } - /* Determines whether to print a divider. */ - if($needPrintDivider and $showCreateList) - { - $html .= '
  • '; - $needPrintDivider = false; - } + $showCreateList = true; + $isOnlyBody = false; + $attr = ''; - $showCreateList = true; - $isOnlyBody = false; - $attr = ''; - - $params = ''; - switch($objectType) - { - case 'doc': - $params = "objectType=&objectID=0&libID=0"; - $createMethod = 'selectLibType'; - $isOnlyBody = true; - $attr = "class='iframe' data-width='700px'"; - break; - case 'project': + $params = ''; + switch($objectType) + { + case 'doc': + $params = "objectType=&objectID=0&libID=0"; + $createMethod = 'selectLibType'; + $isOnlyBody = true; + $attr = "class='iframe' data-width='700px'"; + break; + case 'project': + $params = "model=scrum&programID=0©ProjectID=0&extra=from=global"; + if($config->vision == 'lite') + { + $params = "model=kanban"; + } + elseif(!defined('TUTORIAL')) + { + $params = "programID=0&from=global"; + $createMethod = 'createGuide'; + $attr = 'data-toggle="modal"'; + } + break; + case 'bug': + $params = "productID=$productID&branch=&extras=from=global"; + break; + case 'story': + if(!$productID and $config->vision == 'lite') + { + $module = 'project'; + $params = "model=kanban"; + } + else + { + $params = "productID=$productID&branch=0&moduleID=0&storyID=0&objectID=0&bugID=0&planID=0&todoID=0&extra=from=global"; if($config->vision == 'lite') { - $params = "model=kanban"; - } - else if(!defined('TUTORIAL')) - { - $params = "programID=0&from=global"; - $createMethod = 'createGuide'; - $attr = 'data-toggle="modal"'; - } - else - { - $params = "model=scrum&programID=0©ProjectID=0&extra=from=global"; - } + $projectID = isset($_SESSION['project']) ? $_SESSION['project'] : 0; + $projects = $app->dbh->query("SELECT t2.id FROM " . TABLE_PROJECTPRODUCT . " AS t1 LEFT JOIN " . TABLE_PROJECT . " AS t2 ON t1.project = t2.id WHERE t1.`product` = '{$productID}' and t2.`type` = 'project' and t2.id " . helper::dbIN($app->user->view->projects) . " ORDER BY `order` desc")->fetchAll(); - break; - case 'bug': - $params = "productID=$productID&branch=&extras=from=global"; - break; - case 'story': - if(!$productID and $config->vision == 'lite') - { - $module = 'project'; - $params = "model=kanban"; + $projectIdList = array(); + foreach($projects as $project) $projectIdList[$project->id] = $project->id; + if($projectID and !isset($projectIdList[$projectID])) $projectID = 0; + if(empty($projectID)) $projectID = key($projectIdList); + + $params = "productID={$productID}&branch=0&moduleID=0&storyID=0&objectID={$projectID}&bugID=0&planID=0&todoID=0&extra=from=global"; } - else - { - $params = "productID=$productID&branch=0&moduleID=0&storyID=0&objectID=0&bugID=0&planID=0&todoID=0&extra=from=global"; - if($config->vision == 'lite') - { - $projectID = isset($_SESSION['project']) ? $_SESSION['project'] : 0; - $projects = $app->dbh->query("SELECT t2.id FROM " . TABLE_PROJECTPRODUCT . " AS t1 LEFT JOIN " . TABLE_PROJECT . " AS t2 ON t1.project = t2.id WHERE t1.`product` = '{$productID}' and t2.`type` = 'project' and t2.id " . helper::dbIN($app->user->view->projects) . " ORDER BY `order` desc")->fetchAll(); + } - $projectIdList = array(); - foreach($projects as $project) $projectIdList[$project->id] = $project->id; - if($projectID and !isset($projectIdList[$projectID])) $projectID = 0; - if(empty($projectID)) $projectID = key($projectIdList); - - $params = "productID={$productID}&branch=0&moduleID=0&storyID=0&objectID={$projectID}&bugID=0&planID=0&todoID=0&extra=from=global"; - } - } - - break; - case 'task': - $params = "executionID=0&storyID=0&moduleID=0&taskID=0&todoID=0&extra=from=global"; - break; - case 'testcase': - $params = "productID=$productID&branch=&moduleID=0&from=¶m=0&storyID=0&extras=from=global"; - break; - case 'execution': - $projectID = isset($_SESSION['project']) ? $_SESSION['project'] : 0; - $params = "projectID={$projectID}&executionID=0©ExecutionID=0&planID=0&confirm=no&productID=0&extra=from=global"; - break; - case 'product': - $params = "programID=&extra=from=global"; - break; - case 'program': - $params = "parentProgramID=0&extra=from=global"; - break; - case 'kanbanspace': - $isOnlyBody = true; - $attr = "class='iframe' data-width='75%'"; - break; - case 'kanban': - $isOnlyBody = true; - $attr = "class='iframe' data-width='75%'"; - break; - } - - $html .= '
  • ' . html::a(helper::createLink($module, $createMethod, $params, '', $isOnlyBody), " " . $lang->createObjects[$objectType], '', "$attr data-app=''") . '
  • '; + break; + case 'task': + $params = "executionID=0&storyID=0&moduleID=0&taskID=0&todoID=0&extra=from=global"; + break; + case 'testcase': + $params = "productID=$productID&branch=&moduleID=0&from=¶m=0&storyID=0&extras=from=global"; + break; + case 'execution': + $projectID = isset($_SESSION['project']) ? $_SESSION['project'] : 0; + $params = "projectID={$projectID}&executionID=0©ExecutionID=0&planID=0&confirm=no&productID=0&extra=from=global"; + break; + case 'product': + $params = "programID=&extra=from=global"; + break; + case 'program': + $params = "parentProgramID=0&extra=from=global"; + break; + case 'kanbanspace': + $isOnlyBody = true; + $attr = "class='iframe' data-width='75%'"; + break; + case 'kanban': + $isOnlyBody = true; + $attr = "class='iframe' data-width='75%'"; + break; } + + $html .= '
  • ' . html::a(helper::createLink($module, $createMethod, $params, '', $isOnlyBody), " " . $lang->createObjects[$objectType], '', "$attr data-app=''") . '
  • '; } if(!$showCreateList) return ''; diff --git a/module/doc/control.php b/module/doc/control.php index a681df9fd4..0e3aaa0304 100755 --- a/module/doc/control.php +++ b/module/doc/control.php @@ -381,17 +381,27 @@ class doc extends control $this->config->showMainMenu = (strpos($this->config->doc->textTypes, $docType) === false or $from == 'template'); + $lib = $libID ? $this->doc->getLibByID($libID) : ''; + if(empty($objectID) and $lib) $objectID = zget($lib, $lib->type, 0); + /* Get libs and the default lib id. */ $gobackLink = ($objectID == 0 and $libID == 0) ? $this->createLink('doc', 'tableContents', "type=$linkType") : ''; $unclosed = strpos($this->config->doc->custom->showLibs, 'unclosed') !== false ? 'unclosedProject' : ''; $libs = $this->doc->getLibs($objectType, $extra = "withObject,$unclosed", $libID, $objectID); if(!$libID and !empty($libs)) $libID = key($libs); + if(empty($lib) and $libID) $lib = $this->doc->getLibByID($libID); - $lib = $this->doc->getLibByID($libID); $objects = array(); if($objectType == 'project') { $objects = $this->project->getPairsByProgram('', 'all', false, 'order_asc', 'kanban'); + if($lib->type == 'execution') + { + $execution = $this->loadModel('execution')->getById($lib->execution); + $objectID = $execution->project; + $libs = $this->doc->getLibs('execution', $extra = "withObject,$unclosed", $libID, $lib->execution); + $this->view->execution = $execution; + } $this->view->executions = array(0 => '') + $this->loadModel('execution')->getPairs($objectID, 'sprint,stage', 'multiple,leaf,noprefix'); } elseif($objectType == 'execution') @@ -619,6 +629,7 @@ class doc extends control $libID = $docLib->id; $type = $docLib->type; $objectID = $docLib->$type; + if($this->app->tab != 'execution' and $type == 'execution') $type = 'project'; } $browseLink = inLink('objectLibs', "type=$type&objectID=$objectID&libID=$libID&docID=$docID"); @@ -824,16 +835,26 @@ class doc extends control /** * Ajax get modules by object. * - * @param string $objectType + * @param string $objectType project|product|custom|mine * @param int $objectID + * @param string $docType doc|api * @access public * @return void */ - public function ajaxGetModules($objectType, $objectID) + public function ajaxGetModules($objectType, $objectID, $docType = 'doc') { - $unclosed = strpos($this->config->doc->custom->showLibs, 'unclosed') !== false ? 'unclosedProject' : ''; - $libs = $this->doc->getLibs($objectType, $extra = "withObject,$unclosed", '', $objectID); - $moduleOptionMenu = $this->doc->getLibsOptionMenu($libs); + if($docType == 'doc') + { + $unclosed = strpos($this->config->doc->custom->showLibs, 'unclosed') !== false ? 'unclosedProject' : ''; + $libPairs = $this->doc->getLibs($objectType, $extra = "withObject,$unclosed", '', $objectID); + } + elseif($docType == 'api') + { + $libs = $this->doc->getApiLibs('', $objectType, $objectID); + $libPairs = array(); + foreach($libs as $libID => $lib) $libPairs[$libID] = $lib->name; + } + $moduleOptionMenu = $this->doc->getLibsOptionMenu($libPairs, $docType); return print(html::select('module', $moduleOptionMenu, '', "class='form-control'")); } @@ -896,16 +917,28 @@ class doc extends control /** * AJAX: Get libs by type. * - * @param string $type + * @param string $space mine|product|project|nolink|custom + * @param string $docType doc|api * @access public * @return void */ - public function ajaxGetLibsByType($type) + public function ajaxGetLibsByType($space, $docType = 'doc') { - $unclosed = strpos($this->config->doc->custom->showLibs, 'unclosed') !== false ? 'unclosedProject' : ''; - $libs = $this->doc->getLibs($type, "withObject,$unclosed"); + $libPairs = array(); + if($docType == 'doc') + { + $unclosed = strpos($this->config->doc->custom->showLibs, 'unclosed') !== false ? 'unclosedProject' : ''; + $libPairs = $this->doc->getLibs($space, "withObject,$unclosed"); + } + elseif($docType == 'api') + { + $libs = $this->doc->getApiLibs('', 'nolink'); + $libPairs = array(); + foreach($libs as $libID => $lib) $libPairs[$libID] = $lib->name; + } - return print(html::select('lib', $libs, '', 'class="form-control"')); + $moduleOptionMenu = $this->doc->getLibsOptionMenu($libPairs, $docType); + return print(html::select('module', $moduleOptionMenu, '', "class='form-control'")); } /** @@ -1418,25 +1451,34 @@ class doc extends control { if($_POST) { + $response = array(); + if(empty($_POST['module'])) + { + $response['result'] = 'fail'; + $response['message']['module'] = sprintf($this->lang->error->notempty, $this->lang->doc->libAndModule); + return $this->send($response); + } + + if(strpos($this->post->module, '_') !== false) list($libID, $moduleID) = explode('_', $this->post->module); $response['message'] = $this->lang->saveSuccess; $response['result'] = 'success'; $response['closeModal'] = true; - $response['callback'] = "redirectParentWindow(\"{$this->post->objectType}\", \"{$this->post->lib}\", \"{$this->post->type}\")"; + $response['callback'] = "redirectParentWindow(\"{$this->post->space}\", {$libID}, {$moduleID}, \"{$this->post->type}\")"; return $this->send($response); } - unset($this->lang->doc->libTypeList['book']); + $spaceList = $this->lang->doc->spaceList; + $typeList = $this->lang->doc->types; + if(!common::hasPriv('doc', 'create')) unset($spaceList['mine'], $spaceList['custom'], $typeList['doc']); + if(!common::hasPriv('api', 'create')) unset($spaceList['api'], $typeList['api']); - $globalTypeList = $this->lang->doc->libTypeList; - $globalTypeList = $this->config->vision == 'lite' ? $globalTypeList : $globalTypeList + $this->lang->doc->libGlobalList; + $products = $this->loadModel('product')->getPairs(); + $projects = $this->project->getPairsByProgram('', 'all', false, 'order_asc', 'kanban'); - $defaultType = key($globalTypeList); - $unclosed = strpos($this->config->doc->custom->showLibs, 'unclosed') !== false ? 'unclosedProject' : ''; - $libs = $this->doc->getLibs($defaultType, "withObject,$unclosed"); - - $this->view->globalTypeList = $globalTypeList; - $this->view->defaultType = $defaultType; - $this->view->libs = $libs; + $this->view->spaceList = $spaceList; + $this->view->typeList = $typeList; + $this->view->products = $products; + $this->view->projects = $projects; $this->display(); } diff --git a/module/doc/js/common.js b/module/doc/js/common.js index 4d81139b9f..35720e4b12 100644 --- a/module/doc/js/common.js +++ b/module/doc/js/common.js @@ -6,10 +6,11 @@ * @access public * @return void */ -function loadObjectModules(objectType, objectID) +function loadObjectModules(objectType, objectID, docType) { - var link = createLink('doc', 'ajaxGetModules', 'objectType=' + objectType + '&objectID=' + objectID); - $('#moduleBox').load(link, function(){$('#moduleBox').find('select').chosen()}); + if(typeof docType == 'undefined') docType = 'doc'; + var link = createLink('doc', 'ajaxGetModules', 'objectType=' + objectType + '&objectID=' + objectID + '&type=' + docType); + $('#moduleBox').load(link, function(){$('#moduleBox').find('select').picker(); $('#moduleLabel').remove();}); } /** @@ -22,7 +23,7 @@ function loadObjectModules(objectType, objectID) function loadExecutions(projectID) { var link = createLink('project', 'ajaxGetExecutions', "projectID=" + projectID + "&executionID=0&mode=multiple,leaf,noprefix"); - $('#executionBox').load(link, function(){$('#executionBox').find('select').attr('data-placeholder', holders.execution).attr('onchange', "loadObjectModules('execution', this.value)").chosen()}); + $('#executionBox').load(link, function(){$('#executionBox').find('select').attr('data-placeholder', holders.execution).attr('onchange', "loadObjectModules('execution', this.value)").picker()}); loadObjectModules('project', projectID); } diff --git a/module/doc/js/selectlibtype.js b/module/doc/js/selectlibtype.js index e8b8ae5c76..c35c113429 100644 --- a/module/doc/js/selectlibtype.js +++ b/module/doc/js/selectlibtype.js @@ -1,8 +1,3 @@ -$(function() -{ - loadDocLibs(defaultType); -}) - /** * Redirect the parent window. * @@ -12,14 +7,14 @@ $(function() * @access public * @return void */ -function redirectParentWindow(objectType, libID, docType) +function redirectParentWindow(objectType, libID, moduleID, docType) { if(objectType == 'api') { parent.$.closeModal(function() { new parent.$.zui.ModalTrigger({ - iframe : createLink('api', 'create', 'libID=' + libID), + iframe : createLink('api', 'create', 'libID=' + libID + '&moduleID=' + moduleID), width: '85%' }).show(); }); @@ -27,7 +22,7 @@ function redirectParentWindow(objectType, libID, docType) } config.onlybody = 'no'; - var link = createLink('doc', 'create', 'objectType=' + objectType + '&objectID=0&libID=' + libID + '&moduleID=0&docType=' + docType) + '#app=doc'; + var link = createLink('doc', 'create', 'objectType=' + objectType + '&objectID=0&libID=' + libID + '&moduleID=' + moduleID + '&docType=' + docType) + '#app=doc'; window.parent.$.apps.open(link); } @@ -37,24 +32,8 @@ function redirectParentWindow(objectType, libID, docType) * @param string type * @return void */ -function loadDocLibs(type) +function loadDocLibs(space, type) { - $.get(createLink('doc', 'ajaxGetLibsByType', "type=" + type), function(data) - { - $('#lib').replaceWith(data); - $('#lib_chosen').remove(); - $('#lib').chosen(); - $('#lib').siblings('div').css('width', 'calc(100% - 25px)'); - - if($('#lib').find('option').length == 0) - { - $('#submit').attr('disabled', 'disabled'); - } - else - { - $('#submit').removeAttr('disabled'); - } - }) - - $('#docType').toggleClass('hidden', type == 'api'); + var link = createLink('doc', 'ajaxGetLibsByType', "space=" + space + "&type=" + type); + $('#moduleBox').load(link, function(){$('#moduleBox').find('select').picker(); $('#moduleLabel').remove();}); } diff --git a/module/doc/lang/zh-cn.php b/module/doc/lang/zh-cn.php index 36dc342099..022a94d5d2 100644 --- a/module/doc/lang/zh-cn.php +++ b/module/doc/lang/zh-cn.php @@ -216,6 +216,18 @@ $lang->doc->statusList['draft'] = "草稿"; $lang->doc->aclList['open'] = "公开(有所属库权限即可访问)"; $lang->doc->aclList['private'] = "私有(仅创建者和白名单用户可访问)"; +$lang->doc->space = '所属空间'; +$lang->doc->spaceList['mine'] = '我的空间'; +$lang->doc->spaceList['product'] = '产品空间'; +$lang->doc->spaceList['project'] = '项目空间'; +$lang->doc->spaceList['api'] = '接口空间'; +$lang->doc->spaceList['custom'] = '团队空间'; + +$lang->doc->apiType = '接口类型'; +$lang->doc->apiTypeList['product'] = '产品接口'; +$lang->doc->apiTypeList['project'] = '项目接口'; +$lang->doc->apiTypeList['nolink'] = '无关联接口'; + $lang->doc->typeList['html'] = '富文本'; $lang->doc->typeList['markdown'] = 'Markdown'; $lang->doc->typeList['url'] = '链接'; @@ -229,8 +241,8 @@ $lang->doc->createList['word'] = 'Word'; $lang->doc->createList['ppt'] = 'PPT'; $lang->doc->createList['excel'] = 'Excel'; -$lang->doc->types['text'] = '文档'; -$lang->doc->types['url'] = '链接'; +$lang->doc->types['doc'] = 'WIKI文档'; +$lang->doc->types['api'] = '接口文档'; $lang->doc->contentTypeList['html'] = 'HTML'; $lang->doc->contentTypeList['markdown'] = 'MarkDown'; diff --git a/module/doc/model.php b/module/doc/model.php index 6948a52e0f..ec527d9a5b 100644 --- a/module/doc/model.php +++ b/module/doc/model.php @@ -38,7 +38,7 @@ class docModel extends model * Get api Libraries. * * @param int $appendLib - * @param string $appendLib + * @param string $objectType * @param int $objectID * @return array */ @@ -52,6 +52,7 @@ class docModel extends model ->beginIF($objectType == 'nolink') ->andWhere('product')->eq(0) ->andWhere('project')->eq(0) + ->andWhere('execution')->eq(0) ->fi() ->orderBy('`order`_asc, id_desc') ->fetchAll('id'); @@ -3000,17 +3001,23 @@ class docModel extends model * Get option menu for libs. * * @param array $libs + * @param string $docType * @access public * @return array */ - public function getLibsOptionMenu($libs) + public function getLibsOptionMenu($libs, $docType = 'doc') { $this->loadModel('tree'); $modules = array(); foreach($libs as $libID => $libName) { - if(strpos($libName, '/') !== false) list($objectName, $libName) = explode('/', $libName); - $moduleOptionMenu = $this->tree->getOptionMenu($libID, 'doc', $startModuleID = 0); + if(strpos($libName, '/') !== false) + { + $pausedLibName = explode('/', $libName); + $libName = array_pop($pausedLibName); + $objectName = array_pop($pausedLibName); + } + $moduleOptionMenu = $this->tree->getOptionMenu($libID, $docType, $startModuleID = 0); foreach($moduleOptionMenu as $moduleID => $moduleName) $modules["{$libID}_{$moduleID}"] = $libName . $moduleName; if(empty($moduleOptionMenu)) $modules["{$libID}_0"] = $libName . $moduleName; } diff --git a/module/doc/view/createtexttype.html.php b/module/doc/view/createtexttype.html.php index 2ed7f917fa..29fef3b581 100644 --- a/module/doc/view/createtexttype.html.php +++ b/module/doc/view/createtexttype.html.php @@ -68,10 +68,10 @@ doc->project;?> - + project : $objectID, "class='form-control chosen' onchange=loadExecutions(this.value)");?> app->tab == 'doc'):?> doc->execution?> - doc->placeholder->execution}' onchange='loadObjectModules(\"execution\", this.value)'")?> + doc->placeholder->execution}' onchange='loadObjectModules(\"execution\", this.value)'")?> diff --git a/module/doc/view/selectlibtype.html.php b/module/doc/view/selectlibtype.html.php index 756978bc8a..2e3f6c395b 100644 --- a/module/doc/view/selectlibtype.html.php +++ b/module/doc/view/selectlibtype.html.php @@ -19,27 +19,125 @@
    + - - - - - - + + - doc->types as $typeKey => $typeName) $typeKeyList[$typeKey] = $typeKey; - ?> - + + + + + + + + + + + + + + + - + + + + +
    doc->libType;?>
    doc->lib;?>doc->space?>
    doc->type;?>doc->types, 'text');?>
    doc->nextStep);?>doc->libAndModule?>
    doc->nextStep, 'disabled');?>
    - +doc->placeholder);?> +