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;}
diff --git a/module/common/model.php b/module/common/model.php
index fa7cc564bf..927402fc84 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 4d2fd3236b..ac8946c45b 100755
--- a/module/doc/control.php
+++ b/module/doc/control.php
@@ -375,17 +375,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')
@@ -774,16 +784,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'"));
}
@@ -846,16 +866,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'"));
}
/**
@@ -1318,25 +1350,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 3650f9c138..8b072f9969 100644
--- a/module/doc/lang/zh-cn.php
+++ b/module/doc/lang/zh-cn.php
@@ -217,6 +217,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'] = '链接';
@@ -230,8 +242,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 be7346bb8a..b1ee732734 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');
@@ -3024,17 +3025,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->placeholder);?>
+