Merge remote-tracking branch 'origin/master' into zenops_66

This commit is contained in:
zhaoke
2023-04-13 09:24:52 +08:00
259 changed files with 5958 additions and 4694 deletions
+1 -20
View File
@@ -36,32 +36,13 @@ class bugsEntry extends entry
$this->loadModel('product');
foreach($bugs as $bug)
{
$status = array('code' => $bug->status, 'name' => $this->lang->bug->statusList[$bug->status]);
if($bug->status == 'active' and $bug->confirmed) $status = array('code' => 'confirmed', 'name' => $this->lang->bug->labelConfirmed);
if($bug->resolution == 'postponed') $status = array('code' => 'postponed', 'name' => $this->lang->bug->labelPostponed);
if(!empty($bug->delay)) $status = array('code' => 'delay', 'name' => $this->lang->bug->overdueBugs);
$bug->status = $status['code'];
$bug->statusName = $status['name'];
$product = $this->product->getById($bug->product);
$bug->statusName = $this->lang->bug->statusList[$bug->status];
$bug->productStatus = $product->status;
$result[$bug->id] = $this->format($bug, 'activatedDate:time,openedBy:user,openedDate:time,assignedTo:user,assignedDate:time,mailto:userList,resolvedBy:user,resolvedDate:time,closedBy:user,closedDate:time,lastEditedBy:user,lastEditedDate:time,deadline:date,deleted:bool');
}
$storyChangeds = $this->dao->select('t1.id')->from(TABLE_BUG)->alias('t1')
->leftJoin(TABLE_STORY)->alias('t2')->on('t1.story=t2.id')
->where('t1.id')->in(array_keys($result))
->andWhere('t1.story')->ne('0')
->andWhere('t1.storyVersion != t2.version')
->fetchPairs('id', 'id');
foreach($storyChangeds as $bugID)
{
$status = array('code' => 'storyChanged', 'name' => $this->lang->bug->changed);
$result[$bugID]->status = $status['code'];
$result[$bugID]->statusName = $status['name'];
}
return $this->send(200, array('page' => $pager->pageID, 'total' => $pager->recTotal, 'limit' => $pager->recPerPage, 'bugs' => array_values($result)));
}
+6 -1
View File
@@ -28,6 +28,7 @@ class testcasesEntry extends entry
$this->app->cookie->showAutoCase = 1;
$type = $this->param('status', 'all');
$branch = $this->param('branch', '');
$param = 0;
$moduleID = $this->param('module', 0);
if($moduleID)
@@ -36,8 +37,12 @@ class testcasesEntry extends entry
$param = $moduleID;
}
$this->app->cookie->caseModule = 0;
$this->app->cookie->caseSuite = 0;
$this->app->cookie->preBranch = $branch;
$control = $this->loadController('testcase', 'browse');
$control->browse($productID, $this->param('branch', ''), $type, $param, '', $this->param('order', 'id_desc'), 0, $this->param('limit', 20), $this->param('page', 1));
$control->browse($productID, $this->param('branch', ''), $type, $param, $this->param('caseType', ''), $this->param('order', 'id_desc'), 0, $this->param('limit', 20), $this->param('page', 1));
$data = $this->getData();
+59 -3
View File
File diff suppressed because one or more lines are too long
+402 -325
View File
File diff suppressed because one or more lines are too long
+6 -1
View File
@@ -1185,7 +1185,12 @@ if($config->edition == 'biz' or $config->edition == 'max')
$lang->tree->methodOrder[35] = 'editHost';
$lang->host->methodOrder[40] = 'groupMaintenance';
$lang->resource->doc->diff = 'diffAction';
$lang->resource->doc->diff = 'diffAction';
$lang->resource->doc->mine2export = 'mine2export';
$lang->resource->doc->product2export = 'product2export';
$lang->resource->doc->project2export = 'project2export';
$lang->resource->doc->custom2export = 'custom2export';
$lang->resource->doc->execution2export = 'execution2export';
$lang->resource->my->review = 'review';
+2 -2
View File
@@ -595,7 +595,7 @@ class baseHelper
*/
static public function isZeroDate($date)
{
return (empty($date) or substr($date, 0, 4) == '0000');
return (empty($date) or substr($date, 0, 4) <= '1970');
}
/**
@@ -1008,7 +1008,7 @@ if (!function_exists('getallheaders')) {
function getallheaders()
{
$headers = array();
foreach ($_SERVER as $name => $value)
foreach ($_SERVER as $name => $value)
{
if (substr($name, 0, 5) == 'HTTP_')
{
+52 -3
View File
@@ -316,6 +316,17 @@ class baseDAO
$this->dbh->commit();
}
/**
* Show tables.
*
* @access public
* @return array
*/
public function showTables()
{
return $this->query("SHOW TABLES")->fetchAll(PDO::FETCH_ASSOC);
}
/**
* Desc table, show fields.
*
@@ -325,7 +336,11 @@ class baseDAO
*/
public function descTable($tableName)
{
return $this->query("DESC $tableName")->fetchAll();
$this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
$fields = $this->query("DESC $tableName")->fetchAll();
$this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL);
return $fields;
}
/**
@@ -1703,6 +1718,8 @@ class baseSQL
continue;
}
if(strpos($this->skipFields, ",$field,") !== false) continue;
if($field == 'id' and $this->method == 'update') continue; // primary key not allowed in dmdb.
$this->sql .= "`$field` = " . $this->quote($value) . ',';
}
}
@@ -1874,10 +1891,14 @@ class baseSQL
* @access public
* @return static|sql the sql object.
*/
public function where($arg1, $arg2 = null, $arg3 = null)
public function where($arg1 = '', $arg2 = null, $arg3 = null)
{
if($this->inCondition and !$this->conditionIsTrue) return $this;
if($arg3 !== null)
if(!$arg1)
{
$condition = '';
}
elseif($arg3 !== null)
{
$value = $this->quote($arg3);
$condition = "`$arg1` $arg2 " . $this->quote($arg3);
@@ -2105,6 +2126,34 @@ class baseSQL
return $this;
}
/**
* 不为空日期
* Create not zero date.
*
* @access public
* @return static|sql the sql object.
*/
public function notZeroDate()
{
if($this->inCondition and !$this->conditionIsTrue) return $this;
$this->sql .= " > '1970-01-01' ";
return $this;
}
/**
* 不为空时间
* Create not zero datetime.
*
* @access public
* @return static|sql the sql object.
*/
public function notZeroDatetime()
{
if($this->inCondition and !$this->conditionIsTrue) return $this;
$this->sql .= " > '1970-01-01 00:00:01' ";
return $this;
}
/**
* 创建ORDER BY部分。
* Create the order by part.
+51 -10
View File
@@ -19,6 +19,31 @@
*/
class dm extends dao
{
/**
* 设置$table属性。
* Set the $table property.
*
* @param string $table
* @access public
* @return void
*/
public function setTable($table)
{
$this->table = trim($table, '`');
}
/**
* Show tables.
*
* @access public
* @return array
*/
public function showTables()
{
$sql = "SELECT \"table_name\" FROM all_tables WHERE OWNER = '{$this->config->db->name}'";
return $this->query($sql)->fetchAll(PDO::FETCH_ASSOC);
}
/**
* 类MySQL的DESC语法。
* Desc table, show fields.
@@ -29,14 +54,16 @@ class dm extends dao
*/
public function descTable($tableName)
{
$sql = "select * from all_tab_columns where table_name='{$this->table}'";
$sql = "select * from all_tab_columns where table_name = '$tableName'";
$rawFields = $this->dbh->rawQuery($sql)->fetchAll();
$fields = array();
foreach($rawFields as $rawField)
{
$field = new stdClass();
$field->Field = $rawField->field;
$field->field = $rawField->column_name;
$field->type = $rawField->data_type;
$field->null = $rawField->nullable;
$fields[] = $field;
}
return $fields;
@@ -123,12 +150,17 @@ class dm extends dao
private function formatIfFunction($field)
{
preg_match('/if\(.+\)+/i', $field, $matches);
$if = $matches[0];
if(substr_count($if, '(') == 1)
{
$pos = strpos($if, ')');
$if = substr($if, 0, $pos+1);
}
/* fix sum(if(..., 1, 0)) , count(if(..., 1, 0)) */
if(substr($if, strlen($if)-2) == '))' and (stripos($field, 'sum(') == 0 or stripos($field, 'count(') == 0)) $if = substr($if, 0, strlen($if)-1);
$parts = explode(',', substr($if, 3, strlen($if)-4)); // remove 'if(' and ')'
$case = 'CASE WHEN ' . implode(',', array_slice($parts, 0, count($parts)-2)) . ' THEN ' . $parts[count($parts)-2] . ' ELSE ' . $parts[count($parts)-1] . ' END';
$field = str_ireplace($if, $case, $field);
@@ -146,7 +178,7 @@ class dm extends dao
* @access public
* @return static|sql the sql object.
*/
public function where($arg1, $arg2 = null, $arg3 = null)
public function where($arg1 = '', $arg2 = null, $arg3 = null)
{
$arg1 = $this->formatWhere($arg1);
return parent::where($arg1, $arg2, $arg3);
@@ -250,7 +282,7 @@ class dm extends dao
public function getPKColumns()
{
$sql = "SELECT A.OWNER, A.TABLE_NAME, WM_CONCAT(B.COLUMN_NAME) PK_COLUMNS FROM ALL_CONSTRAINTS A, ALL_CONS_COLUMNS B where A.CONSTRAINT_type = 'P' AND A.OWNER = '{$this->config->db->user}' AND A.TABLE_NAME = '{$this->table}' AND B.OWNER = A.OWNER AND A.TABLE_NAME = B.TABLE_NAME GROUP BY A.OWNER, A.TABLE_NAME;";
$sql = "SELECT A.OWNER, A.TABLE_NAME, WM_CONCAT(B.COLUMN_NAME) PK_COLUMNS FROM ALL_CONSTRAINTS A, ALL_CONS_COLUMNS B where A.CONSTRAINT_type = 'P' AND A.OWNER = '{$this->config->db->name}' AND A.TABLE_NAME = '{$this->table}' AND B.OWNER = A.OWNER AND A.TABLE_NAME = B.TABLE_NAME GROUP BY A.OWNER, A.TABLE_NAME;";
$content = $this->dbh->query($sql)->fetch();
return empty($content) ? false : $content->PK_COLUMNS;
@@ -279,7 +311,7 @@ class dm extends dao
if($this->method == 'replace' && !empty($this->sqlobj->data))
{
$insertSql = "INSERT INTO {$this->table} ";
$insertSql = "INSERT INTO \"{$this->table}\" ";
$fields = '(';
$values = 'VALUES(';
foreach($this->sqlobj->data as $field => $value)
@@ -295,10 +327,19 @@ class dm extends dao
$insertSql .= $fields . ' ' . $values;
$updateSql = str_replace('REPLACE', 'UPDATE', $sql);
$pk = $this->getPKColumns();
if(!empty($pk) && isset($this->sqlobj->data->{$pk})) $updateSql .= " where {$pk} = '{$this->sqlobj->data->{$pk}}'";
$pks = $this->getPKColumns();
if(!empty($pks))
{
$pks = explode(',', $pks);
$conditions = array();
foreach($pks as $pk)
{
if(isset($this->sqlobj->data->{$pk})) $conditions[] = " \"{$pk}\" = '{$this->sqlobj->data->{$pk}}'";
}
if(!empty($conditions)) $updateSql .= ' WHERE ' . implode(' AND ', $conditions);
}
$deleteSql = "DELETE FROM {$this->table} WHERE ";
$deleteSql = "DELETE FROM \"{$this->table}\" WHERE ";
$ingore = array();
$ingore['`zt_config`'] = array('value');
foreach($this->sqlobj->data as $field => $value)
@@ -403,7 +444,7 @@ EOT;
foreach($rawFields as $rawField)
{
$firstPOS = strpos($rawField->data_type, '(');
$type = substr($rawField->data_type, 0, $firstPOS > 0 ? $firstPOS : strlen($rawField->type));
$type = substr($rawField->data_type, 0, $firstPOS > 0 ? $firstPOS : strlen($rawField->data_type));
$type = str_replace(array('big', 'small', 'medium', 'tiny', 'var'), '', $type);
$field = array();
@@ -434,7 +475,7 @@ EOT;
{
$field['rule'] = 'skip';
}
$fields[$rawField->field] = $field;
$fields[$rawField->column_name] = $field;
}
return $fields;
}
+1
View File
@@ -63,6 +63,7 @@ $config->action->majorList['product'] = array('opened', 'edited');
$config->action->majorList['program'] = array('opened', 'edited');
$config->action->majorList['project'] = array('opened', 'edited');
$config->action->majorList['execution'] = array('opened', 'edited');
$config->action->majorList['doc'] = array('releaseddoc', 'collected');
$config->action->needGetProjectType = 'build,task,bug,case,testcase,caselib,testtask,testsuite,testreport,doc,issue,release,risk,design,opportunity,trainplan,gapanalysis,researchplan,researchreport,';
$config->action->needGetRelateField = ',branch,story,productplan,release,task,build,bug,testcase,case,testtask,testreport,doc,doclib,issue,risk,opportunity,trainplan,gapanalysis,team,whitelist,researchplan,researchreport,meeting,kanbanlane,kanbancolumn,module,review,';
+16
View File
@@ -143,6 +143,22 @@ class action extends control
foreach($trashes as $trash) $executionIdList[] = $trash->execution;
$this->view->executionList = $this->execution->getByIdList($executionIdList, 'all');
}
/* Process pivot name. */
foreach($trashes as $trash)
{
if($trash->objectType == 'pivot')
{
$pivotNames = json_decode($trash->objectName, true);
$trash->objectName = zget($pivotNames, $this->app->getClientLang(), '');
if(empty($trash->objectName))
{
$pivotNames = array_filter($pivotNames);
$trash->objectName = reset($pivotNames);
}
}
}
/* Title and position. */
$this->view->title = $this->lang->action->trash;
$this->view->position[] = $this->lang->action->trash;
+12
View File
@@ -269,6 +269,14 @@ $lang->action->desc->linkbug = '$date, <strong>$actor</strong> link bugs <st
$lang->action->desc->unlinkstory = '$date, <strong>$actor</strong> remove stories <strong>$extra</strong> from plan.' . "\n";
$lang->action->desc->unlinkbug = '$date, <strong>$actor</strong> remove bugs <strong>$extra</strong> from plan.' . "\n";
/* Describes the history of operations when a document is saved as a draft or released. */
$lang->action->desc->saveddraft = '$date, 由 <strong>$actor</strong> save draft <strong>$extra</strong>。' . "\n";
$lang->action->desc->releaseddoc = '$date, 由 <strong>$actor</strong> released <strong>$extra</strong>。' . "\n";
/* This parameter describes historical operations that are performed when a document is collected or uncollected. */
$lang->action->desc->collected = '$date, 由 <strong>$actor</strong> collected <strong>$extra</strong>。' . "\n";
$lang->action->desc->uncollected = '$date, 由 <strong>$actor</strong> uncollected <strong>$extra</strong>。' . "\n";
/* Used to display dynamic information. */
$lang->action->label = new stdclass();
$lang->action->label->install = 'install ';
@@ -428,6 +436,10 @@ $lang->action->label->createdsnapshot = 'create snapshot';
$lang->action->label->restoredsnapshot = 'create snapshot';
$lang->action->label->editsnapshot = 'edit snapshot';
$lang->action->label->deletesnapshot = 'deleted snapshot';
$lang->action->label->saveddraft = 'save draft';
$lang->action->label->releaseddoc = 'released';
$lang->action->label->collected = 'collected';
$lang->action->label->uncollected = 'uncollected';
/* Dynamic information is grouped by object. */
$lang->action->dynamicAction = new stdclass;
+12
View File
@@ -269,6 +269,14 @@ $lang->action->desc->linkbug = '$date, <strong>$actor</strong> link bugs <st
$lang->action->desc->unlinkstory = '$date, <strong>$actor</strong> remove stories <strong>$extra</strong> from plan.' . "\n";
$lang->action->desc->unlinkbug = '$date, <strong>$actor</strong> remove bugs <strong>$extra</strong> from plan.' . "\n";
/* Describes the history of operations when a document is saved as a draft or released. */
$lang->action->desc->saveddraft = '$date, 由 <strong>$actor</strong> save draft <strong>$extra</strong>。' . "\n";
$lang->action->desc->releaseddoc = '$date, 由 <strong>$actor</strong> released <strong>$extra</strong>。' . "\n";
/* This parameter describes historical operations that are performed when a document is collected or uncollected. */
$lang->action->desc->collected = '$date, 由 <strong>$actor</strong> collected <strong>$extra</strong>。' . "\n";
$lang->action->desc->uncollected = '$date, 由 <strong>$actor</strong> uncollected <strong>$extra</strong>。' . "\n";
/* Used to display dynamic information. */
$lang->action->label = new stdclass();
$lang->action->label->install = 'install ';
@@ -428,6 +436,10 @@ $lang->action->label->createdsnapshot = 'create snapshot';
$lang->action->label->restoredsnapshot = 'create snapshot';
$lang->action->label->editsnapshot = 'edit snapshot';
$lang->action->label->deletesnapshot = 'deleted snapshot';
$lang->action->label->saveddraft = 'save draft';
$lang->action->label->releaseddoc = 'released';
$lang->action->label->collected = 'collected';
$lang->action->label->uncollected = 'uncollected';
/* Dynamic information is grouped by object. */
$lang->action->dynamicAction = new stdclass;
+12
View File
@@ -269,6 +269,14 @@ $lang->action->desc->linkbug = '$date, <strong>$actor</strong> link bugs <st
$lang->action->desc->unlinkstory = '$date, <strong>$actor</strong> remove stories <strong>$extra</strong> from plan.' . "\n";
$lang->action->desc->unlinkbug = '$date, <strong>$actor</strong> remove bugs <strong>$extra</strong> from plan.' . "\n";
/* Describes the history of operations when a document is saved as a draft or released. */
$lang->action->desc->saveddraft = '$date, 由 <strong>$actor</strong> save draft <strong>$extra</strong>。' . "\n";
$lang->action->desc->releaseddoc = '$date, 由 <strong>$actor</strong> released <strong>$extra</strong>。' . "\n";
/* This parameter describes historical operations that are performed when a document is collected or uncollected. */
$lang->action->desc->collected = '$date, 由 <strong>$actor</strong> collected <strong>$extra</strong>。' . "\n";
$lang->action->desc->uncollected = '$date, 由 <strong>$actor</strong> uncollected <strong>$extra</strong>。' . "\n";
/* Used to display dynamic information. */
$lang->action->label = new stdclass();
$lang->action->label->install = 'install ';
@@ -428,6 +436,10 @@ $lang->action->label->createdsnapshot = 'create snapshot';
$lang->action->label->restoredsnapshot = 'create snapshot';
$lang->action->label->editsnapshot = 'edit snapshot';
$lang->action->label->deletesnapshot = 'deleted snapshot';
$lang->action->label->saveddraft = 'save draft';
$lang->action->label->releaseddoc = 'released';
$lang->action->label->collected = 'collected';
$lang->action->label->uncollected = 'uncollected';
/* Dynamic information is grouped by object. */
$lang->action->dynamicAction = new stdclass();
+12
View File
@@ -269,6 +269,14 @@ $lang->action->desc->linkbug = '$date, 由 <strong>$actor</strong> 关联BUG
$lang->action->desc->unlinkstory = '$date, 由 <strong>$actor</strong> 从计划移除需求 <strong>$extra</strong>。' . "\n";
$lang->action->desc->unlinkbug = '$date, 由 <strong>$actor</strong> 从计划移除BUG <strong>$extra</strong>。' . "\n";
/* 用来描述文档保存为草稿或发布时的历史操作记录。*/
$lang->action->desc->saveddraft = '$date, 由 <strong>$actor</strong> 存为草稿 <strong>$extra</strong>。' . "\n";
$lang->action->desc->releaseddoc = '$date, 由 <strong>$actor</strong> 发布 <strong>$extra</strong>。' . "\n";
/* 用来描述文档收藏或取消收藏时的历史操作记录。*/
$lang->action->desc->collected = '$date, 由 <strong>$actor</strong> 收藏 <strong>$extra</strong>。' . "\n";
$lang->action->desc->uncollected = '$date, 由 <strong>$actor</strong> 取消收藏 <strong>$extra</strong>。' . "\n";
/* 用来显示动态信息。*/
$lang->action->label = new stdclass();
$lang->action->label->install = '安装了';
@@ -428,6 +436,10 @@ $lang->action->label->createdsnapshot = '创建了快照';
$lang->action->label->restoredsnapshot = '还原了快照';
$lang->action->label->editsnapshot = '编辑了快照';
$lang->action->label->deletesnapshot = '编辑了快照';
$lang->action->label->saveddraft = '存为草稿';
$lang->action->label->releaseddoc = '发布了';
$lang->action->label->collected = '收藏了';
$lang->action->label->uncollected = '取消收藏了';
/* 动态信息按照对象分组 */
$lang->action->dynamicAction = new stdclass();
+22 -3
View File
@@ -1306,9 +1306,15 @@ class actionModel extends model
$shadowProducts = $this->dao->select('id')->from(TABLE_PRODUCT)->where('shadow')->eq(1)->fetchPairs();
$projectMultiples = $this->dao->select('id,type,multiple')->from(TABLE_PROJECT)->where('id')->in($projectIdList)->fetchAll('id');
$docList = $this->loadModel('doc')->getPrivDocs('', 0, 'all');
$apiList = $this->loadModel('api')->getPrivApis();
$docLibList = $this->doc->getLibs('hasApi');
foreach($actions as $i => $action)
{
if($action->objectType == 'doc' and !isset($docList[$action->objectID])) unset($actions[$i]);
if($action->objectType == 'api' and !isset($apiList[$action->objectID])) unset($actions[$i]);
if($action->objectType == 'doclib' and !isset($docLibList[$action->objectID])) unset($actions[$i]);
if($action->objectType == 'product' AND isset($shadowProducts[$action->objectID]))
{
unset($actions[$i]);
@@ -1348,6 +1354,16 @@ class actionModel extends model
{
$action->objectName = $action->extra;
}
elseif($action->objectType == 'pivot')
{
$pivotNames = json_decode($action->objectName, true);
$action->objectName = zget($pivotNames, $this->app->getClientLang(), '');
if(empty($action->objectName))
{
$pivotNames = array_filter($pivotNames);
$action->objectName = reset($pivotNames);
}
}
$projectID = isset($relatedProjects[$action->objectType][$action->objectID]) ? $relatedProjects[$action->objectType][$action->objectID] : 0;
@@ -1545,6 +1561,8 @@ class actionModel extends model
*/
public function setObjectLink($action, $deptUsers, $shadowProducts, $project = null)
{
$this->app->loadConfig('doc');
$action->objectLink = '';
$action->objectLabel = zget($this->lang->action->objectTypes, $action->objectLabel);
@@ -1674,9 +1692,10 @@ class actionModel extends model
else
{
$method = 'tablecontents';
if($docLib->type == 'product') $method = 'productspace';
if(in_array($docLib->type, array('project', 'execution'))) $method = 'projectspace';
$params = $method == 'tablecontents' ? sprintf($vars, $docLib->type, $docLib->objectID, $action->objectID, $appendLib) : "objectID={$docLib->objectID}&libID={$action->objectID}";
if(isset($this->config->doc->spaceMethod[$docLib->type])) $method = $this->config->doc->spaceMethod[$docLib->type];
if($method == 'myspace') $params = "type=mine&libID={$action->objectID}";
if($method == 'tablecontents') $params = sprintf($vars, $docLib->type, $docLib->objectID, $action->objectID, $appendLib);
if(!in_array($method, array('myspace', 'tablecontents'))) $params = "objectID={$docLib->objectID}&libID={$action->objectID}";
$action->objectLink = helper::createLink('doc', $method, $params);
}
}
+21 -1
View File
@@ -169,12 +169,32 @@ class api extends control
$this->view->actions = $apiID ? $this->action->getList('api', $apiID) : array();
}
/* Crumbs links array. */
$lib = zget($libs, $libID);
$type = $lib->product ? 'product' : ($lib->project ? 'project' : 'unlink');
$methodName = $type != 'unlink' ? $type . 'Space' : 'index';
if($this->app->tab == 'doc') $methodName = 'index';
$linkObject = zget($lib, $type, 0);
$linkParams = "libID=$lib->id";
if($methodName != 'index') $linkParams = "objectID=$linkObject&$linkParams";
$crumbs[] = html::a(inLink($methodName, $linkParams), html::image("static/svg/interface.svg") . $lib->name);
$moduleList = $this->loadModel('tree')->getParents($api->module);
foreach($moduleList as $module)
{
$linkParams .= "&moduleID=$module->id";
$crumbs[] = html::a(inLink($methodName, $linkParams), $module->name);
}
$this->view->title = $this->lang->api->pageTitle;
$this->view->libs = $libs;
$this->view->isRelease = $release > 0;
$this->view->release = $release;
$this->view->libID = $libID;
$this->view->apiID = $apiID;
$this->view->crumbs = $crumbs;
$this->view->users = $this->user->getPairs('noclosed,noletter');
$this->view->moduleTree = $this->doc->getApiModuleTree($libID, $apiID, $release, $moduleID);
$this->view->objectDropdown = $this->generateLibsDropMenu($libs[$libID], $release);
@@ -517,7 +537,7 @@ class api extends control
return print(js::locate($this->createLink('api', 'index'), 'parent.parent'));
}
return print(js::locate($this->createLink('api', 'index'), 'parent'));
return print(js::reload('parent'));
}
}
+4
View File
@@ -159,3 +159,7 @@ form .table-data, #content .table-data {border: 1px solid #e2e2e3;}
.paramsTable th {text-align: left!important; font-size: 14px;}
.paramsTable td {text-align: left;}
.info .version, .info .crumbs {float: left;}
.info .crumbs {font-size: 13px; margin-top: 5px; font-weight: normal;}
.info .crumbs img {margin-right: 3px;}
+1 -2
View File
@@ -200,8 +200,7 @@ $(document).ready(function()
*/
function redirectParentWindow(libID)
{
var link = createLink('api', 'index', 'libID=' + libID);
parent.location.href = link;
parent.location.reload();
}
try {
+26
View File
@@ -1031,4 +1031,30 @@ class apiModel extends model
return array($normalObjects, $closedObjects);
}
/**
* Get priv Apis..
*
* @param string $mode all
* @access public
* @return array
*/
public function getPrivApis($mode = '')
{
$libs = $this->dao->select('*')->from(TABLE_DOCLIB)
->where('type')->eq('api')
->andWhere('vision')->eq($this->config->vision)
->fetchAll('id');
$this->loadModel('doc');
foreach($libs as $libID => $lib)
{
if(!$this->doc->checkPrivLib($lib)) unset($libs[$libID]);
}
return $this->dao->select('id')->from(TABLE_API)
->where('lib')->in(array_keys($libs))
->beginIF($mode != 'all')->andWhere('deleted')->eq(0)->fi()
->fetchAll('id');
}
}
+1
View File
@@ -20,6 +20,7 @@
</ul>
</div>
</div>
<div class="crumbs"><?php echo implode(' > ', $crumbs);?></div>
</div>
<div class="actions">
<?php echo html::a("javascript:fullScreen()", '<span class="icon-fullscreen"></span>', '', "title='{$lang->fullscreen}' class='btn btn-link fullscreen-btn'");?>
+4 -4
View File
@@ -25,7 +25,7 @@
if($libTree and common::hasPriv('api', 'struct')) echo html::a($this->createLink('api', 'struct', "libID=$libID"), "<i class='icon-treemap muted'> </i>" . $lang->api->struct, '', "class='btn btn-link'");
if($libTree and common::hasPriv('api', 'releases')) echo html::a($this->createLink('api', 'releases', "libID=$libID", 'html', true), "<i class='icon-version muted'> </i>" . $lang->api->releases, '', "class='btn btn-link iframe' data-width='800px'");
if($libTree and common::hasPriv('api', 'createRelease')) echo html::a($this->createLink('api', 'createRelease', "libID=$libID"), "<i class='icon-publish muted'> </i>" . $lang->api->createRelease, '', "class='btn btn-link iframe' data-width='800px'");
if($libTree and common::hasPriv('api', 'export') and $config->edition != 'open') echo html::a($this->createLink('api', 'export', "libID=$libID&version=$version&release=$release", 'html', true), "<i class='icon-export muted'> </i>" . $lang->export, '', "class='btn btn-link export' data-width='480px' id='export'");
if($libTree and common::hasPriv('api', 'export') and $config->edition != 'open') echo html::a($this->createLink('api', 'export', "libID=$libID&version=$version&release=$release&moduleID=$moduleID", 'html', true), "<i class='icon-export muted'> </i>" . $lang->export, '', "class='btn btn-link export' data-width='480px' id='export'");
if(common::hasPriv('api', 'createLib')) echo html::a($this->createLink('api', 'createLib', "type=" . ($objectType ? $objectType : 'nolink') . "&objectID=$objectID"), '<i class="icon icon-plus"></i> ' . $lang->api->createLib, '', 'class="btn btn-secondary iframe" data-width="800px"');
if($libTree and common::hasPriv('api', 'create')) echo html::a($this->createLink('api', 'create', "libID=$libID&moduleID=$moduleID"), '<i class="icon icon-plus"></i> ' . $lang->api->createApi, '', 'class="btn btn-primary"');
?>
@@ -55,7 +55,7 @@
<div class='hidden' id='dropDownData'>
<ul class='libDorpdown'>
<?php if(common::hasPriv('tree', 'browse')):?>
<li data-method="addCataLib" data-has-children='%hasChildren%' data-libid='%libID%' data-moduleid="%moduleID%" data-type="add"><a><i class="icon icon-icon-add-directory"></i><?php echo $lang->doc->libDropdown['addModule'];?></a></li>
<li data-method="addCataLib" data-has-children='%hasChildren%' data-libid='%libID%' data-moduleid="%moduleID%" data-type="add"><a><i class="icon icon-add-directory"></i><?php echo $lang->doc->libDropdown['addModule'];?></a></li>
<?php endif;?>
<?php if(common::hasPriv('api', 'editLib')):?>
<li data-method="editLib"><a href='<?php echo inlink('editLib', 'libID=%libID%');?>' data-toggle='modal' data-type='iframe'><i class="icon icon-edit"></i><?php echo $lang->doc->libDropdown['editLib'];?></a></li>
@@ -66,8 +66,8 @@
</ul>
<ul class='moduleDorpdown'>
<?php if(common::hasPriv('tree', 'browse')):?>
<li data-method="addCataBro" data-type="add" data-id="%moduleID%"><a><i class="icon icon-icon-add-directory"></i><?php echo $lang->doc->libDropdown['addSameModule'];?></a></li>
<li data-method="addCataChild" data-type="add" data-id="%moduleID%" data-has-children='%hasChildren%'><a><i class="icon icon-icon-add-directory"></i><?php echo $lang->doc->libDropdown['addSubModule'];?></a></li>
<li data-method="addCataBro" data-type="add" data-id="%moduleID%"><a><i class="icon icon-add-directory"></i><?php echo $lang->doc->libDropdown['addSameModule'];?></a></li>
<li data-method="addCataChild" data-type="add" data-id="%moduleID%" data-has-children='%hasChildren%'><a><i class="icon icon-add-directory"></i><?php echo $lang->doc->libDropdown['addSubModule'];?></a></li>
<li data-method="editCata" class='edit-module'><a data-href='<?php echo helper::createLink('tree', 'edit', 'moduleID=%moduleID%&type=doc');?>'><i class="icon icon-edit"></i><?php echo $lang->doc->libDropdown['editModule'];?></a></li>
<li data-method="deleteCata"><a href='<?php echo helper::createLink('tree', 'delete', 'rootID=%libID%&moduleID=%moduleID%');?>' target='hiddenwin'><i class="icon icon-trash"></i><?php echo $lang->doc->libDropdown['delModule'];?></a></li>
<?php endif;?>
+44
View File
@@ -40,3 +40,47 @@ $config->statistic = new stdclass();
$config->statistic->storyStages = array('wait', 'planned', 'developing', 'testing', 'released');
$config->block->workMethods = 'task,story,requirement,bug,testcase,testtask,issue,risk,meeting';
$config->block->modules = array();
$config->block->modules['project'] = new stdclass();
$config->block->modules['project']->moreLinkList = new stdclass();
$config->block->modules['project']->moreLinkList->recentproject = 'project|browse|';
$config->block->modules['project']->moreLinkList->statistic = 'project|browse|';
$config->block->modules['project']->moreLinkList->project = 'project|browse|';
$config->block->modules['project']->moreLinkList->cmmireport = 'weekly|index|';
$config->block->modules['project']->moreLinkList->cmmiestimate = 'workestimation|index|';
$config->block->modules['project']->moreLinkList->cmmiissue = 'issue|browse|';
$config->block->modules['project']->moreLinkList->cmmirisk = 'risk|browse|';
$config->block->modules['project']->moreLinkList->scrumlist = 'project|execution|';
$config->block->modules['project']->moreLinkList->scrumtest = 'project|testtask|';
$config->block->modules['project']->moreLinkList->scrumproduct = 'product|all|';
$config->block->modules['project']->moreLinkList->sprint = 'project|execution|';
$config->block->modules['project']->moreLinkList->projectdynamic = 'project|dynamic|';
$config->block->modules['product'] = new stdclass();
$config->block->modules['product']->moreLinkList = new stdclass();
$config->block->modules['product']->moreLinkList->list = 'product|all|';
$config->block->modules['product']->moreLinkList->story = 'my|story|type=%s';
$config->block->modules['execution'] = new stdclass();
$config->block->modules['execution']->moreLinkList = new stdclass();
$config->block->modules['execution']->moreLinkList->list = 'execution|all|status=%s&executionID=';
$config->block->modules['execution']->moreLinkList->task = 'my|task|type=%s';
$config->block->modules['qa'] = new stdclass();
$config->block->modules['qa']->moreLinkList = new stdclass();
$config->block->modules['qa']->moreLinkList->bug = 'my|bug|type=%s';
$config->block->modules['qa']->moreLinkList->case = 'my|testcase|type=%s';
$config->block->modules['qa']->moreLinkList->testtask = 'testtask|browse|type=%s';
$config->block->modules['todo'] = new stdclass();
$config->block->modules['todo']->moreLinkList = new stdclass();
$config->block->modules['todo']->moreLinkList->list = 'my|todo|type=all';
$config->block->modules['common'] = new stdclass();
$config->block->modules['common']->moreLinkList = new stdclass();
$config->block->modules['common']->moreLinkList->dynamic = 'company|dynamic|';
$config->block->modules['doc'] = new stdclass();
$config->block->modules['doc']->moreLinkList = new stdclass();
$config->block->modules['doc']->moreLinkList->docmycollection = 'doc|myspace|type=collect&libID=0&moduleID=0&browseType=all&param=0&orderBy=editedDate_desc';
+122 -4
View File
@@ -42,6 +42,7 @@ class block extends control
if($module == 'my')
{
$modules = $this->lang->block->moduleList;
unset($modules['doc']);
list($programModule, $programMethod) = explode('-', $this->config->programLink);
list($productModule, $productMethod) = explode('-', $this->config->productLink);
@@ -299,9 +300,9 @@ class block extends control
$block->blockLink = $this->createLink('block', 'printBlock', "id=$block->id&module=$block->module");
$block->moreLink = '';
if(isset($this->lang->block->modules[$source]->moreLinkList->{$blockID}))
if(isset($this->config->block->modules[$source]->moreLinkList->{$blockID}))
{
list($moduleName, $method, $vars) = explode('|', sprintf($this->lang->block->modules[$source]->moreLinkList->{$blockID}, isset($block->params->type) ? $block->params->type : ''));
list($moduleName, $method, $vars) = explode('|', sprintf($this->config->block->modules[$source]->moreLinkList->{$blockID}, isset($block->params->type) ? $block->params->type : ''));
/* The list assigned to me jumps to the work page when click more button. */
$block->moreLink = $this->createLink($moduleName, $method, $vars);
@@ -583,9 +584,9 @@ class block extends control
}
$this->view->moreLink = '';
if(isset($this->lang->block->modules[$module]->moreLinkList->{$code}))
if(isset($this->config->block->modules[$module]->moreLinkList->{$code}))
{
list($moduleName, $method, $vars) = explode('|', sprintf($this->lang->block->modules[$module]->moreLinkList->{$code}, isset($params->type) ? $params->type : ''));
list($moduleName, $method, $vars) = explode('|', sprintf($this->config->block->modules[$module]->moreLinkList->{$code}, isset($params->type) ? $params->type : ''));
$this->view->moreLink = $this->createLink($moduleName, $method, $vars);
}
@@ -2033,6 +2034,123 @@ class block extends control
$this->view->projects = $this->loadModel('project')->getOverviewList('byStatus', $status, $orderBy, $count);
}
/**
* Print document statistic block.
*
* @access public
* @return void
*/
public function printDocStatisticBlock()
{
$this->view->statistic = $this->loadModel('doc')->getStatisticInfo();
}
/**
* Print document dynamic block.
*
* @access public
* @return void
*/
public function printDocDynamicBlock()
{
/* Load pager. */
$this->app->loadClass('pager', $static = true);
$pager = new pager(0, 30, 1);
$this->view->actions = $this->loadModel('doc')->getDynamic($pager);
$this->view->users = $this->loadModel('user')->getPairs('nodeleted|noletter|all');
}
/**
* Print my collection of documents block.
*
* @access public
* @return void
*/
public function printDocMyCollectionBlock()
{
/* Load pager. */
$this->app->loadClass('pager', $static = true);
$pager = new pager(0, 6, 1);
$docList = $this->loadModel('doc')->getDocsByBrowseType('collectedbyme', 0, 0, 'editedDate_desc', $pager);
$libList = array();
foreach($docList as $doc)
{
$doc->editedDate = substr($doc->editedDate, 0, 10);
$doc->editInterval = helper::getDateInterval($doc->editedDate);
$libList[] = $doc->lib;
}
$this->view->docList = $docList;
}
/**
* Print recent update block.
*
* @access public
* @return void
*/
public function printDocRecentUpdateBlock()
{
/* Load pager. */
$this->app->loadClass('pager', $static = true);
$pager = new pager(0, 6, 1);
$docList = $this->loadModel('doc')->getDocsByBrowseType('byediteddate', 0, 0, 'editedDate_desc', $pager);
$libList = array();
foreach($docList as $doc)
{
$doc->editedDate = substr($doc->editedDate, 0, 10);
$doc->editInterval = helper::getDateInterval($doc->editedDate);
$libList[] = $doc->lib;
}
$this->view->docList = $docList;
}
/**
* Print view list block.
*
* @access public
* @return void
*/
public function printDocViewListBlock()
{
}
/**
* Print collect list block.
*
* @access public
* @return void
*/
public function printDocCollectListBlock()
{
}
/**
* Print product's document block.
*
* @access public
* @return void
*/
public function printProductDocBlock()
{
}
/**
* Print project's document block.
*
* @access public
* @return void
*/
public function printProjectDocBlock()
{
}
/**
* Print guide block
*
+48 -34
View File
@@ -332,6 +332,42 @@ $lang->block->default['full']['my']['10']['grid'] = 8;
$lang->block->default['full']['my']['10']['params']['orderBy'] = 'id_desc';
$lang->block->default['full']['my']['10']['params']['count'] = '15';
/* Doc module block. */
$lang->block->default['doc']['1']['title'] = 'Statistic';
$lang->block->default['doc']['1']['block'] = 'docstatistic';
$lang->block->default['doc']['1']['grid'] = 8;
$lang->block->default['doc']['2']['title'] = 'Dynamic';
$lang->block->default['doc']['2']['block'] = 'docdynamic';
$lang->block->default['doc']['2']['grid'] = 4;
$lang->block->default['doc']['3']['title'] = 'My Collection';
$lang->block->default['doc']['3']['block'] = 'docmycollection';
$lang->block->default['doc']['3']['grid'] = 8;
$lang->block->default['doc']['4']['title'] = 'Recently update';
$lang->block->default['doc']['4']['block'] = 'docrecentupdate';
$lang->block->default['doc']['4']['grid'] = 8;
$lang->block->default['doc']['5']['title'] = 'Browse Leaderboard';
$lang->block->default['doc']['5']['block'] = 'docviewlist';
$lang->block->default['doc']['5']['grid'] = 4;
if($config->vision == 'rnd')
{
$lang->block->default['doc']['6']['title'] = $lang->productCommon . 'Document';
$lang->block->default['doc']['6']['block'] = 'productdoc';
$lang->block->default['doc']['6']['grid'] = 8;
}
$lang->block->default['doc']['7']['title'] = 'Favorite Leaderboard';
$lang->block->default['doc']['7']['block'] = 'doccollectlist';
$lang->block->default['doc']['7']['grid'] = 4;
$lang->block->default['doc']['8']['title'] = $lang->projectCommon . 'Document';
$lang->block->default['doc']['8']['block'] = 'projectdoc';
$lang->block->default['doc']['8']['grid'] = 8;
$lang->block->count = 'Count';
$lang->block->type = 'Type';
$lang->block->orderBy = 'Order by';
@@ -360,6 +396,7 @@ $lang->block->moduleList['project'] = $lang->projectCommon;
$lang->block->moduleList['execution'] = $lang->execution->common;
$lang->block->moduleList['qa'] = 'QA';
$lang->block->moduleList['todo'] = 'Todos';
$lang->block->moduleList['doc'] = 'Doc';
$lang->block->modules['project'] = new stdclass();
$lang->block->modules['project']->availableBlocks = new stdclass();
@@ -414,6 +451,17 @@ $lang->block->modules['todo'] = new stdclass();
$lang->block->modules['todo']->availableBlocks = new stdclass();
$lang->block->modules['todo']->availableBlocks->list = 'Todos';
$lang->block->modules['doc'] = new stdclass();
$lang->block->modules['doc']->availableBlocks = new stdclass();
$lang->block->modules['doc']->availableBlocks->statistic = 'Statistic';
$lang->block->modules['doc']->availableBlocks->docdynamic = 'Dynamic';
$lang->block->modules['doc']->availableBlocks->mycollection = 'My Collection';
$lang->block->modules['doc']->availableBlocks->recentupdate = 'Recently Update';
$lang->block->modules['doc']->availableBlocks->viewlist = 'Browse Leaderboard';
$lang->block->modules['doc']->availableBlocks->productdoc = $lang->productCommon . 'Document';
$lang->block->modules['doc']->availableBlocks->collectlist = 'Favorite Leaderboard';
$lang->block->modules['doc']->availableBlocks->projectdoc = $lang->projectCommon . 'Document';
$lang->block->orderByList = new stdclass();
$lang->block->orderByList->product = array();
@@ -528,40 +576,6 @@ $lang->block->typeList->testtask['blocked'] = 'Blockiert';
$lang->block->typeList->testtask['done'] = 'Erledigt';
$lang->block->typeList->testtask['all'] = 'Alle';
$lang->block->modules['project']->moreLinkList = new stdclass();
$lang->block->modules['project']->moreLinkList->recentproject = "project|browse|";
$lang->block->modules['project']->moreLinkList->statistic = "project|browse|";
$lang->block->modules['project']->moreLinkList->project = "project|browse|";
$lang->block->modules['project']->moreLinkList->cmmireport = 'weekly|index|';
$lang->block->modules['project']->moreLinkList->cmmiestimate = 'workestimation|index|';
$lang->block->modules['project']->moreLinkList->cmmiissue = 'issue|browse|';
$lang->block->modules['project']->moreLinkList->cmmirisk = 'risk|browse|';
$lang->block->modules['project']->moreLinkList->scrumlist = "project|execution|";
$lang->block->modules['project']->moreLinkList->scrumtest = 'testtask|browse|';
$lang->block->modules['project']->moreLinkList->scrumproduct = 'product|all|';
$lang->block->modules['project']->moreLinkList->sprint = "project|execution|";
$lang->block->modules['project']->moreLinkList->projectdynamic = "project|dynamic|";
$lang->block->modules['product']->moreLinkList = new stdclass();
$lang->block->modules['product']->moreLinkList->list = 'product|all|';
$lang->block->modules['product']->moreLinkList->story = 'my|story|type=%s';
$lang->block->modules['execution']->moreLinkList = new stdclass();
$lang->block->modules['execution']->moreLinkList->list = 'execution|all|status=%s&executionID=';
$lang->block->modules['execution']->moreLinkList->task = 'my|task|type=%s';
$lang->block->modules['qa']->moreLinkList = new stdclass();
$lang->block->modules['qa']->moreLinkList->bug = 'my|bug|type=%s';
$lang->block->modules['qa']->moreLinkList->case = 'my|testcase|type=%s';
$lang->block->modules['qa']->moreLinkList->testtask = 'testtask|browse|type=%s';
$lang->block->modules['todo']->moreLinkList = new stdclass();
$lang->block->modules['todo']->moreLinkList->list = 'my|todo|type=all';
$lang->block->modules['common'] = new stdclass();
$lang->block->modules['common']->moreLinkList = new stdclass();
$lang->block->modules['common']->moreLinkList->dynamic = 'company|dynamic|';
$lang->block->welcomeList['06:00'] = 'Guten Morgen, %s';
$lang->block->welcomeList['11:30'] = 'Guten Tag, %s';
$lang->block->welcomeList['13:30'] = 'Guten Tag, %s';
+48 -34
View File
@@ -332,6 +332,42 @@ $lang->block->default['full']['my']['10']['grid'] = 8;
$lang->block->default['full']['my']['10']['params']['orderBy'] = 'id_desc';
$lang->block->default['full']['my']['10']['params']['count'] = '15';
/* Doc module block. */
$lang->block->default['doc']['1']['title'] = 'Statistic';
$lang->block->default['doc']['1']['block'] = 'docstatistic';
$lang->block->default['doc']['1']['grid'] = 8;
$lang->block->default['doc']['2']['title'] = 'Dynamic';
$lang->block->default['doc']['2']['block'] = 'docdynamic';
$lang->block->default['doc']['2']['grid'] = 4;
$lang->block->default['doc']['3']['title'] = 'My Collection';
$lang->block->default['doc']['3']['block'] = 'docmycollection';
$lang->block->default['doc']['3']['grid'] = 8;
$lang->block->default['doc']['4']['title'] = 'Recently update';
$lang->block->default['doc']['4']['block'] = 'docrecentupdate';
$lang->block->default['doc']['4']['grid'] = 8;
$lang->block->default['doc']['5']['title'] = 'Browse Leaderboard';
$lang->block->default['doc']['5']['block'] = 'docviewlist';
$lang->block->default['doc']['5']['grid'] = 4;
if($config->vision == 'rnd')
{
$lang->block->default['doc']['6']['title'] = $lang->productCommon . 'Document';
$lang->block->default['doc']['6']['block'] = 'productdoc';
$lang->block->default['doc']['6']['grid'] = 8;
}
$lang->block->default['doc']['7']['title'] = 'Favorite Leaderboard';
$lang->block->default['doc']['7']['block'] = 'doccollectlist';
$lang->block->default['doc']['7']['grid'] = 4;
$lang->block->default['doc']['8']['title'] = $lang->projectCommon . 'Document';
$lang->block->default['doc']['8']['block'] = 'projectdoc';
$lang->block->default['doc']['8']['grid'] = 8;
$lang->block->count = 'Count';
$lang->block->type = 'Type';
$lang->block->orderBy = 'Order by';
@@ -360,6 +396,7 @@ $lang->block->moduleList['project'] = $lang->projectCommon;
$lang->block->moduleList['execution'] = $lang->execution->common;
$lang->block->moduleList['qa'] = 'Test';
$lang->block->moduleList['todo'] = 'Todo';
$lang->block->moduleList['doc'] = 'Doc';
$lang->block->modules['project'] = new stdclass();
$lang->block->modules['project']->availableBlocks = new stdclass();
@@ -414,6 +451,17 @@ $lang->block->modules['todo'] = new stdclass();
$lang->block->modules['todo']->availableBlocks = new stdclass();
$lang->block->modules['todo']->availableBlocks->list = 'Todo';
$lang->block->modules['doc'] = new stdclass();
$lang->block->modules['doc']->availableBlocks = new stdclass();
$lang->block->modules['doc']->availableBlocks->docstatistic = 'Statistic';
$lang->block->modules['doc']->availableBlocks->docdynamic = 'Dynamic';
$lang->block->modules['doc']->availableBlocks->docmycollection = 'My Collection';
$lang->block->modules['doc']->availableBlocks->docrecentupdate = 'Recently Update';
$lang->block->modules['doc']->availableBlocks->docviewlist = 'Browse Leaderboard';
$lang->block->modules['doc']->availableBlocks->productdoc = $lang->productCommon . 'Document';
$lang->block->modules['doc']->availableBlocks->doccollectlist = 'Favorite Leaderboard';
$lang->block->modules['doc']->availableBlocks->projectdoc = $lang->projectCommon . 'Document';
$lang->block->orderByList = new stdclass();
$lang->block->orderByList->product = array();
@@ -528,40 +576,6 @@ $lang->block->typeList->testtask['blocked'] = 'Blocked';
$lang->block->typeList->testtask['done'] = 'Done';
$lang->block->typeList->testtask['all'] = 'All';
$lang->block->modules['project']->moreLinkList = new stdclass();
$lang->block->modules['project']->moreLinkList->recentproject = "project|browse|";
$lang->block->modules['project']->moreLinkList->statistic = "project|browse|";
$lang->block->modules['project']->moreLinkList->project = "project|browse|";
$lang->block->modules['project']->moreLinkList->cmmireport = 'weekly|index|';
$lang->block->modules['project']->moreLinkList->cmmiestimate = 'workestimation|index|';
$lang->block->modules['project']->moreLinkList->cmmiissue = 'issue|browse|';
$lang->block->modules['project']->moreLinkList->cmmirisk = 'risk|browse|';
$lang->block->modules['project']->moreLinkList->scrumlist = "project|execution|";
$lang->block->modules['project']->moreLinkList->scrumtest = 'testtask|browse|';
$lang->block->modules['project']->moreLinkList->scrumproduct = 'product|all|';
$lang->block->modules['project']->moreLinkList->sprint = "project|execution|";
$lang->block->modules['project']->moreLinkList->projectdynamic = "project|dynamic|";
$lang->block->modules['product']->moreLinkList = new stdclass();
$lang->block->modules['product']->moreLinkList->list = 'product|all|';
$lang->block->modules['product']->moreLinkList->story = 'my|story|type=%s';
$lang->block->modules['execution']->moreLinkList = new stdclass();
$lang->block->modules['execution']->moreLinkList->list = 'execution|all|status=%s&executionID=';
$lang->block->modules['execution']->moreLinkList->task = 'my|task|type=%s';
$lang->block->modules['qa']->moreLinkList = new stdclass();
$lang->block->modules['qa']->moreLinkList->bug = 'my|bug|type=%s';
$lang->block->modules['qa']->moreLinkList->case = 'my|testcase|type=%s';
$lang->block->modules['qa']->moreLinkList->testtask = 'testtask|browse|type=%s';
$lang->block->modules['todo']->moreLinkList = new stdclass();
$lang->block->modules['todo']->moreLinkList->list = 'my|todo|type=all';
$lang->block->modules['common'] = new stdclass();
$lang->block->modules['common']->moreLinkList = new stdclass();
$lang->block->modules['common']->moreLinkList->dynamic = 'company|dynamic|';
$lang->block->welcomeList['06:00'] = 'Good morning, %s';
$lang->block->welcomeList['11:30'] = 'Good day, %s';
$lang->block->welcomeList['13:30'] = 'Good afternoon, %s';
+48 -34
View File
@@ -332,6 +332,42 @@ $lang->block->default['full']['my']['10']['grid'] = 8;
$lang->block->default['full']['my']['10']['params']['orderBy'] = 'id_desc';
$lang->block->default['full']['my']['10']['params']['count'] = '15';
/* Doc module block. */
$lang->block->default['doc']['1']['title'] = 'Statistic';
$lang->block->default['doc']['1']['block'] = 'docstatistic';
$lang->block->default['doc']['1']['grid'] = 8;
$lang->block->default['doc']['2']['title'] = 'Dynamic';
$lang->block->default['doc']['2']['block'] = 'docdynamic';
$lang->block->default['doc']['2']['grid'] = 4;
$lang->block->default['doc']['3']['title'] = 'My Collection';
$lang->block->default['doc']['3']['block'] = 'docmycollection';
$lang->block->default['doc']['3']['grid'] = 8;
$lang->block->default['doc']['4']['title'] = 'Recently update';
$lang->block->default['doc']['4']['block'] = 'docrecentupdate';
$lang->block->default['doc']['4']['grid'] = 8;
$lang->block->default['doc']['5']['title'] = 'Browse Leaderboard';
$lang->block->default['doc']['5']['block'] = 'docviewlist';
$lang->block->default['doc']['5']['grid'] = 4;
if($config->vision == 'rnd')
{
$lang->block->default['doc']['6']['title'] = $lang->productCommon . 'Document';
$lang->block->default['doc']['6']['block'] = 'productdoc';
$lang->block->default['doc']['6']['grid'] = 8;
}
$lang->block->default['doc']['7']['title'] = 'Favorite Leaderboard';
$lang->block->default['doc']['7']['block'] = 'doccollectlist';
$lang->block->default['doc']['7']['grid'] = 4;
$lang->block->default['doc']['8']['title'] = $lang->projectCommon . 'Document';
$lang->block->default['doc']['8']['block'] = 'projectdoc';
$lang->block->default['doc']['8']['grid'] = 8;
$lang->block->count = 'Numéro';
$lang->block->type = 'Type';
$lang->block->orderBy = 'Trié par';
@@ -360,6 +396,7 @@ $lang->block->moduleList['project'] = $lang->projectCommon;
$lang->block->moduleList['execution'] = $lang->execution->common;
$lang->block->moduleList['qa'] = 'Test';
$lang->block->moduleList['todo'] = 'Todo';
$lang->block->moduleList['doc'] = 'Doc';
$lang->block->modules['project'] = new stdclass();
$lang->block->modules['project']->availableBlocks = new stdclass();
@@ -414,6 +451,17 @@ $lang->block->modules['todo'] = new stdclass();
$lang->block->modules['todo']->availableBlocks = new stdclass();
$lang->block->modules['todo']->availableBlocks->list = 'Todo';
$lang->block->modules['doc'] = new stdclass();
$lang->block->modules['doc']->availableBlocks = new stdclass();
$lang->block->modules['doc']->availableBlocks->docstatistic = 'Statistic';
$lang->block->modules['doc']->availableBlocks->docdynamic = 'Dynamic';
$lang->block->modules['doc']->availableBlocks->docmycollection = 'My Collection';
$lang->block->modules['doc']->availableBlocks->docrecentupdate = 'Recently Update';
$lang->block->modules['doc']->availableBlocks->docviewlist = 'Browse Leaderboard';
$lang->block->modules['doc']->availableBlocks->productdoc = $lang->productCommon . 'Document';
$lang->block->modules['doc']->availableBlocks->doccollectlist = 'Favorite Leaderboard';
$lang->block->modules['doc']->availableBlocks->projectdoc = $lang->projectCommon . 'Document';
$lang->block->orderByList = new stdclass();
$lang->block->orderByList->product = array();
@@ -528,40 +576,6 @@ $lang->block->typeList->testtask['blocked'] = 'Bloquées';
$lang->block->typeList->testtask['done'] = 'Jouées';
$lang->block->typeList->testtask['all'] = 'Toutes';
$lang->block->modules['project']->moreLinkList = new stdclass();
$lang->block->modules['project']->moreLinkList->recentproject = "project|browse|";
$lang->block->modules['project']->moreLinkList->statistic = "project|browse|";
$lang->block->modules['project']->moreLinkList->project = "project|browse|";
$lang->block->modules['project']->moreLinkList->cmmireport = 'weekly|index|';
$lang->block->modules['project']->moreLinkList->cmmiestimate = 'workestimation|index|';
$lang->block->modules['project']->moreLinkList->cmmiissue = 'issue|browse|';
$lang->block->modules['project']->moreLinkList->cmmirisk = 'risk|browse|';
$lang->block->modules['project']->moreLinkList->scrumlist = "project|execution|";
$lang->block->modules['project']->moreLinkList->scrumtest = 'testtask|browse|';
$lang->block->modules['project']->moreLinkList->scrumproduct = 'product|all|';
$lang->block->modules['project']->moreLinkList->sprint = "project|execution|";
$lang->block->modules['project']->moreLinkList->projectdynamic = "project|dynamic|";
$lang->block->modules['product']->moreLinkList = new stdclass();
$lang->block->modules['product']->moreLinkList->list = 'product|all|';
$lang->block->modules['product']->moreLinkList->story = 'my|story|type=%s';
$lang->block->modules['execution']->moreLinkList = new stdclass();
$lang->block->modules['execution']->moreLinkList->list = 'execution|all|status=%s&executionID=';
$lang->block->modules['execution']->moreLinkList->task = 'my|task|type=%s';
$lang->block->modules['qa']->moreLinkList = new stdclass();
$lang->block->modules['qa']->moreLinkList->bug = 'my|bug|type=%s';
$lang->block->modules['qa']->moreLinkList->case = 'my|testcase|type=%s';
$lang->block->modules['qa']->moreLinkList->testtask = 'testtask|browse|type=%s';
$lang->block->modules['todo']->moreLinkList = new stdclass();
$lang->block->modules['todo']->moreLinkList->list = 'my|todo|type=all';
$lang->block->modules['common'] = new stdclass();
$lang->block->modules['common']->moreLinkList = new stdclass();
$lang->block->modules['common']->moreLinkList->dynamic = 'company|dynamic|';
$lang->block->welcomeList['06:00'] = 'Bonjour, %s';
$lang->block->welcomeList['11:30'] = 'Bonjour, %s';
$lang->block->welcomeList['13:30'] = 'Bonjour, %s';
+48 -34
View File
@@ -332,6 +332,42 @@ $lang->block->default['full']['my']['10']['grid'] = 8;
$lang->block->default['full']['my']['10']['params']['orderBy'] = 'id_desc';
$lang->block->default['full']['my']['10']['params']['count'] = '15';
/* Doc module block. */
$lang->block->default['doc']['1']['title'] = '文档统计';
$lang->block->default['doc']['1']['block'] = 'docstatistic';
$lang->block->default['doc']['1']['grid'] = 8;
$lang->block->default['doc']['2']['title'] = '文档动态';
$lang->block->default['doc']['2']['block'] = 'docdynamic';
$lang->block->default['doc']['2']['grid'] = 4;
$lang->block->default['doc']['3']['title'] = '我的收藏';
$lang->block->default['doc']['3']['block'] = 'docmycollection';
$lang->block->default['doc']['3']['grid'] = 8;
$lang->block->default['doc']['4']['title'] = '最近更新';
$lang->block->default['doc']['4']['block'] = 'docrecentupdate';
$lang->block->default['doc']['4']['grid'] = 8;
$lang->block->default['doc']['5']['title'] = '浏览排行榜';
$lang->block->default['doc']['5']['block'] = 'docviewlist';
$lang->block->default['doc']['5']['grid'] = 4;
if($config->vision == 'rnd')
{
$lang->block->default['doc']['6']['title'] = $lang->productCommon . '文档';
$lang->block->default['doc']['6']['block'] = 'productdoc';
$lang->block->default['doc']['6']['grid'] = 8;
}
$lang->block->default['doc']['7']['title'] = '收藏排行榜';
$lang->block->default['doc']['7']['block'] = 'doccollectlist';
$lang->block->default['doc']['7']['grid'] = 4;
$lang->block->default['doc']['8']['title'] = $lang->projectCommon . '文档';
$lang->block->default['doc']['8']['block'] = 'projectdoc';
$lang->block->default['doc']['8']['grid'] = 8;
$lang->block->count = '数量';
$lang->block->type = '类型';
$lang->block->orderBy = '排序';
@@ -360,6 +396,7 @@ $lang->block->moduleList['project'] = $lang->projectCommon;
$lang->block->moduleList['execution'] = $lang->execution->common;
$lang->block->moduleList['qa'] = '测试';
$lang->block->moduleList['todo'] = '待办';
$lang->block->moduleList['doc'] = '文档';
$lang->block->modules['project'] = new stdclass();
$lang->block->modules['project']->availableBlocks = new stdclass();
@@ -414,6 +451,17 @@ $lang->block->modules['todo'] = new stdclass();
$lang->block->modules['todo']->availableBlocks = new stdclass();
$lang->block->modules['todo']->availableBlocks->list = '待办列表';
$lang->block->modules['doc'] = new stdclass();
$lang->block->modules['doc']->availableBlocks = new stdclass();
$lang->block->modules['doc']->availableBlocks->docstatistic = '文档统计';
$lang->block->modules['doc']->availableBlocks->docdynamic = '文档动态';
$lang->block->modules['doc']->availableBlocks->docmycollection = '我的收藏';
$lang->block->modules['doc']->availableBlocks->docrecentupdate = '最近更新';
$lang->block->modules['doc']->availableBlocks->docviewlist = '浏览排行榜';
$lang->block->modules['doc']->availableBlocks->productdoc = $lang->productCommon . '文档';
$lang->block->modules['doc']->availableBlocks->doccollectlist = '收藏排行榜';
$lang->block->modules['doc']->availableBlocks->projectdoc = $lang->projectCommon . '文档';
$lang->block->orderByList = new stdclass();
$lang->block->orderByList->product = array();
@@ -528,40 +576,6 @@ $lang->block->typeList->testtask['blocked'] = '阻塞版本';
$lang->block->typeList->testtask['done'] = '已测版本';
$lang->block->typeList->testtask['all'] = '全部';
$lang->block->modules['project']->moreLinkList = new stdclass();
$lang->block->modules['project']->moreLinkList->recentproject = 'project|browse|';
$lang->block->modules['project']->moreLinkList->statistic = 'project|browse|';
$lang->block->modules['project']->moreLinkList->project = 'project|browse|';
$lang->block->modules['project']->moreLinkList->cmmireport = 'weekly|index|';
$lang->block->modules['project']->moreLinkList->cmmiestimate = 'workestimation|index|';
$lang->block->modules['project']->moreLinkList->cmmiissue = 'issue|browse|';
$lang->block->modules['project']->moreLinkList->cmmirisk = 'risk|browse|';
$lang->block->modules['project']->moreLinkList->scrumlist = 'project|execution|';
$lang->block->modules['project']->moreLinkList->scrumtest = 'project|testtask|';
$lang->block->modules['project']->moreLinkList->scrumproduct = 'product|all|';
$lang->block->modules['project']->moreLinkList->sprint = 'project|execution|';
$lang->block->modules['project']->moreLinkList->projectdynamic = 'project|dynamic|';
$lang->block->modules['product']->moreLinkList = new stdclass();
$lang->block->modules['product']->moreLinkList->list = 'product|all|';
$lang->block->modules['product']->moreLinkList->story = 'my|story|type=%s';
$lang->block->modules['execution']->moreLinkList = new stdclass();
$lang->block->modules['execution']->moreLinkList->list = 'execution|all|status=%s&executionID=';
$lang->block->modules['execution']->moreLinkList->task = 'my|task|type=%s';
$lang->block->modules['qa']->moreLinkList = new stdclass();
$lang->block->modules['qa']->moreLinkList->bug = 'my|bug|type=%s';
$lang->block->modules['qa']->moreLinkList->case = 'my|testcase|type=%s';
$lang->block->modules['qa']->moreLinkList->testtask = 'testtask|browse|type=%s';
$lang->block->modules['todo']->moreLinkList = new stdclass();
$lang->block->modules['todo']->moreLinkList->list = 'my|todo|type=all';
$lang->block->modules['common'] = new stdclass();
$lang->block->modules['common']->moreLinkList = new stdclass();
$lang->block->modules['common']->moreLinkList->dynamic = 'company|dynamic|';
$lang->block->welcomeList['06:00'] = '%s,早上好!';
$lang->block->welcomeList['11:30'] = '%s,中午好!';
$lang->block->welcomeList['13:30'] = '%s,下午好!';
+92 -3
View File
@@ -264,14 +264,14 @@ class blockModel extends model
$blocks = $this->lang->block->default[$type]['project'];
/* Mark project block has init. */
$this->loadModel('setting')->setItem("$account.$module.{$type}common.blockInited@$vision", true);
$this->loadModel('setting')->setItem("$account.$module.{$type}common.blockInited@$vision", '1');
}
else
{
$blocks = $module == 'my' ? $this->lang->block->default[$flow][$module] : $this->lang->block->default[$module];
/* Mark this app has init. */
$this->loadModel('setting')->setItem("$account.$module.common.blockInited@$vision", true);
$this->loadModel('setting')->setItem("$account.$module.common.blockInited@$vision", '1');
}
$this->loadModel('setting')->setItem("$account.$module.block.initVersion", $this->config->block->version);
@@ -558,6 +558,7 @@ class blockModel extends model
if($module == 'project') return $this->getProjectStatisticParams();
if($module == 'execution') return $this->getExecutionStatisticParams();
if($module == 'qa') return $this->getQaStatisticParams();
if($module == 'doc') return $this->getDocStatisticParams();
$params = new stdclass();
$params = $this->appendCountParams($params);
@@ -628,6 +629,17 @@ class blockModel extends model
return json_encode($params);
}
/**
* Get document statistic params.
*
* @access public
* @return bool
*/
public function getDocStatisticParams()
{
return false;
}
/**
* Get recent project pararms.
*
@@ -718,7 +730,7 @@ class blockModel extends model
$params = $this->appendCountParams();
$params->type['name'] = $this->lang->block->type;
$params->type['options'] = $this->lang->issue->labelList;
$params->type['options'] = $this->lang->issue->featureBar['browse'];
$params->type['control'] = 'select';
$params->orderBy['name'] = $this->lang->block->orderBy;
@@ -1061,6 +1073,83 @@ class blockModel extends model
return false;
}
/**
* Get document dynamic params.
*
* @access public
* @return bool
*/
public function getDocDynamicParams()
{
return false;
}
/**
* Get my collection params.
*
* @access public
* @return bool
*/
public function getDocMyCollectionParams()
{
return false;
}
/**
* Get recent update params.
*
* @access public
* @return bool
*/
public function getDocRecentUpdateParams()
{
return false;
}
/**
* Get view list params.
*
* @access public
* @return bool
*/
public function getDocViewlistParams()
{
return false;
}
/**
* Get product document params.
*
* @access public
* @return bool
*/
public function getProductDocParams()
{
return false;
}
/**
* Get collect list params.
*
* @access public
* @return bool
*/
public function getDocCollectListParams()
{
return false;
}
/**
* Get project document params.
*
* @access public
* @return bool
*/
public function getProjectDocParams()
{
return false;
}
/**
* Get the total estimated man hours required.
*
@@ -0,0 +1,37 @@
<?php if(empty($actions)): ?>
<div class='empty-tip'><?php echo $lang->block->emptyTip;?></div>
<?php else:?>
<style>
.block-docdynamic .timeline > li .timeline-text {max-width: 600px; display: block; white-space: nowrap; overflow: hidden; text-overflow: clip; max-height: 20px;}
.block-docdynamic .panel-body {padding-top: 0;}
.timeline > li:before {left: -26px;}
.timeline > li + li:after {left: -23px;}
.timeline-text {margin-left: -18px;}
.block-docdynamic .label-action {padding: 0 6px;}
.block-docdynamic .label-action + a {padding-left: 6px;}
.timeline > li.active:before {left: -30px; background-color: #FFF;}
.timeline > li.collected > div:after {background-color: #FFAF65;}
.timeline > li.releaseddoc > div:after {background-color: #66A2FF;}
.timeline > li > div:after {left: -27px;}
.timeline > li > div > .timeline-tag, .timeline > li > div > .timeline-text > .label-action {color: #838A9D;}
.timeline > li > div > .timeline-text > a {color: #313C52;}
</style>
<div class='panel-body scrollbar-hover'>
<ul class="timeline timeline-tag-left no-margin">
<?php
$i = 0;
foreach($actions as $action)
{
$user = zget($users, $action->actor);
$class = $action->major ? 'active' : '';
if(in_array($action->action, array('releaseddoc', 'collected'))) $class .= " {$action->action}";
echo "<li class='$class'><div>";
if($action->objectLink) printf($lang->block->dynamicInfo, $action->date, $user, $action->actionLabel, $action->objectLabel, $action->objectLink, $action->objectName, $action->objectName);
if(!$action->objectLink) printf($lang->block->noLinkDynamic, $action->date, $action->objectName, $user, $action->actionLabel, $action->objectLabel, ' ' . $action->objectName);
echo "</div></li>";
$i++;
}
?>
</ul>
</div>
<?php endif;?>
@@ -0,0 +1,80 @@
<?php
/**
* The docmycollectionblock view file of block module of ZenTaoPMS.
*
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Yanyi Cao <caoyanyi@easycorp.ltd>
* @package block
* @version $Id$
* @link http://www.zentao.net
*/
?>
<style>
.block-docmycollection .panel-body {padding: 0px 10px 20px;}
.block-docmycollection .doc-list {display: flex; flex-wrap: wrap; padding: 0 4px 0 0;}
.block-docmycollection .doc-list > .doc-box {border: unset; flex: 0 1 50%; padding: 8px;}
.block-docmycollection .doc-list > .doc-box > button.btn {padding: 5px 10px; height: 100%; width: 100%; cursor: pointer; white-space: unset; text-align: unset; border: 1px solid rgba(227, 228, 233, 0.6)}
.block-docmycollection .doc-list > .doc-box > .btn:hover {background: unset;}
.block-docmycollection .doc-list > .doc-box > .btn.no-priv {cursor: not-allowed; pointer-events: unset;}
.block-docmycollection .doc-list > .doc-box > .btn.no-priv p {pointer-events: none;}
.block-docmycollection .doc-list > .doc-box .date-interval {float: right; padding: 8px 0px;}
.block-docmycollection .doc-list > .doc-box > .btn > h4 {padding-right: 5px;}
.block-docmycollection .doc-list > .doc-item .file-icon {margin-right: 2px;}
.block-docmycollection .doc-list > .doc-box .plug-title {height: 16px; overflow: hidden;}
.block-docmycollection.block-sm .doc-list > .doc-box {flex: 0 1 100%;}
</style>
<?php $canView = common::hasPriv('doc', 'view');?>
<div class="panel-body">
<?php if(empty($docList)):?>
<div class='table-empty-tip'><p><span class='text-muted'><?php echo $lang->doc->noDoc;?></p></span></div>
<?php else:?>
<div class="doc-list">
<?php foreach($docList as $doc):?>
<div class="doc-box">
<button class="btn shadow-primary-hover <?php if(!$canView) echo 'no-priv';?>" data-link='<?php echo $this->createLink("doc", "view", "docID=$doc->id");?>'>
<span class='date-interval text-muted'>
<?php
$interval = $doc->editInterval;
$editTip = $lang->doc->todayUpdated;
if($interval->year)
{
$editTip = sprintf($lang->doc->yearsUpdated, $interval->year);
}
elseif($interval->month)
{
$editTip = sprintf($lang->doc->monthsUpdated, $interval->month);
}
elseif($interval->day)
{
$editTip = sprintf($lang->doc->daysUpdated, $interval->day);
}
echo $editTip;
?>
</span>
<h4 class="plug-title" title="<?php echo $doc->title;?>">
<?php
$docType = $doc->type == 'text' ? 'wiki-file' : $doc->type;
echo html::image("static/svg/{$docType}.svg", "class='file-icon'");
?>
<?php echo $doc->title;?>
</h4>
<p class='edit-date text-muted'><?php echo $lang->doc->editedDate . (common::checkNotCN() ? ': ' : ':') . $doc->editedDate;?></p>
</button>
</div>
<?php endforeach;?>
</div>
<?php endif;?>
</div>
<script>
$(function()
{
$('.doc-box .btn').on('click', function()
{
if($(this).hasClass('no-priv')) return;
location.href = $(this).data('link');
});
});
</script>
@@ -0,0 +1,80 @@
<?php
/**
* The docrecentupdateblock view file of block module of ZenTaoPMS.
*
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Yanyi Cao <caoyanyi@easycorp.ltd>
* @package block
* @version $Id$
* @link http://www.zentao.net
*/
?>
<style>
.block-docrecentupdate .panel-body {padding: 0px 10px 20px;}
.block-docrecentupdate .doc-list {display: flex; flex-wrap: wrap; padding: 0 4px 0 0;}
.block-docrecentupdate .doc-list > .doc-box {border: unset; flex: 0 1 33%; padding: 8px;}
.block-docrecentupdate .doc-list > .doc-box > button.btn {padding: 5px 10px; height: 100%; width: 100%; cursor: pointer; white-space: unset; text-align: unset; border: 1px solid rgba(227, 228, 233, 0.6)}
.block-docrecentupdate .doc-list > .doc-box > .btn:hover {background: unset;}
.block-docrecentupdate .doc-list > .doc-box > .btn.no-priv {cursor: not-allowed; pointer-events: unset;}
.block-docrecentupdate .doc-list > .doc-box > .btn.no-priv p {pointer-events: none;}
.block-docrecentupdate .doc-list > .doc-box .date-interval {float: right; padding: 8px 0px;}
.block-docrecentupdate .doc-list > .doc-box > .btn > h4 {padding-right: 5px;}
.block-docrecentupdate .doc-list > .doc-item .file-icon {margin-right: 2px;}
.block-docrecentupdate .doc-list > .doc-box .plug-title {height: 16px; overflow: hidden;}
.block-docrecentupdate.block-sm .doc-list > .doc-box {flex: 0 1 100%;}
</style>
<?php $canView = common::hasPriv('doc', 'view');?>
<div class="panel-body">
<?php if(empty($docList)):?>
<div class='table-empty-tip'><p><span class='text-muted'><?php echo $lang->doc->noDoc;?></p></span></div>
<?php else:?>
<div class="doc-list">
<?php foreach($docList as $doc):?>
<div class="doc-box">
<button class="btn shadow-primary-hover <?php if(!$canView) echo 'no-priv';?>" data-link='<?php echo $this->createLink("doc", "view", "docID=$doc->id");?>'>
<span class='date-interval text-muted'>
<?php
$interval = $doc->editInterval;
$editTip = $lang->doc->todayUpdated;
if($interval->year)
{
$editTip = sprintf($lang->doc->yearsUpdated, $interval->year);
}
elseif($interval->month)
{
$editTip = sprintf($lang->doc->monthsUpdated, $interval->month);
}
elseif($interval->day)
{
$editTip = sprintf($lang->doc->daysUpdated, $interval->day);
}
echo $editTip;
?>
</span>
<h4 class="plug-title" title="<?php echo $doc->title;?>">
<?php
$docType = $doc->type == 'text' ? 'wiki-file' : $doc->type;
echo html::image("static/svg/{$docType}.svg", "class='file-icon'");
?>
<?php echo $doc->title;?>
</h4>
<p class='edit-date text-muted'><?php echo $lang->doc->editedDate . (common::checkNotCN() ? ': ' : ':') . $doc->editedDate;?></p>
</button>
</div>
<?php endforeach;?>
</div>
<?php endif;?>
</div>
<script>
$(function()
{
$('.doc-box .btn').on('click', function()
{
if($(this).hasClass('no-priv')) return;
location.href = $(this).data('link');
});
});
</script>
@@ -0,0 +1,79 @@
<?php
/**
* The statistic view file of block module of ZenTaoPMS.
*
* @copyright Copyright 2009-2023 禅道软件(青岛)有限公司(ZenTao Software (Qingdao) Co., Ltd. www.cnezsoft.com)
* @license ZPL(http://zpl.pub/page/zplv12.html) or AGPL(https://www.gnu.org/licenses/agpl-3.0.en.html)
* @author Yanyi Cao <caoyanyi@easycorp.ltd>
* @package block
* @version $Id$
* @link http://www.zentao.net
*/
?>
<style>
.block-docstatistic .flex {display: flex; flex-wrap: nowrap; flex-direction: row; justify-content: space-between; flex: auto;}
.block-docstatistic .flex-column {flex-direction: column; padding-left: 10px;}
.block-docstatistic .statistic {flex: 0 1 32%;}
.block-docstatistic .created {flex: 0 1 48%;}
.block-docstatistic .edited {flex: 0 1 16%; padding-left: 20px;}
.block-docstatistic .divider {border-right: 1px solid #eee; padding-right: 12%;}
.block-docstatistic .panel-body {padding-top: 0;}
.block-docstatistic.block-sm .flex {justify-content: start;}
.block-docstatistic.block-sm .panel-body.flex {flex-direction: column;}
.block-docstatistic.block-sm .divider {border-right: none;}
.block-docstatistic.block-sm .statistic .flex {margin-top: -28px;}
.block-docstatistic.block-sm .tile {padding: 10px 32px 20px;}
.block-docstatistic.block-sm .panel-body {margin-top: 0px; padding: 10px;}
.block-docstatistic.block-sm .flex-column .flex .tile:nth-child(1) {padding-left: 0;}
.block-docstatistic.block-sm .edited {padding-left: 10px;}
.block-docstatistic.block-sm .flex-column {border-bottom: 1px solid #eee;}
.block-docstatistic.block-sm .flex-column:last-child {border-bottom: none;}
</style>
<div class='panel-move-handler'></div>
<div class="panel-body flex">
<div class='flex flex-column statistic'>
<div class='flex'>
<div class="tile">
<div class="tile-amount"><?php echo (int)$statistic->totalDocs;?></div>
<div class="tile-title"><?php echo $lang->doc->allDoc;?></div>
</div>
<div class="tile divider">
<div class="tile-amount"><?php echo (int)$statistic->todayEditedDocs;?></div>
<div class="tile-title"><?php echo $lang->doc->todayEdited;?></div>
</div>
</div>
</div>
<div class='flex flex-column created'>
<div class='flex'>
<?php if(common::hasPriv('doc', 'mySpace')):?>
<a class="tile" href="<?php echo $this->createLink('doc', 'mySpace', 'type=createdBy');?>">
<?php else:?>
<div class="tile">
<?php endif;?>
<div class="tile-amount"><?php echo (int)$statistic->myDocs;?></div>
<div class="tile-title"><?php echo $lang->doc->docCreated;?></div>
<?php if(common::hasPriv('doc', 'mySpace')):?>
</a>
<?php else:?>
</div>
<?php endif;?>
<div class="tile">
<div class="tile-amount"><?php echo (int)$statistic->myDoc->docViews;?></div>
<div class="tile-title"><?php echo $lang->doc->docViews;?></div>
</div>
<div class="tile divider">
<div class="tile-amount"><?php echo (int)$statistic->myDoc->docCollects;?></div>
<div class="tile-title"><?php echo $lang->doc->docCollects;?></div>
</div>
</div>
</div>
<div class='flex flex-column edited'>
<div class='flex'>
<div class="tile">
<div class="tile-amount"><?php echo (int)$statistic->myEditedDocs;?></div>
<div class="tile-title"><?php echo $lang->doc->docEdited;?></div>
</div>
</div>
</div>
</div>
+7 -3
View File
@@ -2,7 +2,7 @@
<div class='empty-tip'><?php echo $lang->block->emptyTip;?></div>
<?php else:?>
<style>
.block-dynamic .timeline > li .timeline-text {max-width: 600px; display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-height: 20px;}
.block-dynamic .timeline > li .timeline-text {max-width: 600px; display: block; white-space: nowrap; overflow: hidden; text-overflow: clip; max-height: 20px;}
.block-dynamic .panel-body {padding-top: 0;}
.timeline > li:before {left: -26px;}
.timeline > li + li:after {left: -23px;}
@@ -10,6 +10,9 @@
.block-dynamic .label-action {padding: 0 6px;}
.block-dynamic .label-action + a {padding-left: 6px;}
.timeline > li.active:before {left: -30px;}
.timeline > li.collected:before, .timeline > li.releaseddoc:before {background-color: #FFF;}
.timeline > li.collected > div:after {background-color: #FFAF65;}
.timeline > li.releaseddoc > div:after {background-color: #66A2FF;}
.timeline > li > div:after {left: -27px;}
.timeline > li > div > .timeline-tag, .timeline > li > div > .timeline-text > .label-action {color: #838A9D;}
.timeline > li > div > .timeline-text > a {color: #313C52;}
@@ -24,8 +27,9 @@
$user = zget($users, $action->actor);
if($action->action == 'login' or $action->action == 'logout') $action->objectName = $action->objectLabel = '';
if($action->objectType == 'sonarqubeproject') $action->objectName = $action->extra;
$class = $action->major ? "class='active'" : '';
echo "<li $class><div>";
$class = $action->major ? 'active' : '';
if(in_array($action->action, array('releaseddoc', 'collected'))) $class .= " {$action->action}";
echo "<li class='$class'><div>";
if($action->objectLink) printf($lang->block->dynamicInfo, $action->date, $user, $action->actionLabel, $action->objectLabel, $action->objectLink, $action->objectName, $action->objectName);
if(!$action->objectLink) printf($lang->block->noLinkDynamic, $action->date, $action->objectName, $user, $action->actionLabel, $action->objectLabel, ' ' . $action->objectName);
echo "</div></li>";
+2
View File
@@ -105,6 +105,8 @@ class branchModel extends model
*/
public function getPairs($productID, $params = '', $executionID = 0, $mergedBranches = '')
{
if(!$productID) $productID = 0;
$executionBranches = array();
if($executionID)
{
+1 -1
View File
@@ -62,7 +62,7 @@ class bugModel extends model
$bug = fixer::input('post')
->setDefault('openedBy', $this->app->user->account)
->setDefault('openedDate', $now)
->setDefault('project,execution,story,task', 0)
->setDefault('project,execution,story,task,duplicateBug,linkBug', 0)
->setDefault('openedBuild', '')
->setDefault('notifyEmail', '')
->setDefault('deadline', '0000-00-00')
+1 -46
View File
@@ -176,52 +176,7 @@ class chart extends control
$chart = $this->chart->getByID($chartID);
$filterFormat = array();
foreach($filters as $filter)
{
$field = $filter['field'];
if(!isset($filter['default'])) continue;
$default = $filter['default'];
switch($filter['type'])
{
case 'select':
if(empty($default)) break;
$default = array_filter($default, function($val){return !empty($val);});
$value = "('" . implode("', '", $default) . "')";
$filterFormat[$field] = array('operator' => 'IN', 'value' => $value);
break;
case 'input':
$filterFormat[$field] = array('operator' => 'like', 'value' => "'%$default%'");
break;
case 'date':
case 'datetime':
$begin = $default['begin'];
$end = $default['end'];
if(empty($begin) or empty($end)) break;
$value = "'$begin' and '$end'";
$filterFormat[$field] = array('operator' => 'BETWEEN', 'value' => $value);
break;
case 'condition':
$operator = $filter['operator'];
$value = $filter['value'];
if(in_array($operator, array('IN', 'NOT IN')))
{
$valueArr = explode(',', $value);
foreach($valueArr as $key => $val) $valueArr[$key] = '"' . $val . '"';
$value = '(' . implode(',', $valueArr) . ')';
}
elseif(in_array($operator, array('IS NOT NULL', 'IS NULL')))
{
$value = '';
}
$filterFormat[$field] = array('operator' => $operator, 'value' => $value);
break;
}
}
$filterFormat = $this->chart->getFilterFormat($filters);
$sql = str_replace(';', '', "$post->sql");
$fields = $post->fieldSettings;
+1 -1
View File
@@ -48,6 +48,6 @@
.filter-items{display: flex; flex: 1; flex-wrap: wrap;}
.filter-item{padding: 0 16px 5px 0;}
.filter-item-grow{flex-grow: 1;}
.queryBtn{display: flex; align-items: center; padding-bottom: 5px;}
.queryBtn{display: flex; align-items: center; padding-bottom: 5px; flex-basis: 60px;}
.filterBox .picker-selections{width: 128px; height: 32px; overflow: hidden; text-overflow: clip; white-space: nowrap;}
+12
View File
@@ -17,6 +17,7 @@ function ajaxGetChart(check = true, chart = DataStorage.chart, echart = window.e
var data = JSON.parse(resp);
if(echart)
{
echart.resize();
echart.clear();
echart.setOption(data, true);
$('.btn-export').removeClass('hidden');
@@ -24,6 +25,17 @@ function ajaxGetChart(check = true, chart = DataStorage.chart, echart = window.e
});
}
function resizeChart()
{
var filterHeight = $('.main-col .cell #filterContent').height();
$('.main-col .cell #draw').css('height', 'calc(100% - ' + (filterHeight + 16) + 'px)')
if(echart)
{
echart.resize();
}
}
/**
* Init picker.
*
+41 -20
View File
@@ -7,19 +7,22 @@ $(function()
chartMap = new Map();
if(charts.length > 0)
{
charts.forEach(function(chart)
var chartPros = charts.map(function(chart)
{
var echartDom = $('#chartDraw' + chart.currentGroup + chart.id).get(0);
var echartDom = $('#chartDraw' + chart.currentGroup + '_' + chart.id).get(0);
var echart = echarts.init(echartDom);
ajaxGetChart(false, chart, echart);
renderFilters(chart);
chartMap.set(chart.currentGroup + chart.id, chart);
chartMap.set(chart.cudrrentGroup + chart.id, chart);
return renderFilters(chart);
});
}
calcPreviewGrowFilter();
$('body').resize(() => {calcPreviewGrowFilter(true);});
Promise.all(chartPros).then(function()
{
calcPreviewGrowFilter();
$('body').resize(() => {calcPreviewGrowFilter(true);});
});
}
$('[data-toggle="tooltip"]').tooltip();
})
@@ -127,12 +130,13 @@ function calcPreviewGrowFilter(resize = false)
/* When body resize, resize echarts. */
if(resize)
{
var echartDom = $('#chartDraw' + chart.currentGroup + chart.id).get(0);
var echartDom = $('#chartDraw' + chart.currentGroup + '_' + chart.id).get(0);
var echart = echarts.init(echartDom);
echart.resize();
}
var $filterItems = $('#filterItems' + chart.currentGroup + chart.id + ' .filter-items');
var $filterBox = $('#filterItems' + chart.currentGroup + '_' + chart.id);
var $filterItems = $filterBox.find('.filter-items');
/* When refreshing this page, ZenTao load this page twice, when the first load isn't complete, jump back to index and load the second time,
the first load can't calc filter width, can't get the element using jQuery at first load. */
var hasInit = true;
@@ -146,8 +150,12 @@ function calcPreviewGrowFilter(resize = false)
var domWidth = $filterItems[0].getBoundingClientRect().width;
var nowWidth = domWidth;
var lineWrap = false;
var nowCount = 0;
var canGrowTotal = 0;
$filterBox.find('.query-inside').addClass('hidden');
$filterBox.find('.query-outside').addClass('hidden');
chart.filters.forEach(function(filter, index)
{
var nowItem = '.filter-item-' + index;
@@ -169,6 +177,7 @@ function calcPreviewGrowFilter(resize = false)
canGrowTotal += nowCount;
nowWidth = domWidth - filterWidth;
nowCount = 1;
lineWrap = true;
}
});
@@ -179,24 +188,36 @@ function calcPreviewGrowFilter(resize = false)
var nowItem = '.filter-item-' + index;
if(canGrowTotal >= index + 1) $filterItems.find(nowItem).addClass('filter-item-grow');
});
var queryType =(!lineWrap && nowWidth >= 60) ? '.query-inside' : '.query-outside';
$filterBox.find(queryType).removeClass('hidden');
});
}
function renderFilters(chart)
{
if(chart.filters.length == 0) return;
var fieldNames = {};
Object.keys(chart.fieldSettings).forEach(function(key){fieldNames[key] = chart.fieldSettings[key].name;});
$.post(createLink('chart', 'ajaxGetFilterForm', 'chartID=' + chart.id), {fieldList: fieldNames, fieldSettings: chart.fieldSettings, filters: chart.filters, langs: chart.langs}, function(resp)
return new Promise(function(resolve, reject)
{
resp = JSON.parse(resp);
chart.filters.forEach(function(filter, index)
if(chart.filters.length == 0)
{
var $filterItems = $('#filterItems' + chart.currentGroup + chart.id + ' .filter-items');
$filterItems.append(renderFilterItem(filter, resp, index));
resolve();
return;
}
var fieldNames = {};
Object.keys(chart.fieldSettings).forEach(function(key){fieldNames[key] = chart.fieldSettings[key].name;});
$.post(createLink('chart', 'ajaxGetFilterForm', 'chartID=' + chart.id), {fieldList: fieldNames, fieldSettings: chart.fieldSettings, filters: chart.filters, langs: chart.langs}, function(resp)
{
resp = JSON.parse(resp);
var $filterItems = $('#filterItems' + chart.currentGroup + '_' + chart.id + ' .filter-items');
chart.filters.forEach(function(filter, index)
{
$filterItems.append(renderFilterItem(filter, resp, index));
});
$filterItems.append(queryDom);
resolve();
});
});
})
}
function renderFilterItem(filter, resp, index, step)
+59 -1
View File
@@ -477,7 +477,12 @@ class chartModel extends model
$series[] = array('name' => $seriesName, 'data' => $yData, 'type' => 'bar', 'stack' => $stack);
}
$options = array('series' => $series, 'legend' => $legend, 'xAxis' => $xaxis, 'yAxis' => $yaxis, 'tooltip' => array('trigger' => 'axis'));
$dataZoomX = '[{"type":"inside","startValue":0,"endValue":5,"minValueSpan":10,"maxValueSpan":10,"xAxisIndex":[0],"zoomOnMouseWheel":false,"moveOnMouseWheel":true,"moveOnMouseMove":true},{"type":"slider","realtime":true,"startValue":0,"endValue":5,"zoomLock":true,"brushSelect":false,"width":"80%","height":"5","xAxisIndex":[0],"fillerColor":"#33aaff","borderColor":"#33aaff00","backgroundColor":"#cfcfcf00","handleSize":0,"showDataShadow":false,"showDetail":false,"bottom":"0","left":"10%"}]';
$dataZoomY = '[{"type":"inside","startValue":0,"endValue":5,"minValueSpan":10,"maxValueSpan":10,"yAxisIndex":[0],"zoomOnMouseWheel":false,"moveOnMouseWheel":true,"moveOnMouseMove":true},{"type":"slider","realtime":true,"startValue":0,"endValue":5,"zoomLock":true,"brushSelect":false,"width":5,"height":"80%","yAxisIndex":[0],"fillerColor":"#33aaff","borderColor":"#33aaff00","backgroundColor":"#cfcfcf00","handleSize":0,"showDataShadow":false,"showDetail":false,"top":"10%","right":0}]';
$isY = in_array($settings['type'], array('cluBarY', 'stackedBarY'));
$dataZoom = $isY ? json_decode($dataZoomY, true) : json_decode($dataZoomX, true);
$options = array('series' => $series, 'legend' => $legend, 'xAxis' => $xaxis, 'yAxis' => $yaxis, 'tooltip' => array('trigger' => 'axis'), 'dataZoom' => $dataZoom);
return $options;
}
@@ -626,5 +631,58 @@ class chartModel extends model
return $options;
}
public function getFilterFormat($filters)
{
$filterFormat = array();
foreach($filters as $filter)
{
$field = $filter['field'];
if(!isset($filter['default'])) continue;
$default = $filter['default'];
switch($filter['type'])
{
case 'select':
if(empty($default)) break;
if(!is_array($default)) $default = array($default);
$default = array_filter($default, function($val){return !empty($val);});
$value = "('" . implode("', '", $default) . "')";
$filterFormat[$field] = array('operator' => 'IN', 'value' => $value);
break;
case 'input':
$filterFormat[$field] = array('operator' => 'like', 'value' => "'%$default%'");
break;
case 'date':
case 'datetime':
$begin = $default['begin'];
$end = $default['end'];
if(empty($begin) or empty($end)) break;
$value = "'$begin' and '$end'";
$filterFormat[$field] = array('operator' => 'BETWEEN', 'value' => $value);
break;
case 'condition':
$operator = $filter['operator'];
$value = $filter['value'];
if(in_array($operator, array('IN', 'NOT IN')))
{
$valueArr = explode(',', $value);
foreach($valueArr as $key => $val) $valueArr[$key] = '"' . $val . '"';
$value = '(' . implode(',', $valueArr) . ')';
}
elseif(in_array($operator, array('IS NOT NULL', 'IS NULL')))
{
$value = '';
}
$filterFormat[$field] = array('operator' => $operator, 'value' => $value);
break;
}
}
return $filterFormat;
}
}
+5 -3
View File
@@ -20,6 +20,8 @@
<?php js::set('WIDTH_INPUT', $config->chart->widthInput);?>
<?php js::set('WIDTH_DATE', $config->chart->widthDate);?>
<?php js::set('pickerHeight', $config->bi->pickerHeight);?>
<?php $queryDom = "<div class='queryBtn query-inside hidden'> <button type='submit' id='submit' class='btn btn-primary btn-query' data-loading='Loading...'>{$lang->chart->query}</button></div>";?>
<?php js::set('queryDom', $queryDom);?>
<div id='mainMenu' class='clearfix main-position'>
<div class='btn-toolBar pull-left parent-position'>
@@ -92,13 +94,13 @@
</div>
</div>
<div class='panel-body'>
<div id="filterItems<?php echo $chart->currentGroup;?><?php echo $chart->id;?>" class='filterBox'>
<div id="filterItems<?php echo $chart->currentGroup . '_';?><?php echo $chart->id;?>" class='filterBox'>
<div class='filter-items'></div>
<?php if(!empty($chart->filters)):?>
<div class='queryBtn'><?php echo html::submitButton($lang->chart->query, "data-chart={$chart->currentGroup}{$chart->id}", 'btn btn-primary btn-query');?></div>
<div class='queryBtn query-outside'><?php echo html::submitButton($lang->chart->query, "data-chart={$chart->currentGroup}{$chart->id}", 'btn btn-primary btn-query');?></div>
<?php endif;?>
</div>
<div id="chartDraw<?php echo $chart->currentGroup;?><?php echo $chart->id;?>" data-group="<?php echo $chart->currentGroup;?>" data-id="<?php echo $chart->id;?>" class='echart-content'></div>
<div id="chartDraw<?php echo $chart->currentGroup . '_';?><?php echo $chart->id;?>" data-group="<?php echo $chart->currentGroup;?>" data-id="<?php echo $chart->id;?>" class='echart-content'></div>
</div>
</div>
<?php endforeach;?>
+2 -2
View File
@@ -627,7 +627,7 @@ class commonModel extends model
$params = "objectType=&objectID=0&libID=0";
$createMethod = 'selectLibType';
$isOnlyBody = true;
$attr = "class='iframe' data-width='700px'";
$attr = "class='iframe' data-width='750px'";
break;
case 'project':
$params = "model=scrum&programID=0&copyProjectID=0&extra=from=global";
@@ -2396,7 +2396,7 @@ EOF;
$hasField = false;
foreach($fields as $fieldObj)
{
if($field == $fieldObj->Field)
if($field == $fieldObj->field)
{
$hasField = true;
break;
+3
View File
@@ -29,6 +29,9 @@
.label-action {padding: 0 4px;}
.label-id {margin-left: 4px;}
.timeline > li.active:before {left: -30px;}
.timeline > li.collected:before, .timeline > li.releaseddoc:before {background-color: #FFF;}
.timeline > li.collected > div:after {background-color: #FFAF65;}
.timeline > li.releaseddoc > div:after {background-color: #66A2FF;}
.timeline > li > div:after {left: -27px;}
.timeline .timeline-text {display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
.timeline > li > div > .timeline-tag, .timeline > li > div > .timeline-text > .label-action {color: #838A9D;}
+3 -1
View File
@@ -63,7 +63,9 @@
<?php foreach($actions as $i => $action):?>
<?php if($action->action == 'adjusttasktowait') continue;?>
<?php if(empty($firstAction)) $firstAction = $action;?>
<li <?php if($action->major) echo "class='active'";?>>
<?php $class = $action->major ? 'active' : '';?>
<?php if(in_array($action->action, array('releaseddoc', 'collected'))) $class .= " {$action->action}";?>
<li <?php if($action->major) echo "class='$class'";?>>
<div>
<span class="timeline-tag"><?php echo $action->time?></span>
<span class="timeline-text">
+1 -1
View File
@@ -34,7 +34,7 @@ class cron extends control
*/
public function turnon($confirm = 'no')
{
$turnon = empty($this->config->global->cron) ? 1 : 0;
$turnon = empty($this->config->global->cron) ? '1' : '0';
if(!$turnon and $confirm == 'no') return print(js::confirm($this->lang->cron->confirmTurnon, inlink('turnon', "confirm=yes")));
$this->loadModel('setting')->setItem('system.common.global.cron', $turnon);
return print(js::reload('parent'));
+1 -1
View File
@@ -1001,7 +1001,7 @@ class customModel extends model
$disabledFeatures = rtrim($disabledFeatures, ',');
$this->loadModel('setting')->setItem('system.common.disabledFeatures', $disabledFeatures);
$URAndSR = strpos(",$disabledFeatures,", ',productUR,') === false ? 1 : 0;
$URAndSR = strpos(",$disabledFeatures,", ',productUR,') === false ? '1' : '0';
$this->setting->setItem('system.custom.URAndSR', $URAndSR);
$this->processMeasrecordCron();
+2 -6
View File
@@ -18,9 +18,8 @@ class devModel extends model
public function getTables()
{
$this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
$sql = "SHOW TABLES";
$tables = array();
$datatables = $this->dbh->query($sql)->fetchAll(PDO::FETCH_ASSOC);
$datatables = $this->dao->showTables();
foreach($datatables as $table)
{
$table = current($table);
@@ -62,10 +61,7 @@ class devModel extends model
try
{
$this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_LOWER);
$sql = "DESC $table";
$rawFields = $this->dbh->query($sql)->fetchAll();
$this->dbh->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL);
$rawFields = $this->dao->descTable($table);
}
catch (PDOException $e)
{
+2
View File
@@ -3,3 +3,5 @@ $config->dimension->changeDimensionLink = array();
$config->dimension->changeDimensionLink['screen-browse'] = 'screen|browse|dimensionID=%s';
$config->dimension->changeDimensionLink['pivot-preview'] = 'pivot|preview|dimensionID=%s';
$config->dimension->changeDimensionLink['chart-preview'] = 'chart|preview|dimensionID=%s';
$config->dimension->defaultDimension = array('efficiency', 'quality');
+3 -2
View File
@@ -1,6 +1,7 @@
<?php
$lang->dimension->common = 'Dimension';
$lang->dimension->default = 'Efficiency';
$lang->dimension->common = 'Dimension';
$lang->dimension->efficiency = 'Efficiency';
$lang->dimension->quality = 'Quality';
$lang->dimension->moduleList[''] = '';
$lang->dimension->moduleList['product'] = $lang->productCommon;
+3 -2
View File
@@ -1,6 +1,7 @@
<?php
$lang->dimension->common = 'Dimension';
$lang->dimension->default = 'Efficiency';
$lang->dimension->common = 'Dimension';
$lang->dimension->efficiency = 'Efficiency';
$lang->dimension->quality = 'Quality';
$lang->dimension->moduleList[''] = '';
$lang->dimension->moduleList['product'] = $lang->productCommon;
+3 -2
View File
@@ -1,6 +1,7 @@
<?php
$lang->dimension->common = 'Dimension';
$lang->dimension->default = 'Efficiency';
$lang->dimension->common = 'Dimension';
$lang->dimension->efficiency = 'Efficiency';
$lang->dimension->quality = 'Quality';
$lang->dimension->moduleList[''] = '';
$lang->dimension->moduleList['product'] = $lang->productCommon;
+3 -2
View File
@@ -1,6 +1,7 @@
<?php
$lang->dimension->common = '维度';
$lang->dimension->default = '效能';
$lang->dimension->common = '维度';
$lang->dimension->efficiency = '效能';
$lang->dimension->quality = '质量';
$lang->dimension->moduleList[''] = '';
$lang->dimension->moduleList['product'] = $lang->productCommon;
+10 -9
View File
@@ -12,10 +12,11 @@ $config->doc->editlib->requiredFields = 'name';
$config->doc->create->requiredFields = 'lib,title';
$config->doc->edit->requiredFields = 'title';
$config->doc->customObjectLibs = 'files,customFiles';
$config->doc->notArticleType = '';
$config->doc->officeTypes = 'word,ppt,excel';
$config->doc->textTypes = 'html,markdown,text';
$config->doc->customObjectLibs = 'files,customFiles';
$config->doc->notArticleType = '';
$config->doc->officeTypes = 'word,ppt,excel';
$config->doc->textTypes = 'html,markdown,text';
$config->doc->saveDraftInterval = '60';
$config->doc->custom = new stdclass();
$config->doc->custom->objectLibs = $config->doc->customObjectLibs;
@@ -43,11 +44,11 @@ $config->doc->objectIconList['execution'] = 'icon-run';
$config->doc->objectIconList['mine'] = 'icon-contacts';
$config->doc->objectIconList['custom'] = 'icon-groups';
$config->doc->spaceMethod['mine'] = 'mySpace';
$config->doc->spaceMethod['product'] = 'productSpace';
$config->doc->spaceMethod['project'] = 'projectSpace';
$config->doc->spaceMethod['execution'] = 'projectSpace';
$config->doc->spaceMethod['custom'] = 'tableContents';
$config->doc->spaceMethod['mine'] = 'myspace';
$config->doc->spaceMethod['product'] = 'productspace';
$config->doc->spaceMethod['project'] = 'projectspace';
$config->doc->spaceMethod['execution'] = 'projectspace';
$config->doc->spaceMethod['custom'] = 'tablecontents';
$config->doc->search['module'] = 'doc';
$config->doc->search['fields']['title'] = $lang->doc->title;
+118 -108
View File
@@ -36,26 +36,14 @@ class doc extends control
*/
public function index()
{
$this->session->set('docList', $this->app->getURI(true), 'doc');
$this->app->loadClass('pager', $static = true);
$pager = new pager(0, 5, 1);
$this->view->title = $this->lang->doc->common . $this->lang->colon . $this->lang->doc->index;
$this->view->position[] = $this->lang->doc->index;
$this->view->latestEditedDocs = $this->doc->getDocsByBrowseType('byediteddate', 0, 0, 'editedDate_desc, id_desc', $pager);
$this->view->myDocs = $this->doc->getDocsByBrowseType('openedbyme', 0, 0, 'addedDate_desc', $pager);
$this->view->collectedDocs = $this->doc->getDocsByBrowseType('collectedbyme', 0, 0, 'addedDate_desc', $pager);
$this->view->statisticInfo = $this->doc->getStatisticInfo();
$this->view->users = $this->user->getPairs('noletter');
$this->view->title = $this->lang->doc->common . $this->lang->colon . $this->lang->doc->index;
$this->display();
}
/**
* My space.
*
* @param string $type mine|view|collect|createBy
* @param string $type mine|view|collect|createdBy
* @param int $libID
* @param int $moduleID
* @param string $browseType all|draft|bysearch
@@ -67,48 +55,59 @@ class doc extends control
* @access public
* @return void
*/
public function mySpace($type = 'mine', $libID = 0, $moduleID = 0, $browseType = 'all', $param = 0, $orderBy = 'status,id_desc', $recTotal = 0, $recPerPage = 20, $pageID = 1)
public function mySpace($type = 'mine', $libID = 0, $moduleID = 0, $browseType = 'all', $param = 0, $orderBy = '', $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
$browseType = strtolower($browseType);
$type = strtolower($type);
if(empty($orderBy) and $type == 'mine') $orderBy = 'status,editedDate_desc';
if(empty($orderBy) and ($type == 'view' or $type == 'collect')) $orderBy = 'status,date_desc';
if(empty($orderBy) and ($type == 'createdby')) $orderBy = 'status,addedDate_desc';
/* Save session, load module. */
$uri = $this->app->getURI(true);
$this->session->set('docList', $uri, 'doc');
$this->session->set('productList', $uri, 'product');
$this->session->set('executionList', $uri, 'execution');
$this->session->set('projectList', $uri, 'project');
$this->session->set('objectName', '', 'doc');
$this->session->set('spaceType', 'mine', 'doc');
$this->loadModel('search');
list($libs, $libID, $object, $objectID, $objectDropdown) = $this->doc->setMenuByType('mine', 0, $libID);
/* Build the search form. */
$browseType = strtolower($browseType);
$type = strtolower($type);
$queryID = $browseType == 'bysearch' ? (int)$param : 0;
$params = "libID=$libID&moduleID=$moduleID&browseType=bySearch&param=myQueryID&orderBy=$orderBy";
if($this->app->rawMethod == 'mySpace') $param = "type=$type&" . $params;
if($this->app->rawMethod == 'myspace') $params = "type=$type&" . $params;
$actionURL = $this->createLink('doc', $this->app->rawMethod, $params);
$this->doc->buildSearchForm($libID, $libs, $queryID, $actionURL, $type);
/* Set header and position. */
$this->view->title = $this->lang->doc->common;
/* Load pager. */
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
/* Append id for secend sort. */
$sort = common::appendOrder($orderBy);
$docs = array();
if($type == 'mine')
{
$docs = $this->doc->getDocs($libID, $moduleID, $browseType, $orderBy, $pager);
if($browseType != 'bysearch' and !$libID)
{
$docs = array();
}
else
{
$docs = $browseType == 'bysearch' ? $this->doc->getDocsBySearch('mine', 0, $libID, $queryID, $orderBy, $pager) : $this->doc->getDocs($libID, $moduleID, $browseType, $orderBy, $pager);
}
}
elseif($type == 'view' or $type == 'collect' or $type == 'createdby')
{
$docs = $this->doc->getMineList($type, $browseType, $orderBy, $pager);
$docs = $this->doc->getMineList($type, $browseType, $orderBy, $pager, $queryID);
}
$this->view->title = $this->lang->doc->common;
$this->view->moduleID = $moduleID;
$this->view->docs = $docs;
$this->view->users = $this->user->getPairs('noletter');
@@ -117,11 +116,11 @@ class doc extends control
$this->view->param = $param;
$this->view->libID = $libID;
$this->view->lib = $this->doc->getLibById($libID);
$this->view->libTree = $this->doc->getLibTree($type != 'mine' ? 0 : $libID, $libs, 'mine', $moduleID);
$this->view->libTree = $this->doc->getLibTree($type != 'mine' ? 0 : $libID, $libs, 'mine', $moduleID, 0, $browseType);
$this->view->pager = $pager;
$this->view->type = $type;
$this->view->objectID = 0;
$this->view->canExport = common::hasPriv('doc', 'mine2export');
$this->view->canExport = ($this->config->edition != 'open' and common::hasPriv('doc', 'mine2export') and $type == 'mine');
$this->view->libType = 'lib';
$this->display();
@@ -178,7 +177,7 @@ class doc extends control
if($type == 'execution')
{
$objects = $this->execution->getPairs(0, 'sprint,stage', 'multiple,leaf,noprefix');
$objects = $this->execution->getPairs(0, 'sprint,stage', 'multiple,leaf,noprefix,withobject');
$execution = $this->execution->getByID($objectID);
if($execution->type == 'stage') $this->lang->doc->execution = str_replace($this->lang->executionCommon, $this->lang->project->stage, $this->lang->doc->execution);
}
@@ -192,8 +191,6 @@ class doc extends control
elseif($type == 'mine')
{
$acl = 'private';
unset($this->lang->doclib->aclList['open']);
unset($this->lang->doclib->aclList['default']);
$this->lang->doclib->aclList = $this->lang->doclib->mySpaceAclList['private'];
}
@@ -278,20 +275,28 @@ class doc extends control
$this->view->object = $execution;
}
if($lib->type == 'custom') unset($this->lang->doclib->aclList['default']);
if($lib->type == 'api')
if($lib->type == 'custom')
{
unset($this->lang->doclib->aclList['default']);
}
elseif($lib->type == 'api')
{
$this->app->loadLang('api');
$type = !empty($lib->product) ? 'product' : 'project';
$this->lang->api->aclList['default'] = sprintf($this->lang->api->aclList['default'], $this->lang->{$type}->common);
}
if($lib->type != 'custom')
elseif($lib->type == 'mine')
{
$this->lang->doclib->aclList = $this->lang->doclib->mySpaceAclList['private'];
}
elseif($lib->type != 'custom')
{
$type = isset($type) ? $type : $lib->type;
$this->lang->doclib->aclList['default'] = sprintf($this->lang->doclib->aclList['default'], $this->lang->{$type}->common);
$this->lang->doclib->aclList['private'] = sprintf($this->lang->doclib->privateACL, $this->lang->{$type}->common);
unset($this->lang->doclib->aclList['open']);
}
if(!empty($lib->main)) unset($this->lang->doclib->aclList['private'], $this->lang->doclib->aclList['open']);
$this->view->lib = $lib;
@@ -377,7 +382,8 @@ class doc extends control
$fileAction = '';
if(!empty($files)) $fileAction = $this->lang->addFiles . join(',', $files) . "\n";
$this->action->create('doc', $docID, 'Created', $fileAction);
$actionType = $_POST['status'] == 'draft' ? 'savedDraft' : 'releasedDoc';
$this->action->create('doc', $docID, $actionType, $fileAction);
if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'id' => $docID));
$objectID = zget($lib, $lib->type, 0);
@@ -388,24 +394,7 @@ class doc extends control
return $this->send($response);
}
if($this->app->tab == 'product')
{
$this->product->setMenu($objectID);
}
elseif($this->app->tab == 'project')
{
$this->project->setMenu($this->session->project);
}
elseif($this->app->tab == 'execution')
{
$this->execution->setMenu($objectID);
}
else
{
$this->app->rawMethod = $objectType;
}
unset($_GET['onlybody']);
$this->config->showMainMenu = (strpos($this->config->doc->textTypes, $docType) === false or $from == 'template');
$lib = $libID ? $this->doc->getLibByID($libID) : '';
@@ -419,7 +408,7 @@ class doc extends control
if(empty($lib) and $libID) $lib = $this->doc->getLibByID($libID);
$objects = array();
if($objectType == 'project')
if($linkType == 'project')
{
$excludedModel = $this->config->vision == 'lite' ? '' : 'kanban';
$objects = $this->project->getPairsByProgram('', 'all', false, 'order_asc', $excludedModel);
@@ -432,16 +421,16 @@ class doc extends control
}
$this->view->executions = array(0 => '') + $this->loadModel('execution')->getPairs($objectID, 'sprint,stage', 'multiple,leaf,noprefix');
}
elseif($objectType == 'execution')
elseif($linkType == 'execution')
{
$execution = $this->loadModel('execution')->getById($objectID);
$objects = $this->execution->getPairs($execution->project, 'sprint,stage', "multiple,leaf,noprefix");
}
elseif($objectType == 'product')
elseif($linkType == 'product')
{
$objects = $this->loadModel('product')->getPairs();
}
elseif($objectType == 'mine')
elseif($linkType == 'mine')
{
$this->lang->doc->aclList = $this->lang->doclib->mySpaceAclList;
}
@@ -523,6 +512,8 @@ class doc extends control
*/
public function edit($docID, $comment = false, $objectType = '', $objectID = 0, $libID = 0, $from = 'edit')
{
$doc = $this->doc->getById($docID);
if(!empty($_POST))
{
if($comment == false || $comment == 'false')
@@ -534,7 +525,14 @@ class doc extends control
}
if($this->post->comment != '' or !empty($changes) or !empty($files))
{
$action = !empty($changes) ? 'Edited' : 'Commented';
$action = 'Commented';
if(!empty($changes))
{
$newType = $_POST['status'];
if($doc->status == 'draft' and $newType == 'draft') $action = 'savedDraft';
if($doc->status == 'draft' and $newType == 'normal') $action = 'releasedDoc';
if($doc->status == 'normal' and $newType == 'normal') $action = 'Edited';
}
$fileAction = '';
if(!empty($files)) $fileAction = $this->lang->addFiles . join(',', $files) . "\n";
$actionID = $this->action->create('doc', $docID, $action, $fileAction . $this->post->comment);
@@ -542,9 +540,11 @@ class doc extends control
}
$link = $this->session->docList ? $this->session->docList : $this->createLink('doc', 'index');
$oldLib = $doc->lib;
$doc = $this->doc->getById($docID);
$lib = $this->doc->getLibById($doc->lib);
$objectID = zget($lib, $lib->type, 0);
if($oldLib != $doc->lib) $link = $this->createLink('doc', 'view', "docID={$docID}");
if(!empty($objectType) and $objectType != 'doc' and $doc->type != 'chapter' and $doc->type != 'article')
{
@@ -556,7 +556,6 @@ class doc extends control
}
/* Get doc and set menu. */
$doc = $this->doc->getById($docID);
$libID = $doc->lib;
if($doc->contentType == 'markdown') $this->config->doc->markdown->edit = array('id' => 'content', 'tools' => 'toolbar');
@@ -565,31 +564,6 @@ class doc extends control
$objectType = $lib->type;
$objectID = zget($lib, $objectType, 0);
/* Set menus. */
if($this->app->tab == 'product')
{
$this->product->setMenu($objectID);
}
else if($this->app->tab == 'project')
{
$this->project->setMenu($objectID);
}
else if($this->app->tab == 'execution')
{
$this->execution->setMenu($objectID);
}
else if($this->app->tab == 'my')
{
$this->lang->doc->menu = $this->lang->my->menu->contribute;
$this->lang->modulePageNav = '';
$this->lang->TRActions = '';
$this->lang->my->menu->contribute['subModule'] = 'doc';
}
else
{
$this->app->rawMethod = $objectType == 'execution' ? 'project' : $objectType;
}
$libs = $this->doc->getLibs($objectType, 'withObject', $libID, $objectID);
$objects = array();
if($objectType == 'project')
@@ -605,6 +579,10 @@ class doc extends control
{
$objects = $this->loadModel('product')->getPairs();
}
elseif($objectType == 'mine')
{
$this->lang->doc->aclList = $this->lang->doclib->mySpaceAclList['private'];
}
$moduleOptionMenu = $this->doc->getLibsOptionMenu($libs);
$this->config->showMainMenu = strpos(',html,markdown,text,', ",{$doc->type},") === false;
@@ -621,6 +599,7 @@ class doc extends control
$this->view->from = $from;
$this->view->files = $this->loadModel('file')->getByObject('doc', $docID);
$this->view->objectID = $objectID;
$this->view->otherEditing = $this->doc->checkOtherEditing($docID);
$this->display();
}
@@ -755,10 +734,12 @@ class doc extends control
if($action)
{
$this->doc->deleteAction($action->id);
$this->action->create('doc', $objectID, 'uncollected');
}
else
{
$this->doc->createAction($objectID, 'collect');
$this->action->create('doc', $objectID, 'collected');
}
return $this->send(array('status' => $action ? 'no' : 'yes'));
@@ -1121,7 +1102,7 @@ class doc extends control
public function view($docID = 0, $version = 0, $appendLib = 0)
{
$doc = $this->doc->getById($docID);
if(!$doc)
if(!$doc or !isset($doc->id))
{
if(defined('RUN_MODE') && RUN_MODE == 'api') return $this->send(array('status' => 'fail', 'code' => 404, 'message' => '404 Not found'));
return print(js::error($this->lang->notFound) . js::locate($this->inlink('index')));
@@ -1132,18 +1113,16 @@ class doc extends control
$objectType = isset($lib->type) ? $lib->type : 'custom';
$type = $objectType == 'execution' && $this->app->tab != 'execution' ? 'project' : $objectType;
$objectID = isset($doc->{$type}) ? $doc->{$type} : 0;
list($libs, $libID, $object, $objectID) = $this->doc->setMenuByType($type, $objectID, $doc->lib, $appendLib);
$objectID = zget($doc, $type, 0);
list($libs, $libID, $object, $objectID, $objectDropdown) = $this->doc->setMenuByType($type, $objectID, $doc->lib, $appendLib);
$moduleTree = $this->doc->getTreeMenu($type, $objectID, $libID, 0, $docID);
/* Get doc. */
if($docID)
{
$doc = $this->doc->getById($docID, $version, true);
if(!$doc) return print(js::error($this->lang->notFound));
$this->doc->createAction($docID, 'view');
$this->doc->removeEditing($doc);
if($doc->keywords)
{
$doc->keywords = str_replace(",", ',', $doc->keywords);
@@ -1215,26 +1194,54 @@ class doc extends control
}
}
$doc = $docID ? $doc : '';
$spaceType = $objectType . 'Space';
$doc = $docID ? $doc : '';
$this->view->title = isset($this->lang->doc->{$spaceType}) ? $this->lang->doc->{$spaceType} : $this->lang->doc->common;
$this->view->docID = $docID;
$this->view->doc = $doc;
$this->view->version = $version;
$this->view->object = $object;
$this->view->objectID = $objectID;
$this->view->objectType = $objectType;
$this->view->type = $type;
$this->view->libID = $libID;
$this->view->lib = isset($libs[$libID]) ? $libs[$libID] : new stdclass();
$this->view->libs = $this->doc->getLibsByObject($type, $objectID);
$this->view->canBeChanged = common::canModify($type, $object); // Determines whether an object is editable.
$this->view->actions = $docID ? $this->action->getList('doc', $docID) : array();
$this->view->users = $this->user->getPairs('noclosed,noletter');
$this->view->autoloadPage = $this->doc->checkAutoloadPage($doc);
$this->view->libTree = $this->doc->getLibTree($libID, $libs, $type, $doc->module, $objectID);
$this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('doc', $docID);
/* Crumbs links array. */
$methodName = in_array($type, array('product', 'project')) ? $objectType . 'Space' : 'tableContents';
$linkParams = "objectID={$objectID}&libID={$lib->id}";
if($this->app->tab == 'execution' or $objectType == 'custom')
{
$linkParams = "objectType=$objectType&$linkParams";
$methodName = 'tableContents';
}
if($type == 'mine')
{
$linkParams = "type=mine&libID={$lib->id}";
$methodName = 'mySpace';
}
$crumbs[] = html::a(inLink($methodName, $linkParams), html::image("static/svg/wiki-file-lib.svg") . $lib->name);
$moduleList = $this->loadModel('tree')->getParents($doc->module);
foreach($moduleList as $module)
{
$withModuleParams = $linkParams . "&moduleID=$module->id";
$crumbs[] = html::a(inLink($methodName, $withModuleParams), $module->name);
}
$spaceType = $objectType . 'Space';
$this->view->title = isset($this->lang->doc->{$spaceType}) ? $this->lang->doc->{$spaceType} : $this->lang->doc->common;
$this->view->docID = $docID;
$this->view->doc = $doc;
$this->view->version = $version;
$this->view->object = $object;
$this->view->objectID = $objectID;
$this->view->objectType = $objectType;
$this->view->type = $type;
$this->view->libID = $libID;
$this->view->crumbs = $crumbs;
$this->view->lib = isset($libs[$libID]) ? $libs[$libID] : new stdclass();
$this->view->libs = $this->doc->getLibsByObject($type, $objectID);
$this->view->canBeChanged = common::canModify($type, $object); // Determines whether an object is editable.
$this->view->actions = $docID ? $this->action->getList('doc', $docID) : array();
$this->view->users = $this->user->getPairs('noclosed,noletter');
$this->view->autoloadPage = $this->doc->checkAutoloadPage($doc);
$this->view->libTree = $this->doc->getLibTree($libID, $libs, $type, $doc->module, $objectID);
$this->view->preAndNext = $this->loadModel('common')->getPreAndNextObject('doc', $docID);
$this->view->moduleID = $doc->module;
$this->view->objectDropdown = $objectDropdown;
$this->view->canExport = ($this->config->edition != 'open' && common::hasPriv('doc', $type . '2export'));
$this->view->exportMethod = $type . '2export';
$this->display();
}
@@ -1309,6 +1316,9 @@ class doc extends control
$apiObjectID = $apiObjectType ? $objectID : 0;
$apiLibs = $apiObjectType ? $this->doc->getApiLibs(0, $apiObjectType, $apiObjectID) : array();
$canExport = $libType == 'api' ? common::hasPriv('api', 'export') : common::hasPriv('doc', $type . '2export');
if($this->config->edition == 'open') $canExport = false;
$this->view->title = $title;
$this->view->type = $type;
$this->view->objectType = $type;
@@ -1326,7 +1336,7 @@ class doc extends control
$this->view->objectID = $objectID;
$this->view->orderBy = $orderBy;
$this->view->release = $browseType == 'byrelease' ? $param : 0;
$this->view->canExport = $libType == 'api' ? common::hasPriv('api', 'export') : common::hasPriv('doc', $type . '2export');
$this->view->canExport = $canExport;
$this->view->exportMethod = $libType == 'api' ? 'export' : $type . '2export';
$this->view->apiLibID = key($apiLibs);
@@ -1437,7 +1447,7 @@ class doc extends control
$this->view->objectType = $objectType;
$this->view->objectID = $objectID;
$this->view->module = $module;
$this->view->method = $method;
$this->view->method = $method =='view' ? $objectType.'space' : $method;
$this->view->normalObjects = $myObjects + $normalObjects;
$this->view->closedObjects = $closedObjects;
$this->view->objectsPinYin = common::convert2Pinyin($myObjects + $normalObjects + $closedObjects);
+3
View File
@@ -104,5 +104,8 @@ ol, ul {margin-bottom: 0}
#subHeader .list-group>a.selected {color: #e9f2fb !important;}
#pageNav #dropMenu .table-col .list-group .icon-move {display:block; float: left; font-size: 12px; padding: 3px 4px 3px 1px;}
#content .detail-content.article-content {overflow-y: auto; height: calc(100vh - 300px);}
#aclBox .acl-tip {color: #838a9d;}
.ajaxCollect > img.star-empty {margin-right: 0px;}
#outlineMenu {background: #fff; position: absolute; height: calc(100vh - 200px)!important; overflow-y: auto; top: 50px; right: 20px;}
.pl-0px {padding-left:0px !important;}
+1
View File
@@ -1,3 +1,4 @@
body {overflow: hidden;}
.doc-title {width:400px;}
.doc-title input {border: unset; font-size: 18px; font-weight: bold; color: #3c4353; padding-left: 16px;}
.doc-title .form-control:focus {border: unset; box-shadow: unset;}
+1
View File
@@ -1,3 +1,4 @@
body {overflow: hidden;}
.doc-title {width:400px;}
.doc-title input {border: unset; font-size: 18px; font-weight: bold; color: #3c4353; padding-left: 16px;}
.doc-title .form-control:focus {border: unset; box-shadow: unset;}
-4
View File
@@ -1,4 +0,0 @@
#pageActions ul.dropdown-menu {left: 67px;}
#mainRow .main-col .row .col-sm-7 {width: 55% !important;}
#mainRow .main-col .row .col-sm-5 {width: 45% !important;}
#mainRow .c-num {text-overflow: ellipsis; white-space: nowrap;}
+1 -1
View File
@@ -9,6 +9,6 @@
.overflow-auto {overflow: auto;}
.overflow-visible {overflow: visible;}
.overflow-hidden {overflow: hidden;}
#mainContent > .panel {margin-bottom: 0; height: calc(100vh - 125px); overflow-y: auto;}
#mainContent > .panel {margin-bottom: 0; height: calc(100vh - 130px); overflow-y: auto;}
#bysearchTab::before {display: none;}
#queryBox #groupAndOr {min-width: 60px;}
+1 -1
View File
@@ -19,7 +19,7 @@
#mainContent #createDropdown {display: inline-block;}
#mainContent #createDropdown ul {position: absolute;}
#pageNav .dropdown-menu {max-height: inherit;}
#mainContent > .panel {margin-bottom: 0; height: calc(100vh - 125px); overflow-y: auto;}
#mainContent > .panel {margin-bottom: 0; height: calc(100vh - 130px); overflow-y: auto;}
#mainContent > .main-col {padding-left: 0;}
.no-content {width: 100px; height: 100px; margin: 0 auto;}
+2 -2
View File
@@ -15,7 +15,7 @@
#mainContent #createDropdown {display: inline-block;}
#mainContent #createDropdown ul {position: absolute;}
#pageNav .dropdown-menu {max-height: inherit;}
#mainContent > .panel {margin-bottom: 0; height: calc(100vh - 125px); overflow-y: auto;}
#mainContent > .panel {margin-bottom: 0; height: calc(100vh - 130px); overflow-y: auto;}
#mainContent > .main-col {padding-left: 0;}
#swapper {margin-right: 15px;}
@@ -32,7 +32,6 @@
span.item>a {padding-left: 6px;}
span.dotted-line+a {display: block;}
#modules li.doc:before, .chapterNode:before, .independent:before {content: " "; width: 100%; border-bottom: 1px dashed #b5b9c5; position: absolute; top: 13px; right: 0; left: 30px;}
.doc-title ,.item{display: inline-block !important; position: relative; padding-right: 10px; max-width:80%; white-space: nowrap; text-overflow: clip; overflow: hidden;}
#modules i.icon-file-text {color: #D0D2D6; font-size: 14px;}
.sortable-sorting .module-name > a {cursor: move;}
@@ -48,6 +47,7 @@ span.dotted-line+a {display: block;}
li.drag-shadow ul {display: none!important;}
.table .c-name > .doc-title {display: inline-block; max-width: calc(100% - 80px); overflow: hidden; background: transparent; padding-right:0px;}
.table .c-name > span.doc-title {line-height: 0; vertical-align: inherit;}
.table .c-name > .draft {background-color:rgba(129, 102, 238, 0.12); color:#8166EE;}
.table .c-name > .ajaxCollect {float: right; position: relative; right: 10px; top: 0px;}
table.table > thead > tr {height: 32px;}
+26 -12
View File
@@ -1,15 +1,14 @@
.h-full-adjust {overflow-y: auto; height: calc(100vh - 100px);}
.h-full-adjust {overflow-y: auto; height: calc(100vh - 120px);}
.main-col .block-files .panel-heading {padding-right: 20px;}
.main-col .block-files .panel-heading .panel-title {height: 35px; line-height: 30px;}
.main-col .doc-title {display: flex; font-size: 16px; margin-bottom: 15px;}
.main-col .doc-title {display: flex; font-size: 16px; margin-bottom: 10px;}
.main-col .doc-title .title {margin-right: 10px; line-height: 32px; font-size: 25px;}
.main-col .doc-title .info {flex: 1 1 0;}
.main-col .doc-title .version a {font-size: 13px; color: #8c8c8c;}
.main-col .doc-title .version .dropdown-menu a:hover {color: #ffffff;}
.main-col .doc-title .actions a + a {margin-left: 8px;}
.main-col .doc-title .actions a + a {margin-left: 0px;}
.main-col .doc-title .actions i {font-size: 15px; color: #8c8c8c;}
#content .title {max-width: 54%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
#content .detail-content {padding-left: 10px;}
#mainContent .scrollbar-hover {max-height: 2000px; overflow: scroll;}
#content .editor-preview {background: #fff}
#content .CodeMirror{border: none}
@@ -20,19 +19,22 @@
.hide-sidebar #sidebar>.sidebar-toggle>.icon:before {content: "\e314";}
.detail.empty {line-height: 200px;}
.main-col iframe {min-height: 380px;}
.article-content .keywords {margin-bottom: 15px;}
.article-content {margin-top: 0px}
.article-content .info {margin-bottom: 15px; width:100%; overflow:hidden;}
.article-content .info .user-time{margin-right: 16px}
.article-content .info .keywords .label {padding-right:8px; padding-left:8px; color:#18A6FD; border-color:rgba(24, 166, 253, 0.25); height:22px; line-height:14px; margin-right:4px;}
.article-content {width: 100%; display: inline-block;}
.outline {position: relative;}
.outline .outline-toggle i.icon-angle-right, i.icon-angle-left {width: 18px; height: 18px; border-radius: 50%; position: absolute; padding-left: 2px; padding-top: 1px;}
.outline .outline-toggle i.icon-angle-right:before {content: "\e314"; cursor: pointer;}
.outline .outline-toggle i.icon-angle-left:before {content: "\e315"; cursor: pointer;}
.outline-toggle {position: absolute; right: 20px; top: 50px;}
.outline-toggle i.icon-angle-right:before {content: "\e314"; cursor: pointer;}
.outline-toggle i.icon-angle-left:before {content: "\e315"; cursor: pointer;}
.outline ul li {list-style: none;}
.outline-content {display: none; padding-top: 18px;}
.outline-content a {color: #838A9D;}
.outline-content li.text-ellipsis.active>a {font-weight: 700; color: #0c64eb;}
#outline li.has-list.open:before {content: unset;}
#fileTree {margin-bottom: 40px; max-height: calc(100vh - 160px); overflow: auto;}
#fileTree {margin-bottom: 40px; max-height: calc(100vh - 180px); overflow: auto;}
#closeBtn {position: absolute; right: 10px; top: 10px;}
.title {font-size: 20px !important;}
.article-content.comment {width: 100% !important;}
@@ -48,11 +50,23 @@
.overflow-auto {overflow: auto;}
.overflow-visible {overflow: visible;}
.overflow-hidden {overflow: hidden;}
#mainContent > .panel {margin-bottom: 0; overflow-y: auto;}
.detail-title .actions .ajaxCollect > img {width: 20px;}
.actions > .text {color: #8c8c8c; font-size: 14px;}
.flex-content {display: flex; width: 100%; height: 100%;}
.flex-content > #content {flex: auto; overflow-y: auto;}
.flex-content > #history {flex: 0 0 302px; position: relative;}
.flex-content > #history {flex: 0 0 302px; position: relative; overflow: auto;}
.flex-content > #history > #closeIcon {position: absolute; right: 10px; top: 10px;}
.panel {margin-bottom: 0;}
.detail {margin: 0 4px;}
#mainContent > .panel {margin-bottom: 0; overflow-y: auto;}
#mainContent > .main-col{flex: auto;}
.info .version, .info .crumbs {float: left;}
.crumbs img {margin-right: 3px; margin-bottom: 4px;}
.crumbs {float: left; display: flex;height: 32px; width: 670px; align-items: center; overflow: hidden;}
.crumbs .crumb-item {padding: 6px 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: none; display: flex;}
.crumb-item .separator {flex: 0 0 15px; display: flex; justify-content: center; align-items: center;}
.crumb-item a {flex: none}
.main-col {position: relative;}
#autoBox {display: flex; overflow: hidden; text-overflow: ellipsis; padding-right: 15px; position: relative;}
#autoBox > .ellipsis {position: absolute; top: 3px; right: 0; width: 10px; background: #F4F5F7; height: 100%;}
+40 -2
View File
@@ -9,8 +9,13 @@
function loadObjectModules(objectType, objectID, docType)
{
if(typeof docType == 'undefined') docType = 'doc';
if(objectType == 'execution' && objectID == 0)
{
objectType = 'project';
objectID = $('#project').val();
}
if(objectID == undefined) objectID = 0;
var link = createLink('doc', 'ajaxGetModules', 'objectType=' + objectType + '&objectID=' + objectID + '&type=' + docType);
if(objectType == 'execution' && objectID == 0) var link = createLink('doc', 'ajaxGetModules', 'objectType=project&objectID=' + $('#project').val() + '&type=' + docType);
$('#moduleBox').load(link, function(){$('#moduleBox').find('select').picker(); $('#moduleLabel').remove();});
}
@@ -23,7 +28,7 @@ function loadObjectModules(objectType, objectID, docType)
*/
function loadExecutions(projectID)
{
var link = createLink('project', 'ajaxGetExecutions', "projectID=" + projectID + "&executionID=0&mode=multiple,leaf,noprefix");
var link = createLink('project', 'ajaxGetExecutions', "projectID=" + projectID + "&executionID=0&mode=multiple,leaf,noprefix&type=sprint,stage");
$('#executionBox').load(link, function(){$('#executionBox').find('select').attr('data-placeholder', holders.execution).attr('onchange', "loadObjectModules('execution', this.value)").picker()});
loadObjectModules('project', projectID);
}
@@ -275,6 +280,7 @@ $(document).ready(function()
$(function()
{
$('.split-row').splitRow();
updateCrumbs();
});
var $pageSetting = $('#pageSetting');
@@ -288,6 +294,8 @@ $(document).ready(function()
$(document).on('mousedown', '.ajaxCollect', function (event)
{
if(event.button != 0) return;
var obj = $(this);
var url = obj.data('url');
$.get(url, function(response)
@@ -389,3 +397,33 @@ function submit(object)
$('#dataform').submit();
setTimeout(function(){$(object).attr('type', 'button').removeAttr('disabled')}, 2000);
}
/**
* Update crumbs.
*
* @access public
* @return void
*/
function updateCrumbs()
{
var $crumbs = $('#crumbs');
var $crumbItems = $('#crumbs > .crumb-item');
var crumbMaxWidth = 660;
if($crumbs.width < crumbMaxWidth || $crumbItems.length == 1) return;
/* last crumbItem width major */
var $lastChild = $($crumbItems[$crumbItems.length -1]);
var widthSum = 0 + $lastChild.width();
for(var i = 0; i < $crumbItems.length - 1; i++)
{
var crumbItem = $crumbItems[i];
var widthSum = widthSum + $(crumbItem).width();
if(widthSum >= crumbMaxWidth)
{
$(crumbItem).addClass('in-auto-box');
}
}
var $autoCrumbItems = $('#crumbs > .in-auto-box');
$lastChild.before('<div id="autoBox" class="flex-auto"><div class="ellipsis">...<div></div>');
$('#autoBox').prepend($autoCrumbItems);
}
-9
View File
@@ -37,17 +37,8 @@ $(function()
}
}, 100)
$('#top-submit').click(function()
{
$(this).addClass('disabled');
$('form').submit();
})
$('#subNavbar li[data-id="doc"]').addClass('active');
/* Automatically save document contents. */
setInterval("saveDraft()", 60 * 1000);
$(document).on("mouseup", 'span[data-name="fullscreen"]', function()
{
if(config.onlybody == 'no')
+11 -7
View File
@@ -141,17 +141,16 @@ $(function()
$('.outline').height($('.article-content').height());
$('#content').on('click', '.outline .outline-toggle i.icon-angle-right', function()
$('body').on('click', '.outline-toggle i.icon-angle-right', function()
{
$('.article-content').css('width', '85%');
$('.outline').css({'min-width' : '180px', 'border-left' : '2px solid #efefef'});
$(this).removeClass('icon-angle-right').addClass('icon-angle-left').css('left', '-9px');
$('.outline-content').show();
if($('#sidebar>.cell').is(':visible')) $('#sidebar .icon.icon-angle-right').trigger("click");
}).on('click', '.outline .outline-toggle i.icon-angle-left', function()
}).on('click', '.outline-toggle i.icon-angle-left', function()
{
$('.article-content').width('100%');
$(this).removeClass('icon-angle-left').addClass('icon-angle-right');
$('.outline').css({'min-width' : '180px', 'border-left' : 'none'});
$('.outline-content').hide();
}).on('click', '#outline li', function(e)
{
@@ -187,6 +186,7 @@ $(function()
simplemde.value(String($('#markdownContent').val()));
simplemde.togglePreview();
}
$('#docExport').attr('href', createLink('doc', exportMethod, 'libID=' + libID + '&moduleID=0&docID=' + docID + '&version=' + $('#content .doc-title .version').data('version')));
});
})
@@ -199,6 +199,7 @@ $(function()
})
$('.outline .outline-toggle i.icon-angle-right').trigger("click");
$('#history').append('<a id="closeBtn" href="###" class="btn btn-link"><i class="icon icon-close"></i></a>');
$('#hisTrigger').on('click', function()
{
var $history = $('#history');
@@ -206,20 +207,23 @@ $(function()
if($history.hasClass('hidden'))
{
$history.removeClass('hidden');
$('#outlineMenu').addClass('hidden');
$icon.addClass('text-primary');
}
else
{
$history.addClass('hidden');
$('#outlineMenu').removeClass('hidden');
$icon.removeClass('text-primary');
}
})
$('#history').find('.btn.pull-right').removeClass('pull-right')
$('#history').append('<a id="closeIcon" class="btn btn-link"><i class="icon icon-close"></i></a>');
$('#closeIcon').on('click', function()
$('#history').find('.btn.pull-right').removeClass('pull-right');
$('#closeBtn').on('click', function()
{
$('#history').addClass('hidden');
$('#outlineMenu').removeClass('hidden');
$('#hisTrigger').removeClass('text-primary');
})
$('#history').find('.btn.pull-right').removeClass('pull-right');
})
+14 -3
View File
@@ -77,7 +77,7 @@ $lang->doc->digest = 'Zusammenfassung';
$lang->doc->comment = 'Bemerkung';
$lang->doc->type = 'Typ';
$lang->doc->content = 'Text';
$lang->doc->keywords = 'Tags';
$lang->doc->keywords = 'Keywords';
$lang->doc->status = 'Status';
$lang->doc->url = 'URL';
$lang->doc->files = 'Datei';
@@ -117,6 +117,7 @@ $lang->doc->main = 'Main Document Library';
$lang->doc->order = 'Order';
$lang->doc->doc = 'Document';
$lang->doc->updateOrder = 'Update Order';
$lang->doc->update = 'Update';
$lang->doc->nextStep = 'Next';
$lang->doc->closed = 'Closed';
$lang->doc->saveDraft = 'Save Draft';
@@ -145,9 +146,18 @@ $lang->doc->tableContents = 'Catalog';
$lang->doc->addCatalog = 'Add Catalog';
$lang->doc->editCatalog = 'Edit Catalog';
$lang->doc->deleteCatalog = 'Delete Catalog';
$lang->doc->docStatistic = 'Statistic';
$lang->doc->docCreated = 'Created Documents';
$lang->doc->docEdited = 'Edited Documents';
$lang->doc->docViews = 'Page Views';
$lang->doc->docCollects = 'Collection';
$lang->doc->todayUpdated = "Today's update";
$lang->doc->daysUpdated = 'Updated %s days ago';
$lang->doc->monthsUpdated = 'Updated %s months ago';
$lang->doc->yearsUpdated = 'Updated %s years ago';
/* Methods list */
$lang->doc->index = 'Home';
$lang->doc->index = 'Dashboard';
$lang->doc->createAB = 'Create';
$lang->doc->create = 'Dokument hinzufügen';
$lang->doc->edit = 'Bearbeiten';
@@ -198,7 +208,7 @@ $lang->doc->showDoc = 'Whether to display documents';
global $config;
/* Query condition list. */
$lang->doc->allProduct = 'Alle' . $lang->productCommon;
$lang->doc->allExecutions = 'Alle' . $lang->executionCommon;
$lang->doc->allExecutions = 'Alle' . $lang->execution->common;
$lang->doc->allProjects = 'All' . $lang->projectCommon . 's';
$lang->doc->libTypeList['product'] = $lang->productCommon . ' Bibliothek';
@@ -287,6 +297,7 @@ $lang->doc->confirmDelete = "Möchten Sie dieses Dokument löschen?";
$lang->doc->confirmDeleteLib = "Möchten Sie diese Bibliothek löschen?";
$lang->doc->confirmDeleteBook = "Do you want to delete this book?";
$lang->doc->confirmDeleteChapter = "Do you want to delete this chapter?";
$lang->doc->confirmOtherEditing = "This document is currently editing. Continuing to edit will overwrite the content edited by others. Do you want to continue?";
$lang->doc->errorEditSystemDoc = "System Dokumentenbibliothek darf nicht geändert werden.";
$lang->doc->errorEmptyProduct = "Kein {$lang->productCommon}. Kann nicht erstellt werden.";
$lang->doc->errorEmptyProject = "Kein {$lang->executionCommon}. Kann nicht erstellt werden.";
+14 -3
View File
@@ -77,7 +77,7 @@ $lang->doc->digest = 'Summary';
$lang->doc->comment = 'Comment';
$lang->doc->type = 'Type';
$lang->doc->content = 'Text';
$lang->doc->keywords = 'Tags';
$lang->doc->keywords = 'Keywords';
$lang->doc->status = 'Status';
$lang->doc->url = 'URL';
$lang->doc->files = 'Files';
@@ -117,6 +117,7 @@ $lang->doc->main = 'Main Document Library';
$lang->doc->order = 'Order';
$lang->doc->doc = 'Document';
$lang->doc->updateOrder = 'Update Order';
$lang->doc->update = 'Update';
$lang->doc->nextStep = 'Next';
$lang->doc->closed = 'Closed';
$lang->doc->saveDraft = 'Save Draft';
@@ -145,9 +146,18 @@ $lang->doc->tableContents = 'Directory';
$lang->doc->addCatalog = 'Add Catalog';
$lang->doc->editCatalog = 'Edit Catalog';
$lang->doc->deleteCatalog = 'Delete Catalog';
$lang->doc->docStatistic = 'Statistic';
$lang->doc->docCreated = 'Created Documents';
$lang->doc->docEdited = 'Edited Documents';
$lang->doc->docViews = 'Page Views';
$lang->doc->docCollects = 'Collection';
$lang->doc->todayUpdated = "Today's update";
$lang->doc->daysUpdated = 'Updated %s days ago';
$lang->doc->monthsUpdated = 'Updated %s months ago';
$lang->doc->yearsUpdated = 'Updated %s years ago';
/* Methods list */
$lang->doc->index = 'Document Home';
$lang->doc->index = 'Dashboard';
$lang->doc->createAB = 'Create';
$lang->doc->create = 'Create Document';
$lang->doc->edit = 'Edit Document';
@@ -198,7 +208,7 @@ $lang->doc->showDoc = 'Whether to display documents';
global $config;
/* Query condition list. */
$lang->doc->allProduct = 'All' . $lang->productCommon . 's';
$lang->doc->allExecutions = 'All' . $lang->executionCommon . 's';
$lang->doc->allExecutions = 'All' . $lang->execution->common . 's';
$lang->doc->allProjects = 'All' . $lang->projectCommon . 's';
$lang->doc->libTypeList['product'] = $lang->productCommon . ' Library';
@@ -287,6 +297,7 @@ $lang->doc->confirmDelete = "Do you want to delete this document?";
$lang->doc->confirmDeleteLib = "Do you want to delete this document library?";
$lang->doc->confirmDeleteBook = "Do you want to delete this book?";
$lang->doc->confirmDeleteChapter = "Do you want to delete this chapter?";
$lang->doc->confirmOtherEditing = "This document is currently editing. Continuing to edit will overwrite the content edited by others. Do you want to continue?";
$lang->doc->errorEditSystemDoc = "You don't have to change system document library.";
$lang->doc->errorEmptyProduct = "No {$lang->productCommon}. It cannot be created.";
$lang->doc->errorEmptyProject = "No {$lang->executionCommon}. It cannot be created.";
+14 -3
View File
@@ -77,7 +77,7 @@ $lang->doc->digest = 'Résumé';
$lang->doc->comment = 'Commentaire';
$lang->doc->type = 'Type';
$lang->doc->content = 'Texte';
$lang->doc->keywords = 'Tags';
$lang->doc->keywords = 'Keywords';
$lang->doc->status = 'Status';
$lang->doc->url = 'URL';
$lang->doc->files = 'Fichiers';
@@ -117,6 +117,7 @@ $lang->doc->main = 'Main Document Library';
$lang->doc->order = 'Order';
$lang->doc->doc = 'Document';
$lang->doc->updateOrder = 'Update Order';
$lang->doc->update = 'Update';
$lang->doc->nextStep = 'Next';
$lang->doc->closed = 'Closed';
$lang->doc->saveDraft = 'Save Draft';
@@ -145,9 +146,18 @@ $lang->doc->tableContents = 'Catalog';
$lang->doc->addCatalog = 'Add Catalog';
$lang->doc->editCatalog = 'Edit Catalog';
$lang->doc->deleteCatalog = 'Delete Catalog';
$lang->doc->docStatistic = 'Statistic';
$lang->doc->docCreated = 'Created Documents';
$lang->doc->docEdited = 'Edited Documents';
$lang->doc->docViews = 'Page Views';
$lang->doc->docCollects = 'Collection';
$lang->doc->todayUpdated = "Today's update";
$lang->doc->daysUpdated = 'Updated %s days ago';
$lang->doc->monthsUpdated = 'Updated %s months ago';
$lang->doc->yearsUpdated = 'Updated %s years ago';
/* Methods list */
$lang->doc->index = 'Accueil Documents';
$lang->doc->index = 'Dashboard';
$lang->doc->createAB = 'Create';
$lang->doc->create = 'Ajouter Document';
$lang->doc->edit = 'Editer Document';
@@ -198,7 +208,7 @@ $lang->doc->showDoc = 'Whether to display documents';
global $config;
/* Query condition list. */
$lang->doc->allProduct = 'Tous les' . $lang->productCommon . 's';
$lang->doc->allExecutions = 'Tous les' . $lang->executionCommon . 's';
$lang->doc->allExecutions = 'Tous les' . $lang->execution->common . 's';
$lang->doc->allProjects = 'All' . $lang->projectCommon . 's';
$lang->doc->libTypeList['product'] = $lang->productCommon . ' Library';
@@ -287,6 +297,7 @@ $lang->doc->confirmDelete = "Voulez-vous supprimer ce document ?";
$lang->doc->confirmDeleteLib = "Voulez-vous supprimer cette Bibliothèque ?";
$lang->doc->confirmDeleteBook = "Do you want to delete this book?";
$lang->doc->confirmDeleteChapter = "Do you want to delete this chapter?";
$lang->doc->confirmOtherEditing = "This document is currently editing. Continuing to edit will overwrite the content edited by others. Do you want to continue?";
$lang->doc->errorEditSystemDoc = "Vous n'avez pas besoin de changer de système de Bibliothèque.";
$lang->doc->errorEmptyProduct = "Aucun {$lang->productCommon}. Il ne peut pas être créé.";
$lang->doc->errorEmptyProject = "Aucun {$lang->executionCommon}. Il ne peut pas être créé.";
+16 -5
View File
@@ -117,6 +117,7 @@ $lang->doc->main = '文档主库';
$lang->doc->order = '排序';
$lang->doc->doc = '文档';
$lang->doc->updateOrder = '更新排序';
$lang->doc->update = '更新';
$lang->doc->nextStep = '下一步';
$lang->doc->closed = '已关闭';
$lang->doc->saveDraft = '存为草稿';
@@ -128,9 +129,9 @@ $lang->doc->team = '团队';
$lang->doc->moduleDoc = '按模块浏览';
$lang->doc->searchDoc = '搜索';
$lang->doc->fast = '快速访问';
$lang->doc->allDoc = '所有文档';
$lang->doc->openedByMe = '由我创建';
$lang->doc->editedByMe = '由我编辑';
$lang->doc->allDoc = '全部文档';
$lang->doc->openedByMe = '我的创建';
$lang->doc->editedByMe = '我的编辑';
$lang->doc->orderByOpen = '最近添加';
$lang->doc->orderByEdit = '最近更新';
$lang->doc->orderByVisit = '最近访问';
@@ -145,9 +146,18 @@ $lang->doc->tableContents = '目录';
$lang->doc->addCatalog = '添加目录';
$lang->doc->editCatalog = '编辑目录';
$lang->doc->deleteCatalog = '删除目录';
$lang->doc->docStatistic = '文档统计';
$lang->doc->docCreated = '创建的文档';
$lang->doc->docEdited = '编辑的文档';
$lang->doc->docViews = '被浏览量';
$lang->doc->docCollects = '被收藏量';
$lang->doc->todayUpdated = '今天更新';
$lang->doc->daysUpdated = '%s天前更新';
$lang->doc->monthsUpdated = '%s月前更新';
$lang->doc->yearsUpdated = '%s年前更新';
/* 方法列表。*/
$lang->doc->index = '文档主页';
$lang->doc->index = '仪表盘';
$lang->doc->createAB = '创建';
$lang->doc->create = '创建文档';
$lang->doc->edit = '编辑文档';
@@ -198,7 +208,7 @@ $lang->doc->showDoc = '是否显示文档';
global $config;
/* 查询条件列表 */
$lang->doc->allProduct = '所有' . $lang->productCommon;
$lang->doc->allExecutions = '所有' . $lang->executionCommon;
$lang->doc->allExecutions = '所有' . $lang->execution->common;
$lang->doc->allProjects = '所有' . $lang->projectCommon;
$lang->doc->libTypeList['product'] = $lang->productCommon . '文档库';
@@ -287,6 +297,7 @@ $lang->doc->confirmDelete = "您确定删除该文档吗?";
$lang->doc->confirmDeleteLib = "您确定删除该文档库吗?";
$lang->doc->confirmDeleteBook = "您确定删除该手册吗?";
$lang->doc->confirmDeleteChapter = "您确定删除该章节吗?";
$lang->doc->confirmOtherEditing = "该文档正在编辑中,如果继续编辑将覆盖他人编辑内容,是否继续?";
$lang->doc->errorEditSystemDoc = "系统文档库无需修改。";
$lang->doc->errorEmptyProduct = "没有{$lang->productCommon},无法创建文档";
$lang->doc->errorEmptyProject = "没有{$lang->executionCommon},无法创建文档";
+230 -116
View File
@@ -64,7 +64,7 @@ class docModel extends model
/**
* Get libraries.
*
* @param string $type
* @param string $type all|includeDeleted|hasApi|mine|product|project|execution|custom
* @param string $extra
* @param string $appendLibs
* @param int $objectID
@@ -75,14 +75,14 @@ class docModel extends model
*/
public function getLibs($type = '', $extra = '', $appendLibs = '', $objectID = 0, $excludeType = '')
{
if($type == 'all' or $type == 'includeDeleted')
if(in_array($type, array('all', 'includeDeleted', 'hasApi')))
{
$stmt = $this->dao->select('*')->from(TABLE_DOCLIB)
->where('type')->ne('api')
->where('vision')->eq($this->config->vision)
->beginIF($type == 'all')->andWhere('deleted')->eq(0)->fi()
->beginIF($type != 'hasApi')->andWhere('type')->ne('api')->fi()
->beginIF($excludeType)->andWhere('type')->notin($excludeType)->fi()
->andWhere('vision')->eq($this->config->vision)
->orderBy('`order`_asc, id_asc')
->orderBy('id_asc')
->query();
}
else
@@ -93,12 +93,13 @@ class docModel extends model
->beginIF($type)->andWhere('type')->eq($type)->fi()
->beginIF(!$type)->andWhere('type')->ne('api')->fi()
->beginIF($objectID and strpos(',product,project,execution,', ",$type,") !== false)->andWhere($type)->eq($objectID)->fi()
->orderBy("`order`_asc, id_asc")->query();
->orderBy('id_asc')
->query();
}
$products = $this->loadModel('product')->getPairs();
$projects = $this->loadModel('project')->getPairsByProgram();
$executions = $this->loadModel('execution')->getPairs(0, 'all', 'multiple,leaf');
$projects = $this->loadModel('project')->getPairsByProgram('', 'all', false, 'order_asc', 'kanban');
$executions = $this->loadModel('execution')->getPairs(0, 'sprint,stage', 'multiple,leaf');
$waterfalls = array();
if(empty($objectID) and $type != 'product' and $type != 'project' and $type != 'custom')
{
@@ -123,14 +124,18 @@ class docModel extends model
{
if(strpos($extra, 'withObject') !== false)
{
if($lib->product != 0) $lib->name = zget($products, $lib->product, '') . ' / ' . $lib->name;
if($lib->execution != 0)
{
$lib->name = zget($executions, $lib->execution, '') . ' / ' . $lib->name;
$lib->name = ltrim($lib->name, '/');
if(!empty($waterfalls[$lib->execution])) $lib->name = $waterfalls[$lib->execution] . ' / ' . $lib->name;
$lib->name = trim($lib->name, '/');
}
if($lib->product != 0) $lib->name = zget($products, $lib->product, '') . ' / ' . $lib->name;
if($lib->project != 0) $lib->name = zget($projects, $lib->project, '') . ' / ' . $lib->name;
if($lib->project != 0) $lib->name = zget($projects, $lib->project, '') . ' / ' . $lib->name;
if($lib->type == 'mine') $lib->name = $this->lang->doc->person . ' / ' . $lib->name;
if($lib->type == 'custom') $lib->name = $this->lang->doc->team . ' / ' . $lib->name;
}
$libPairs[$lib->id] = $lib->name;
@@ -377,13 +382,13 @@ class docModel extends model
*/
public function getDocsByBrowseType($browseType, $queryID, $moduleID, $sort, $pager)
{
$allLibs = $this->getLibs('all');
$allLibIDList = array_keys($allLibs);
$docIdList = $this->getPrivDocs(0, $moduleID);
$allLibs = $this->getLibs('all');
$allLibIDList = array_keys($allLibs);
$hasPrivDocIdList = $this->getPrivDocs(0, $moduleID);
$files = $this->dao->select('*')->from(TABLE_FILE)
->where('objectType')->eq('doc')
->andWhere('objectID')->in($docIdList)
->andWhere('objectID')->in($hasPrivDocIdList)
->fetchGroup('objectID');
if($browseType == "all")
@@ -413,6 +418,7 @@ class docModel extends model
$query = $this->getDocQuery($this->session->contributeDocQuery);
$docIDList = $this->dao->select('objectID')->from(TABLE_ACTION)
->where('objectType')->eq('doc')
->andWhere('objectID')->in($hasPrivDocIdList)
->andWhere('actor')->eq($this->app->user->account)
->andWhere('action')->eq('edited')
->fetchAll('objectID');
@@ -433,6 +439,7 @@ class docModel extends model
$docs = $this->dao->select('*')->from(TABLE_DOC)
->where('deleted')->eq(0)
->andWhere('lib')->in($allLibIDList)
->andWhere('id')->in($hasPrivDocIdList)
->beginIF($this->config->doc->notArticleType)->andWhere('type')->notIN($this->config->doc->notArticleType)->fi()
->andWhere('addedBy')->eq($this->app->user->account)
->orderBy($sort)
@@ -444,6 +451,7 @@ class docModel extends model
$docIDList = $this->dao->select('objectID')->from(TABLE_ACTION)
->where('objectType')->eq('doc')
->andWhere('actor')->eq($this->app->user->account)
->andWhere('objectID')->in($hasPrivDocIdList)
->andWhere('action')->eq('edited')
->fetchAll('objectID');
$docs = $this->dao->select('*')->from(TABLE_DOC)
@@ -459,7 +467,7 @@ class docModel extends model
{
$docs = $this->dao->select('*')->from(TABLE_DOC)
->where('deleted')->eq(0)
->andWhere('id')->in($docIdList)
->andWhere('id')->in($hasPrivDocIdList)
->beginIF($this->config->doc->notArticleType)->andWhere('type')->notIN($this->config->doc->notArticleType)->fi()
->andWhere('lib')->in($allLibIDList)
->orderBy('editedDate_desc')
@@ -472,6 +480,7 @@ class docModel extends model
->leftJoin(TABLE_DOCACTION)->alias('t2')->on("t1.id=t2.doc && t2.action='collect'")
->where('t1.deleted')->eq(0)
->andWhere('t1.lib')->in($allLibIDList)
->andWhere('t1.id')->in($hasPrivDocIdList)
->beginIF($this->config->doc->notArticleType)->andWhere('t1.type')->notIN($this->config->doc->notArticleType)->fi()
->andWhere('t2.actor')->eq($this->app->user->account)
->orderBy($sort)
@@ -575,7 +584,8 @@ class docModel extends model
*/
public function getObjectsByDoc($docIdList = array())
{
if(empty($docIdList)) return array();
$projects = $executions = $products = array();
if(empty($docIdList)) return array($projects, $executions, $products);
$projects = $this->dao->select('t1.id, t1.name')->from(TABLE_PROJECT)->alias('t1')
->leftJoin(TABLE_DOC)->alias('t2')->on('t1.id=t2.project')
@@ -632,31 +642,53 @@ class docModel extends model
* @access public
* @return array
*/
public function getMineList($type, $browseType, $orderBy, $pager = null)
public function getMineList($type, $browseType, $orderBy, $pager = null, $queryID = 0)
{
$query = '';
if($browseType == 'bysearch')
{
$query = $this->buildQuery($type, $queryID);
$query = preg_replace('/(`\w+`)/', 't1.$1', $query);
}
$libs = $this->getLibs();
$docIDList = $this->getPrivDocs(array_keys($libs));
if($type == 'view' or $type == 'collect')
{
$docs = $this->dao->select('DISTINCT t1.*,t3.name as libName,t3.type as objectType')->from(TABLE_DOC)->alias('t1')
$docs = $this->dao->select('t1.*,t3.name as libName,t3.type as objectType,max(t2.`date`) as date')->from(TABLE_DOC)->alias('t1')
->leftJoin(TABLE_DOCACTION)->alias('t2')->on("t1.id=t2.doc")
->leftJoin(TABLE_DOCLIB)->alias('t3')->on("t1.lib=t3.id")
->where('t1.deleted')->eq(0)
->andWhere('t1.lib')->ne('')
->andWhere('t1.vision')->eq($this->config->vision)
->andWhere('t1.id')->in(array_keys($docIDList))
->andWhere('t2.action')->eq($type)
->andWhere('t2.actor')->eq($this->app->user->account)
->beginIF($browseType == 'all')->andWhere("(t1.status = 'normal' or (t1.status = 'draft' and t1.addedBy='{$this->app->user->account}'))")->fi()
->beginIF(!common::hasPriv('doc', 'productSpace'))->andWhere('t3.type')->ne('product')->fi()
->beginIF(!common::hasPriv('doc', 'projectSpace'))->andWhere('t3.type')->notIN('project,execution')->fi()
->beginIF(!common::hasPriv('doc', 'tableContents'))->andWhere('t3.type')->ne('custom')->fi()
->beginIF($browseType == 'all' or $browseType == 'bysearch')->andWhere("(t1.status = 'normal' or (t1.status = 'draft' and t1.addedBy='{$this->app->user->account}'))")->fi()
->beginIF($browseType == 'draft')->andWhere('t1.status')->eq('draft')->andWhere('t1.addedBy')->eq($this->app->user->account)->fi()
->beginIF($browseType == 'bysearch')->andWhere($query)->fi()
->groupBy('t1.id')
->orderBy($orderBy)
->page($pager, 't1.id')
->fetchAll('id');
}
elseif($type == 'createdby')
{
$docs = $this->dao->select('DISTINCT t1.*,t2.name as libName,t2.type as objectType')->from(TABLE_DOC)->alias('t1')
$docs = $this->dao->select('t1.*,t2.name as libName,t2.type as objectType')->from(TABLE_DOC)->alias('t1')
->leftJoin(TABLE_DOCLIB)->alias('t2')->on("t1.lib=t2.id")
->where('t1.deleted')->eq(0)
->andWhere('t1.lib')->ne('')
->andWhere('t1.id')->in(array_keys($docIDList))
->andWhere('t1.vision')->eq($this->config->vision)
->andWhere('t1.addedBy')->eq($this->app->user->account)
->beginIF(!common::hasPriv('doc', 'productSpace'))->andWhere('t2.type')->ne('product')->fi()
->beginIF(!common::hasPriv('doc', 'projectSpace'))->andWhere('t2.type')->notIN('project,execution')->fi()
->beginIF(!common::hasPriv('doc', 'tableContents'))->andWhere('t2.type')->ne('custom')->fi()
->beginIF($browseType == 'draft')->andWhere('t1.status')->eq('draft')->andWhere('t1.addedBy')->eq($this->app->user->account)->fi()
->beginIF($browseType == 'bysearch')->andWhere($query)->fi()
->orderBy($orderBy)
->page($pager)
->fetchAll('id');
@@ -696,7 +728,7 @@ class docModel extends model
* @param int $module
* @param string $mode normal|all
* @access public
* @return void
* @return array
*/
public function getPrivDocs($libIdList = array(), $module = 0, $mode = 'normal')
{
@@ -739,7 +771,8 @@ class docModel extends model
echo(js::alert($this->lang->doc->accessDenied));
$loginLink = $this->config->requestType == 'GET' ? "?{$this->config->moduleVar}=user&{$this->config->methodVar}=login" : "user{$this->config->requestFix}login";
if(strpos($this->server->http_referer, $loginLink) !== false) return print(js::locate(inlink('index')));
return print(js::locate('back'));
helper::end(print(js::locate('back')));
die;
}
$docs = $this->processCollector(array($doc->id => $doc));
@@ -902,14 +935,11 @@ class docModel extends model
public function update($docID)
{
$oldDoc = $this->dao->select('*')->from(TABLE_DOC)->where('id')->eq((int)$docID)->fetch();
if(!empty($_POST['editedDate']) and $oldDoc->editedDate != $this->post->editedDate)
{
dao::$errors[] = $this->lang->error->editedByOther;
return false;
}
if(!isset($_POST['lib']) and strpos($_POST['module'], '_') !== false) list($_POST['lib'], $_POST['module']) = explode('_', $_POST['module']);
$doc = fixer::input('post')->setDefault('module', 0)
$account = $this->app->user->account;
$now = helper::now();
$doc = fixer::input('post')->setDefault('module', 0)
->callFunc('title', 'trim')
->stripTags($this->config->doc->editor->edit['id'], $this->config->allowedTags)
->setDefault('users', '')
@@ -917,8 +947,8 @@ class docModel extends model
->setDefault('product', 0)
->setDefault('execution', 0)
->setDefault('mailto', '')
->add('editedBy', $this->app->user->account)
->add('editedDate', helper::now())
->add('editedBy', $account)
->add('editedDate', $now)
->cleanInt('project,product,execution,lib,module')
->join('groups', ',')
->join('users', ',')
@@ -926,6 +956,10 @@ class docModel extends model
->remove('comment,files,labels,uid,contactListMenu')
->get();
$editingDate = $oldDoc->editingDate ? json_decode($oldDoc->editingDate, true) : array();
unset($editingDate[$account]);
$doc->editingDate = json_encode($editingDate);
if($doc->acl == 'open') $doc->users = $doc->groups = '';
if($doc->type == 'chapter' and $doc->parent)
{
@@ -983,7 +1017,7 @@ class docModel extends model
if($files) $docContent->files .= ',' . join(',', array_keys($files));
$docContent->files = trim($docContent->files, ',');
if(isset($doc->digest)) $docContent->digest = $doc->digest;
if($doc->status == 'draft')
if($oldDoc->status == 'draft')
{
$this->dao->update(TABLE_DOCCONTENT)->data($docContent)->where('id')->eq($oldDocContent->id)->exec();
}
@@ -1020,11 +1054,19 @@ class docModel extends model
*/
public function saveDraft($docID)
{
$docID = (int)$docID;
$oldDoc = $this->dao->select('id,editingDate')->from(TABLE_DOC)->where('id')->eq($docID)->fetch();
$account = $this->app->user->account;
$data = fixer::input('post')->stripTags($this->config->doc->editor->edit['id'], $this->config->allowedTags)->get();
$doc = new stdclass();
$doc->draft = $data->content;
$docType = $this->dao->select('type')->from(TABLE_DOCCONTENT)->where('doc')->eq((int)$docID)->orderBy('version_desc')->fetch();
$doc->editingDate = $oldDoc->editingDate ? json_decode($oldDoc->editingDate, true) : array();
$doc->editingDate[$account] = time();
$doc->editingDate = json_encode($doc->editingDate);
$docType = $this->dao->select('type')->from(TABLE_DOCCONTENT)->where('doc')->eq($docID)->orderBy('version_desc')->fetch();
if($docType == 'markdown') $doc->draft = $this->post->content;
$this->dao->update(TABLE_DOC)->data($doc)->where('id')->eq($docID)->exec();
@@ -1056,7 +1098,7 @@ class docModel extends model
unset($this->config->doc->search['fields']['module']);
}
elseif(in_array($type, array('product', 'project', 'execution', 'custom', 'mine')))
else
{
if(!isset($libs[$libID])) $libs[$libID] = $this->getLibById($libID);
@@ -1073,43 +1115,63 @@ class docModel extends model
{
$this->config->doc->search['params']['execution']['values'] = array('' => '') + $this->loadModel('execution')->getPairs($this->session->project, 'sprint,stage', 'multiple,leaf,noprefix') + array('all' => $this->lang->doc->allExecutions);
}
elseif($type == 'mine')
{
unset($this->config->doc->search['fields']['addedBy']);
unset($this->config->doc->search['fields']['editedBy']);
}
else
{
if($type == 'mine' or $type == 'createdby')
{
unset($this->config->doc->search['fields']['addedBy']);
if($type == 'mine') unset($this->config->doc->search['fields']['editedBy']);
}
unset($this->config->doc->search['fields']['execution']);
}
if(in_array($type, array('view', 'collect', 'createdby'))) $libPairs = array('' => '') + $this->getLibs('all', 'withObject');
$this->config->doc->search['module'] = $queryName;
$this->config->doc->search['params']['lib']['values'] = $libPairs + array('all' => $this->lang->doclib->all);
unset($this->config->doc->search['fields']['product']);
unset($this->config->doc->search['fields']['module']);
}
else
{
$products = $this->product->getPairs('nocode', $this->session->project);
$this->config->doc->search['params']['execution']['values'] = array('' => '') + $this->loadModel('execution')->getPairs($this->session->project, 'sprint,stage', 'multiple,leaf,noprefix') + array('all' => $this->lang->doc->allExecutions);
$this->config->doc->search['params']['lib']['values'] = array('' => '', $libID => ($libID ? $libs[$libID] : 0), 'all' => $this->lang->doclib->all);
$this->config->doc->search['params']['product']['values'] = array('' => '') + $products + array('all' => $this->lang->doc->allProduct);
}
$this->config->doc->search['actionURL'] = $actionURL;
$this->config->doc->search['queryID'] = $queryID;
/* Get the modules. */
$this->config->doc->search['params']['module']['values'] = $this->loadModel('tree')->getOptionMenu($libID, 'doc', $startModuleID = 0);
$this->loadModel('search')->setSearchParams($this->config->doc->search);
}
if($type == 'index' || $type == 'view' || ($this->app->rawMethod != 'contribute' and $libID == 0))
/**
* Build search query.
*
* @param string $type
* @param int $queryID
* @access public
* @return string
*/
public function buildQuery($type, $queryID = 0)
{
$queryName = $type . 'libDocQuery';
$queryForm = $type . 'libDocForm';
if($queryID)
{
unset($this->config->doc->search['fields']['module']);
unset($this->config->doc->search['fields']['lib']);
$query = $this->loadModel('search')->getQuery($queryID);
if($query)
{
$this->session->set($queryName, $query->sql);
$this->session->set($queryForm, $query->form);
}
else
{
$this->session->set($queryName, ' 1 = 1');
}
}
else
{
if($this->session->$queryName == false) $this->session->set($queryName, ' 1 = 1');
}
$this->loadModel('search')->setSearchParams($this->config->doc->search);
$query = $this->session->$queryName;
if(strpos($query, "`lib` = 'all'") !== false) $query = str_replace("`lib` = 'all'", '1', $query);
return $query;
}
/**
@@ -1207,7 +1269,9 @@ class docModel extends model
*/
public function checkPrivLib($object, $extra = '')
{
if($this->app->user->admin and $object->type != 'mine') return true;
if(empty($object)) return false;
if($this->app->user->admin and ($object->type != 'mine' or ($object->type == 'mine' and $object->addedBy == $this->app->user->account))) return true;
if($object->acl == 'open') return true;
@@ -1264,17 +1328,14 @@ class docModel extends model
*/
public function checkPrivDoc($object)
{
if($this->app->user->admin) return true;
if(!isset($object->lib)) return false;
if(isset($object->assetLibType) and $object->assetLibType) return true;
if($object->status == 'draft' and $object->addedBy != $this->app->user->account) return false;
if($object->status == 'normal' and $this->app->user->admin) return true;
static $extraDocLibs;
if($extraDocLibs === null) $extraDocLibs = $this->getPrivLibsByDoc();
static $libs;
if($libs === null) $libs = $this->getLibs('all');
if(isset($libs[$object->lib]) and isset($extraDocLibs[$object->lib])) unset($extraDocLibs[$object->lib]);
if($object->acl == 'open' and !isset($extraDocLibs[$object->lib])) return true;
if($object->acl == 'public' and !isset($extraDocLibs[$object->lib])) return true;
$lib = $this->getLibById($object->lib);
if(!$this->checkPrivLib($lib)) return false;
if(in_array($object->acl, array('open', 'public'))) return true;
$account = ",{$this->app->user->account},";
if(isset($object->addedBy) and $object->addedBy == $this->app->user->account) return true;
@@ -1750,7 +1811,7 @@ class docModel extends model
->groupBy('root')
->fetchPairs();
$docs = $this->dao->select("`id`,`addedBy`,`lib`,`acl`,`users`,`groups`")->from(TABLE_DOC)
$docs = $this->dao->select("`id`,`addedBy`,`lib`,`acl`,`users`,`groups`,`status`")->from(TABLE_DOC)
->where('lib')->in($idList)
->andWhere('deleted')->eq(0)
->andWhere('module')->eq(0)
@@ -2094,29 +2155,19 @@ class docModel extends model
{
$allLibs = array_keys($this->getLibs('all'));
$docIdList = $this->getPrivDocs($allLibs);
$myDocList = $this->dao->select('id')->from(TABLE_DOC)->where('addedBy')->eq($this->app->user->account)->fetchPairs('id');
$today = date('Y-m-d');
$lately = date('Y-m-d', strtotime('-3 day'));
$statisticInfo = $this->dao->select("count(id) as totalDocs, count(IF(editedDate like '{$today}%', 1, null)) as todayEditedDocs,
count(IF(editedDate > '{$lately}', 1, null)) as lastEditedDocs, count(IF(addedDate > '{$lately}', 1, null)) as lastAddedDocs,
count(IF(addedBy = '{$this->app->user->account}', 1, null)) as myDocs")->from(TABLE_DOC)
$today = date('Y-m-d');
$statistic = $this->dao->select("count(id) as totalDocs, count(IF(editedDate like '{$today}%', 1, null)) as todayEditedDocs,
count(IF(editedBy = '{$this->app->user->account}', 1, null)) as myEditedDocs, count(IF(addedBy = '{$this->app->user->account}', 1, null)) as myDocs")->from(TABLE_DOC)
->where('deleted')->eq(0)
->andWhere('vision')->eq($this->config->vision)
->andWhere('id')->in($docIdList)
->fetch();
$statisticInfo->myCollection = $this->dao->select('count(*) as count')->from(TABLE_DOCACTION)
->where('doc')->in($docIdList)
->andWhere('action')->eq('collect')
->andWhere('actor')->eq($this->app->user->account)
->fetch('count');
$statisticInfo->pastEditedDocs = $statisticInfo->totalDocs - $statisticInfo->todayEditedDocs;
$statisticInfo->lastEditedProgress = $statisticInfo->totalDocs ? round($statisticInfo->lastEditedDocs / $statisticInfo->totalDocs, 2) * 100 : 0;
$statisticInfo->lastAddedProgress = $statisticInfo->totalDocs ? round($statisticInfo->lastAddedDocs / $statisticInfo->totalDocs, 2) * 100 : 0;
$statisticInfo->myCollectionProgress = $statisticInfo->totalDocs ? round($statisticInfo->myCollection / $statisticInfo->totalDocs, 2) * 100 : 0;
$statisticInfo->myDocsProgress = $statisticInfo->totalDocs ? round($statisticInfo->myDocs / $statisticInfo->totalDocs, 2) * 100 : 0;
$statistic->myDoc = $this->dao->select("count(IF(`action` = 'view', 1, null)) as docViews, count(IF(`action` = 'collect', 1, null)) as docCollects")->from(TABLE_DOCACTION)->where('doc')->in($myDocList)->fetch();
return $statisticInfo;
return $statistic;
}
/**
@@ -2760,7 +2811,7 @@ class docModel extends model
public function checkAutoloadPage($doc)
{
$autoloadPage = true;
if(!empty($doc) and $doc->type == 'url')
if(isset($doc->type) and $doc->type == 'url')
{
if(empty($doc->content)) return false;
@@ -2788,32 +2839,10 @@ class docModel extends model
*/
public function getDocsBySearch($type, $objectID, $libID, $queryID, $orderBy = 'id_desc', $pager = null)
{
$queryName = $type . 'libDocQuery';
$queryForm = $type . 'libDocForm';
if($queryID)
{
$query = $this->loadModel('search')->getQuery($queryID);
if($query)
{
$this->session->set($queryName, $query->sql);
$this->session->set($queryForm, $query->form);
}
else
{
$this->session->set($queryName, ' 1 = 1');
}
}
else
{
if($this->session->$queryName == false) $this->session->set($queryName, ' 1 = 1');
}
$libs = $this->getLibsByObject($type, $objectID);
$query = $this->session->$queryName;
if(strpos($query, "`lib` = 'all'") !== false) $query = str_replace("`lib` = 'all'", '1', $query);
$query = $this->buildQuery($type, $queryID);
$libs = $this->getLibsByObject($type, $objectID);
$docIdList = $this->getPrivDocs(array_keys($libs));
$docs = $this->dao->select('*')->from(TABLE_DOC)
$docs = $this->dao->select('*')->from(TABLE_DOC)
->where('deleted')->eq(0)
->andWhere($query)
->andWhere('lib')->in(array_keys($libs))
@@ -2938,6 +2967,7 @@ class docModel extends model
$release = null;
if($browseType == 'byrelease' and $param) $release = $this->loadModel('api')->getRelease(0, 'byId', $param);
$browseType = strtolower($browseType);
$libTree = array($type => array());
$apiLibs = array();
$apiLibIDList = array();
@@ -2955,7 +2985,7 @@ class docModel extends model
$item->name = $lib->name;
$item->objectType = $type;
$item->objectID = $objectID;
$item->active = $lib->id == $libID && $browseType != 'bySearch' ? 1 : 0;
$item->active = $lib->id == $libID && $browseType != 'bysearch' ? 1 : 0;
$item->children = $this->getModuleTree($lib->id, $moduleID, $lib->type == 'api' ? 'api' : 'doc', 0, $releaseModule);
$showDoc = $this->loadModel('setting')->getItem('owner=' . $this->app->user->account . '&module=doc&key=showDoc');
$showDoc = $showDoc === '0' ? 0 : 1;
@@ -2964,6 +2994,7 @@ class docModel extends model
$docIDList = $this->getPrivDocs($lib->id);
$docs = $this->dao->select('*, title as name')->from(TABLE_DOC)
->where('id')->in($docIDList)
->andWhere("(status = 'normal' or (status = 'draft' and addedBy='{$this->app->user->account}'))")
->andWhere('deleted')->eq(0)
->andWhere('module')->eq(0)
->fetchAll('id');
@@ -3059,15 +3090,18 @@ class docModel extends model
if($type != 'project') $libTree = array_values($libTree[$type]);
if($type == 'mine')
{
$libType = zget($this->app->rawParams, 'type', '');
$libType = strtolower($libType);
$myLib = new stdclass();
$myLib->id = 0;
$myLib->name = $this->lang->doc->myLib;
$myLib->type = 'min';
$myLib->type = 'mine';
$myLib->objectType = 'doc';
$myLib->objectID = 0;
$myLib->active = 0;
$myLib->hasAction = false;
$myLib->active = $libID ? 1 : 0;
$myLib->active = $libType == 'mine' ? 1 : 0;
$myLib->children = $libTree;
$myView = new stdclass();
@@ -3077,7 +3111,7 @@ class docModel extends model
$myView->objectType = 'doc';
$myView->objectID = 0;
$myView->hasAction = false;
$myView->active = zget($this->app->rawParams, 'type', '') == 'view' ? 1 : 0;
$myView->active = $libType == 'view' ? 1 : 0;
$myCollection = new stdclass();
$myCollection->id = 0;
@@ -3086,7 +3120,7 @@ class docModel extends model
$myCollection->objectType = 'doc';
$myCollection->objectID = 0;
$myCollection->hasAction = false;
$myCollection->active = zget($this->app->rawParams, 'type', '') == 'collect' ? 1 : 0;
$myCollection->active = $libType == 'collect' ? 1 : 0;
$myCreation = new stdclass();
$myCreation->id = 0;
@@ -3095,7 +3129,7 @@ class docModel extends model
$myCreation->objectType = 'doc';
$myCreation->objectID = 0;
$myCreation->hasAction = false;
$myCreation->active = zget($this->app->rawParams, 'type', '') == 'createdBy' ? 1 : 0;
$myCreation->active = $libType == 'createdby' ? 1 : 0;
$libTree = array();
$libTree[] = $myLib;
@@ -3110,17 +3144,16 @@ class docModel extends model
* Print create document button.
*
* @param object $lib
* @param type $type project|product|custom
* @param int $objectID
* @param int $moduleID
* @param string $from list
* @access public
* @return string
*/
public function printCreateBtn($lib, $type, $objectID, $moduleID, $from = '')
public function printCreateBtn($lib, $moduleID, $from = '')
{
if(!common::hasPriv('doc', 'create')) return null;
if(!common::hasPriv('doc', 'create') or !isset($lib->id)) return null;
$objectID = zget($lib, $lib->type, 0);
$class = $from == 'list' ? 'btn-info' : 'btn-primary';
$html = "<div class='dropdown btn-group createDropdown'>";
$html .= html::a(helper::createLink('doc', 'create', "objectType={$lib->type}&objectID=$objectID&libID={$lib->id}&moduleID=$moduleID&type=html"), "<i class='icon icon-plus'></i> {$this->lang->doc->create}", '', "class='btn $class'");
@@ -3134,7 +3167,7 @@ class docModel extends model
$attr = "data-app='{$this->app->tab}'";
$class = strpos($this->config->doc->officeTypes, $typeKey) !== false ? 'iframe' : '';
$params = "objectType={$lib->type}&objectID=$objectID&libID={$lib->id}&moduleID=$moduleID&type=$typeKey";
if($typeKey == 'template') $params = "objectType=$type&objectID=$objectID&libID={$lib->id}&moduleID=$moduleID&type=html&from=template";
if($typeKey == 'template') $params = "objectType={$lib->type}&objectID=$objectID&libID={$lib->id}&moduleID=$moduleID&type=html&from=template";
$html .= "<li>";
$html .= html::a(helper::createLink('doc', 'create', $params, '', $class ? true : false), $typeName, '', "class='$class' $attr");
@@ -3288,4 +3321,85 @@ class docModel extends model
}
return $docs;
}
/**
* Check other editing.
*
* @param int $docID
* @access public
* @return bool
*/
public function checkOtherEditing($docID)
{
$now = time();
$account = $this->app->user->account;
$docID = (int)$docID;
$doc = $this->dao->select('id,editingDate')->from(TABLE_DOC)->where('id')->eq($docID)->fetch();
if(empty($doc)) return false;
$editingDate = $doc->editingDate ? json_decode($doc->editingDate, true) : array();
$otherEditing = false;
foreach($editingDate as $editingAccount => $timestamp)
{
if($editingAccount != $account and ($now - $timestamp) <= $this->config->doc->saveDraftInterval)
{
$otherEditing = true;
break;
}
}
$editingDate[$account] = $now;
$this->dao->update(TABLE_DOC)->set('editingDate')->eq(json_encode($editingDate))->where('id')->eq($docID)->exec();
return $otherEditing;
}
/**
* Get document dynamic.
*
* @param object $pager
* @access public
* @return array
*/
public function getDynamic($pager = null)
{
$allLibs = $this->getLibs('hasApi');
$hasPrivDocIdList = $this->getPrivDocs('', 0, 'all');
$apiList = $this->loadModel('api')->getPrivApis();
$actions = $this->dao->select('*')->from(TABLE_ACTION)
->where('vision')->eq($this->config->vision)
->andWhere('((objectType')->eq('doclib')
->andWhere('objectID')->in(array_keys($allLibs))
->markRight(1)
->orWhere('(objectType')->eq('doc')
->andWhere('objectID')->in($hasPrivDocIdList)
->markRight(1)
->orWhere('(objectType')->eq('api')
->andWhere('objectID')->in(array_keys($apiList))
->markRight(2)
->orderBy('date_desc')
->page($pager)
->fetchAll();
return $this->loadModel('action')->transformActions($actions);
}
/**
* Remove editing.
*
* @param object $doc
* @access public
* @return void
*/
public function removeEditing($doc)
{
if(empty($doc->id) or empty($doc->editingDate)) return false;
$account = $this->app->user->account;
$editingDate = json_decode($doc->editingDate, true);
if(!isset($editingDate[$account])) return false;
unset($editingDate[$account]);
$this->dao->update(TABLE_DOC)->set('editingDate')->eq(json_encode($editingDate))->where('id')->eq($doc->id)->exec();
}
}
+20 -19
View File
@@ -26,8 +26,6 @@
</ul>
</div>
</div>
<div class="user"></div>
<div class="time"></div>
</div>
<div class="actions">
<span class='text'><?php echo$lang->doc->diff?></span>
@@ -55,7 +53,7 @@
}?>
<a id="hisTrigger" href="###" class="btn btn-link" title=<?php echo $lang->history?>><span class="icon icon-clock"></span></a>
<?php if($this->config->edition == 'max' and $this->app->tab == 'project'):?>
<?php if($config->vision == 'rnd' and $config->edition == 'max' and $app->tab == 'project'):?>
<?php
$canImportToPracticeLib = (common::hasPriv('doc', 'importToPracticeLib') and helper::hasFeature('practicelib'));
$canImportToComponentLib = (common::hasPriv('doc', 'importToComponentLib') and helper::hasFeature('componentlib'));
@@ -73,15 +71,18 @@
<?php endif;?>
</div>
</div>
<div class="table-row">
<div class="">
<div class="detail-content article-content table-col">
<?php if($doc->keywords):?>
<p class='keywords'>
<?php foreach($doc->keywords as $keywords):?>
<?php if($keywords) echo "<span class='label label-outline'>$keywords</span>";?>
<?php endforeach;?>
</p>
<?php endif;?>
<div class='info'>
<span class='user-time text-muted'><i class='icon icon-account'></i> <?php echo zget($users, $doc->editedBy) . " {$lang->colon} " . substr($doc->editedDate, 0, 10) . (common::checkNotCN() ? ' ' : '') . $lang->doc->update;?></span>
<?php if($doc->keywords):?>
<span class='keywords'>
<?php foreach($doc->keywords as $keywords):?>
<?php if($keywords) echo "<span class='label label-outline' title='{$keywords}'>{$keywords}</span>";?>
<?php endforeach;?>
</span>
<?php endif;?>
</div>
<?php
if($doc->type == 'url' and $autoloadPage)
{
@@ -144,14 +145,6 @@
<?php endif;?>
<?php endforeach;?>
</div>
<?php if(!empty($outline) and strip_tags($outline)):?>
<div class="outline table-col">
<div class="outline-toggle"><i class="icon icon-angle-right"></i></div>
<div class="outline-content">
<?php echo $outline;?>
</div>
</div>
<?php endif;?>
</div>
</div>
<?php echo $this->fetch('file', 'printFiles', array('files' => $doc->files, 'fieldset' => 'true', 'object' => $doc));?>
@@ -159,6 +152,14 @@
<?php common::printPreAndNext($preAndNext);?>
</div>
</div>
<?php if(!empty($outline) and strip_tags($outline)):?>
<div id="outlineMenu" class="outline table-col">
<div class="outline-content">
<?php echo $outline;?>
</div>
</div>
<div class="outline-toggle"><i class="icon icon-angle-right"></i></div>
<?php endif;?>
<div id="history" class='panel hidden' style="margin-left: 2px;">
<?php
$canBeChanged = common::canBeChanged('doc', $doc);
+8 -5
View File
@@ -60,33 +60,34 @@
</button>
<table class='table table-form' id="basicInfoBox">
<tbody>
<tr><th class='w-100px'></th><td></td><th class='w-100px'></th><td></td></tr>
<tr><th class='w-110px'></th><td></td><th class='w-110px'></th><td></td><td class='w-30px'></td></tr>
<tr>
<th><?php echo $lang->doc->title?></th>
<td colspan='3' id='copyTitle'></td>
</tr>
<?php if($objectType == 'project'):?>
<?php if($linkType == 'project'):?>
<tr>
<th><?php echo $lang->doc->project;?></th>
<td class='required'><?php echo html::select('project', $objects, isset($execution) ? $execution->project : $objectID, "class='form-control picker-select' onchange=loadExecutions(this.value)");?></td>
<?php if($this->app->tab == 'doc' and $config->vision == 'rnd'):?>
<th><?php echo $lang->doc->execution?></th>
<td id='executionBox'><?php echo html::select('execution', $executions, isset($execution) ? $objectID : '', "class='form-control chosen' data-placeholder='{$lang->doc->placeholder->execution}' onchange='loadObjectModules(\"execution\", this.value)'")?></td>
<td class='pl-0px'><i class='icon icon-help' title='<?php echo $lang->doc->placeholder->execution;?>'></i></td>
<?php endif;?>
</tr>
<?php elseif($objectType == 'execution'):?>
<?php elseif($linkType == 'execution'):?>
<tr>
<th><?php echo $lang->doc->execution;?></th>
<td class='required'><?php echo html::select('execution', $objects, $objectID, "class='form-control picker-select' onchange='loadObjectModules(\"execution\", this.value)'");?></td>
</tr>
<?php elseif($objectType == 'product'):?>
<?php elseif($linkType == 'product'):?>
<tr>
<th><?php echo $lang->doc->product;?></th>
<td class='required'><?php echo html::select('product', $objects, $objectID, "class='form-control picker-select' onchange='loadObjectModules(\"product\", this.value)'");?></td>
</tr>
<?php endif;?>
<tr>
<th class='w-100px'><?php echo $lang->doc->libAndModule?></th>
<th class='w-110px'><?php echo $lang->doc->libAndModule?></th>
<td colspan='3' class='required'><span id='moduleBox'><?php echo html::select('module', $moduleOptionMenu, $moduleID, "class='form-control picker-select'");?></span></td>
</tr>
<tr>
@@ -114,6 +115,7 @@
<?php echo html::radio('acl', $lang->doc->aclList, $objectType == 'mine' ? 'private' : 'open', "onchange='toggleAcl(this.value, \"doc\")'");?>
</td>
</tr>
<?php if($objectType != 'mine'):?>
<tr id='whiteListBox' class='hidden'>
<th><?php echo $lang->doc->whiteList;?></th>
<td colspan='3'>
@@ -128,6 +130,7 @@
</div>
</td>
</tr>
<?php endif;?>
</tbody>
<tfoot>
<tr>
+2 -1
View File
@@ -20,6 +20,7 @@ body {margin-bottom: 25px;}
#docListForm .checkbox-primary > label {height: 16px; line-height: 16px; padding-left: 16px;}
#docListForm .checkbox-primary > label:before {left: -1px; font-size: 10px;}
#docListForm .checkbox-primary > label:after {width: 12px; height: 12px;}
.table-files .btn {padding: 0 2px;}
</style>
<?php if(common::checkNotCN()):?>
<style>
@@ -34,7 +35,7 @@ body {margin-bottom: 25px;}
<?php
if($browseType != 'bySearch' and $libID and (common::hasPriv('doc', 'create') or (common::hasPriv('api', 'create') and !$apiLibID)))
{
echo $this->doc->printCreateBtn($lib, $type, $objectID, $moduleID, 'list');
echo $this->doc->printCreateBtn($lib, $moduleID, 'list');
}
?>
</p>
+1 -2
View File
@@ -35,7 +35,7 @@
</tr>
<?php endif;?>
<tr>
<th class='w-100px'><?php echo $lang->doc->libAndModule?></th>
<th class='w-110px'><?php echo $lang->doc->libAndModule?></th>
<td colspan='3' class='required'><span id='moduleBox'><?php echo html::select('module', $moduleOptionMenu, $doc->lib . '_' . $doc->module, "class='form-control chosen'");?></span></td>
</tr>
<tr>
@@ -82,7 +82,6 @@
<?php
echo html::hidden('contentType', $doc->contentType);
echo html::hidden('type', $doc->type);
echo html::hidden('editedDate', $doc->editedDate);
echo html::hidden('status', $doc->status);
echo html::hidden('parent', $doc->parent);
echo html::submitButton();
+18 -3
View File
@@ -44,7 +44,6 @@
<div class='contenthtml'><?php echo html::textarea('content', htmlSpecialString($doc->content), "style='width:100%;'");?></div>
<?php echo html::hidden('contentType', $doc->contentType);?>
<?php echo html::hidden('type', 'text');?>
<?php echo html::hidden('editedDate', $doc->editedDate);?>
<?php echo html::hidden('status', $doc->status);?>
</div>
</div>
@@ -69,12 +68,12 @@
<tbody>
<?php if(strpos('product|project|execution', $type) !== false):?>
<tr>
<th><?php echo $lang->doc->project;?></th>
<th><?php echo $lang->doc->{$type};?></th>
<td class='required'><?php echo html::select($type, $objects, $objectID, "class='form-control picker-select' onchange='loadObjectModules(\"{$type}\", this.value)'");?></td>
</tr>
<?php endif;?>
<tr>
<th class='w-100px'><?php echo $lang->doc->libAndModule?></th>
<th class='w-110px'><?php echo $lang->doc->libAndModule?></th>
<td colspan='3' class='required'><span id='moduleBox'><?php echo html::select('module', $moduleOptionMenu, $doc->lib . '_' . $doc->module, "class='form-control picker-select'");?></span></td>
</tr>
<tr>
@@ -102,6 +101,7 @@
<?php echo html::radio('acl', $lang->doc->aclList, $doc->acl, "onchange='toggleAcl(this.value, \"doc\")'")?>
</td>
</tr>
<?php if($lib->type != 'mine'):?>
<tr id='whiteListBox' class='<?php if($doc->acl == 'open') echo 'hidden';?>'>
<th><?php echo $lang->doc->whiteList;?></th>
<td colspan='3'>
@@ -116,6 +116,7 @@
</div>
</td>
</tr>
<?php endif;?>
</tbody>
<tfoot>
<tr>
@@ -129,6 +130,20 @@
</div>
</form>
</div>
<script>
$(function()
{
/* Automatically save document contents. */
setInterval("saveDraft()", <?php echo $config->doc->saveDraftInterval;?> * 1000);
<?php if($otherEditing):?>
bootbox.confirm(
{
message: '<?php echo $lang->doc->confirmOtherEditing;?>',
callback: function(result){if(!result) location.href='<?php echo $backLink;?>'}
});
<?php endif;?>
})
</script>
<?php js::set('needUpdateContent', $doc->content != $doc->draft);?>
<?php js::set('confirmUpdateContent', $lang->doc->confirmUpdateContent);?>
<?php js::set('docID', $doc->id);?>
+1 -193
View File
@@ -11,197 +11,5 @@
*/
?>
<?php include '../../common/view/header.html.php';?>
<div class='main-row split-row fade' id='mainRow'>
<div id="mainContent">
<div class="cell" id="queryBox" data-module='doc'></div>
<div class="row">
<div class="col-sm-7">
<div class="panel block-files block-sm" style="height: 290px;">
<div class="panel-heading">
<div class="panel-title"><?php echo $lang->doc->orderByEdit;?></div>
<nav class="panel-actions nav nav-default">
<li><?php echo html::a($this->createLink('doc', 'browse', "browseType=byediteddate"), strtoupper($lang->more), '', "title='{$lang->more}'");?></li>
</nav>
</div>
<?php if(empty($latestEditedDocs)):?>
<div class="table-empty-tip">
<p><span class="text-muted"><?php echo $lang->doc->noDoc;?></span></p>
</div>
<?php else:?>
<div class="panel-body has-table">
<table class="table table-borderless table-fixed-head table-hover">
<thead>
<tr>
<th class="c-name"><?php echo $lang->doc->title;?></th>
<th class="c-num text-right" title="<?php echo $lang->doc->size?>"><?php echo $lang->doc->size;?></th>
<th class="c-user" title="<?php echo $lang->doc->addedBy;?>"><?php echo $lang->doc->addedBy;?></th>
<th class="c-datetime"><?php echo $lang->doc->editedDate;?></th>
</tr>
</thead>
<tbody>
<?php foreach($latestEditedDocs as $doc):?>
<tr>
<td class="c-name"><?php echo html::a($this->createLink('doc', 'view', "docID={$doc->id}", '', true), $doc->title, '', "data-toggle='modal' data-type='iframe' data-width='90%' title='{$doc->title}'")?></a></td>
<td class="c-num text-right"><?php echo $doc->fileSize ? $doc->fileSize : '-';?></td>
<td class="c-user"><?php echo zget($users, $doc->addedBy);?></td>
<td class="c-datetime"><?php echo helper::isZeroDate($doc->editedDate) ? formatTime($doc->addedDate, 'Y-m-d') : formatTime($doc->editedDate, 'Y-m-d');?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
<?php endif;?>
</div>
</div>
<div class="col-sm-5">
<div class="panel block-sm" style="height: 290px;">
<div class="panel-heading">
<div class="panel-title"><?php echo $lang->doc->allDoc . ' ' . $statisticInfo->totalDocs;?></div>
</div>
<div class="panel-body table-row">
<div class="col-7 text-middle text-center">
<div class="progress-pie inline-block space-lg" data-value="<?php echo $statisticInfo->lastEditedProgress;?>" data-doughnut-size="84" data-real-value="<?php echo $statisticInfo->lastEditedDocs;?>">
<canvas width="100" height="100"></canvas>
<div class="progress-info">
<small><?php echo $lang->doc->orderByEdit;?></small>
<strong class="progress-value"><?php echo $statisticInfo->lastEditedDocs;?></strong>
</div>
</div>
<div class="table-row text-center small text-muted">
<div class="col-4">
<span class="label label-dot label-primary"></span>
<span><?php echo $lang->doc->todayEdited;?></span>
<em class="strong"><?php echo $statisticInfo->todayEditedDocs;?></em>
</div>
<div class="col-4">
<span class="label label-dot label-pale"></span>
<span><?php echo $lang->doc->pastEdited;?></span>
<em class="strong"><?php echo $statisticInfo->pastEditedDocs;?></em>
</div>
</div>
</div>
<div class="col-5 text-middle text-center">
<a class="table-row space-lg">
<div class="table-col text-middle">
<small class="muted"><?php echo $lang->doc->orderByOpen;?></small>
<div class="strong"><?php echo $statisticInfo->lastAddedDocs;?></div>
</div>
<div class="table-col text-middle">
<div class="progress-pie inline-block" data-value="<?php echo $statisticInfo->lastAddedProgress;?>" data-doughnut-size="78" data-color="#00a9fc">
<canvas width="50" height="50"></canvas>
<div class="progress-info">
<strong><span class="progress-value"><?php echo $statisticInfo->lastAddedProgress;?></span><small>%</small></strong>
</div>
</div>
</div>
</a>
<a class="table-row space-lg">
<div class="table-col text-middle">
<small class="muted"><?php echo $lang->doc->myDoc;?></small>
<div class="strong"><?php echo $statisticInfo->myDocs;?></div>
</div>
<div class="table-col text-middle">
<div class="progress-pie inline-block" data-value="<?php echo $statisticInfo->myDocsProgress;?>" data-doughnut-size="78" data-color="#00da88">
<canvas width="50" height="50"></canvas>
<div class="progress-info">
<strong><span class="progress-value"><?php echo $statisticInfo->myDocsProgress;?></span><small><?php echo $lang->percent;?></small></strong>
</div>
</div>
</div>
</a>
<a class="table-row">
<div class="table-col text-middle">
<small class="muted"><?php echo $lang->doc->myCollection;?></small>
<div class="strong"><?php echo $statisticInfo->myCollection;?></div>
</div>
<div class="table-col text-middle">
<div class="progress-pie inline-block" data-value="<?php echo $statisticInfo->myCollectionProgress;?>" data-doughnut-size="78" data-color="#fdc137">
<canvas width="50" height="50"></canvas>
<div class="progress-info">
<strong><span class="progress-value"><?php echo $statisticInfo->myCollectionProgress;?></span><small><?php echo $lang->percent;?></small></strong>
</div>
</div>
</div>
</a>
</div>
</div>
</div>
</div>
<div class="col-sm-7">
<div class="panel block-files block-sm" style="height: 290px;">
<div class="panel-heading">
<div class="panel-title"><?php echo $lang->doc->myDoc;?></div>
<nav class="panel-actions nav nav-default">
<li><?php echo html::a($this->createLink('doc', 'browse', "browseType=openedbyme"), strtoupper($lang->more), '', "title='{$lang->more}'");?></li>
</nav>
</div>
<?php if(empty($myDocs)):?>
<div class="table-empty-tip">
<p><span class="text-muted"><?php echo $lang->doc->noDoc;?></span></p>
</div>
<?php else:?>
<div class="panel-body has-table">
<table class="table table-borderless table-fixed-head table-hover">
<thead>
<tr>
<th class="c-name"><?php echo $lang->doc->title;?></th>
<th class="c-num text-right"><?php echo $lang->doc->size;?></th>
<th class="c-user"><?php echo $lang->doc->addedBy;?></th>
<th class="c-datetime"><?php echo $lang->doc->editedDate;?></th>
</tr>
</thead>
<tbody>
<?php foreach($myDocs as $doc):?>
<tr>
<td class="c-name"><?php echo html::a($this->createLink('doc', 'view', "docID={$doc->id}", '', true), $doc->title, '', "data-toggle='modal' data-type='iframe' data-width='90%' title='{$doc->title}'")?></a></td>
<td class="c-num text-right"><?php echo $doc->fileSize ? $doc->fileSize : '-';?></td>
<td class="c-user"><?php echo zget($users, $doc->addedBy);?></td>
<td class="c-datetime"><?php echo formatTime($doc->editedDate) ? formatTime($doc->editedDate, 'Y-m-d') : formatTime($doc->addedDate, 'y-m-d');?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
<?php endif;?>
</div>
</div>
<div class="col-sm-5">
<div class="panel block-files block-sm" style="height: 290px;">
<div class="panel-heading">
<div class="panel-title"><?php echo $lang->doc->myCollection;?></div>
<nav class="panel-actions nav nav-default">
<li><?php echo html::a($this->createLink('doc', 'browse', "browseType=collectedbyme"), strtoupper($lang->more), '', "title='{$lang->more}'");?></li>
</nav>
</div>
<?php if(empty($collectedDocs)):?>
<div class="table-empty-tip">
<p><span class="text-muted"><?php echo $lang->doc->noDoc;?></span></p>
</div>
<?php else:?>
<div class="panel-body has-table">
<table class="table table-borderless table-fixed-head table-hover">
<thead>
<tr>
<th class="c-name"><?php echo $lang->doc->title;?></th>
<th class="c-user"><?php echo $lang->doc->addedBy;?></th>
<th class="c-datetime"><?php echo $lang->doc->editedDate;?></th>
</tr>
</thead>
<tbody>
<?php foreach($collectedDocs as $doc):?>
<tr>
<td class="c-name"><?php echo html::a($this->createLink('doc', 'view', "docID={$doc->id}", '', true), $doc->title, '', "data-toggle='modal' data-type='iframe' data-width='90%' title='{$doc->title}'")?></a></td>
<td class="c-user"><?php echo zget($users, $doc->addedBy);?></td>
<td class="c-datetime"><?php echo formatTime($doc->editedDate) ? formatTime($doc->editedDate, 'Y-m-d') : formatTime($doc->addedDate, 'y-m-d');?></td>
</tr>
<?php endforeach;?>
</tbody>
</table>
</div>
<?php endif;?>
</div>
</div>
</div>
</div>
</div>
<?php echo $this->fetch('block', 'dashboard', 'module=doc');?>
<?php include '../../common/view/footer.html.php';?>
+8 -7
View File
@@ -23,7 +23,7 @@
.input-tree {width: 120px;}
.tree-icon {position: absolute; right: 0;}
.tree li.has-input {overflow: hidden;}
.tree li.has-input > input {margin-left: 15px;}
.tree li.has-input > input.input-bro {margin-left: 15px;}
.img-lib {flex: 0 0 14px; height: 14px; margin-right: 5px;}
.tree-icon {position: absolute; right: 0;}
.tree li > a {max-width: 100%; padding: 2px;}
@@ -118,7 +118,7 @@ js::set('hasLibPriv', $hasLibPriv);
<?php foreach(array('doc', 'api') as $module):?>
<ul class='<?php echo $module;?>LibDorpdown'>
<?php if($canAddCatalog[$module]):?>
<li data-method="addCataLib" data-has-children='%hasChildren%' data-libid='%libID%' data-moduleid="%moduleID%" data-type="add"><a><i class="icon icon-icon-add-directory"></i><?php echo $lang->doc->libDropdown['addModule'];?></a></li>
<li data-method="addCataLib" data-has-children='%hasChildren%' data-libid='%libID%' data-moduleid="%moduleID%" data-type="add"><a><i class="icon icon-add-directory"></i><?php echo $lang->doc->libDropdown['addModule'];?></a></li>
<?php endif;?>
<?php if(common::hasPriv($module, 'editLib')):?>
<li data-method="editLib"><a href='<?php echo inlink('editLib', 'libID=%libID%');?>' data-toggle='modal' data-type='iframe'><i class="icon icon-edit"></i><?php echo $lang->doc->libDropdown['editLib'];?></a></li>
@@ -129,8 +129,8 @@ js::set('hasLibPriv', $hasLibPriv);
</ul>
<ul class='<?php echo $module;?>ModuleDorpdown'>
<?php if($canAddCatalog[$module]):?>
<li data-method="addCataBro" data-type="add" data-id="%moduleID%"><a><i class="icon icon-icon-add-directory"></i><?php echo $lang->doc->libDropdown['addSameModule'];?></a></li>
<li data-method="addCataChild" data-type="add" data-id="%moduleID%" data-has-children='%hasChildren%'><a><i class="icon icon-icon-add-directory"></i><?php echo $lang->doc->libDropdown['addSubModule'];?></a></li>
<li data-method="addCataBro" data-type="add" data-id="%moduleID%"><a><i class="icon icon-add-directory"></i><?php echo $lang->doc->libDropdown['addSameModule'];?></a></li>
<li data-method="addCataChild" data-type="add" data-id="%moduleID%" data-has-children='%hasChildren%'><a><i class="icon icon-add-directory"></i><?php echo $lang->doc->libDropdown['addSubModule'];?></a></li>
<?php endif;?>
<?php if($canEditCatalog[$module]):?>
<li data-method="editCata" class='edit-module'><a data-href='<?php echo helper::createLink($module, 'editCatalog', "moduleID=%moduleID%&type=$app->rawModule");?>'><i class="icon icon-edit"></i><?php echo $lang->doc->libDropdown['editModule'];?></a></li>
@@ -289,7 +289,7 @@ $(function()
if(isFirstLoad) ele.data('zui.tree').collapse();
var $leaf = ele.find('li.active > a');
if($leaf.length && $('#fileTree').height() >= $('#sideBar').height()) $('#sideBar')[0].scrollTop = $($leaf[$leaf.length - 1]).offset().top;
if($leaf.length && $('#fileTree').height() >= $('#sideBar').height()) $('#sideBar')[0].scrollTop = $($leaf[$leaf.length - 1]).offset().top - 100;
ele.on('click', '.icon-drop', function(e)
{
@@ -448,7 +448,8 @@ $(function()
else if(objectType == 'mine' || objectType == 'view' || objectType == 'collect' || objectType == 'createdby')
{
var mySpaceType = 'mine';
if(type == 'view' || type == 'collect' || type == 'createdBy') mySpaceType = type;
if(type == 'view' || type == 'collect') mySpaceType = type;
if(type == 'createdBy' || type == 'createdby') mySpaceType = 'createdby';
methodName = 'mySpace';
linkParams = 'type='+ mySpaceType + '&libID=' + libID + '&moduleID=' + moduleID;
@@ -549,7 +550,7 @@ $(function()
var $rootDom = $('#fileTree li[data-id=' + item.id + ']');
$rootDom.after($input);
$rootDom.closest('ul').find('.has-input').css('padding-left', '0');
$('#fileTree').find('input').focus();
$('#fileTree').find('input').addClass('input-bro').focus();
break;
case 'addCataChild' :
moduleData.parentID = item.id;
+6 -4
View File
@@ -17,6 +17,7 @@ body {margin-bottom: 25px;}
#docListForm th.c-actions {width: 84px; padding-left: 15px;}
#docListForm .c-module, #docListForm .c-object {width: 120px; overflow: hidden; white-space: nowrap; text-overflow: clip;}
#docListForm .table .c-name > .doc-title {display: inline-block; max-width: calc(100% - 80px); overflow: hidden; background: transparent; padding-right:0px;}
#docListForm .table .c-name > span.doc-title {line-height: 0; vertical-align: inherit;}
#docListForm .table .c-name > .draft {background-color:rgba(129, 102, 238, 0.12); color:#8166EE;}
#docListForm .table .c-name > .ajaxCollect {float: right; position: relative; right: 10px; top: 0px;}
#docListForm table.table > thead > tr {height: 32px;}
@@ -25,6 +26,7 @@ body {margin-bottom: 25px;}
#docListForm .checkbox-primary > label {height: 16px; line-height: 16px; padding-left: 16px;}
#docListForm .checkbox-primary > label:before {left: -1px; font-size: 10px;}
#docListForm .checkbox-primary > label:after {width: 12px; height: 12px;}
.table-files .btn {padding: 0 2px;}
</style>
<?php if(common::checkNotCN()):?>
<style>
@@ -37,9 +39,9 @@ body {margin-bottom: 25px;}
<p>
<span class="text-muted"><?php echo $lang->doc->noDoc;?></span>
<?php
if($browseType != 'bySearch' and $libID and (common::hasPriv('doc', 'create') or (common::hasPriv('api', 'create') and !$apiLibID)))
if($browseType != 'bysearch' and $libID and common::hasPriv('doc', 'create'))
{
echo $this->doc->printCreateBtn($lib, $type, $objectID, $moduleID, 'list');
echo $this->doc->printCreateBtn($lib, $moduleID, 'list');
}
?>
</p>
@@ -65,7 +67,7 @@ body {margin-bottom: 25px;}
<th class='c-object'><?php echo $lang->doc->object;?></th>
<th class="c-module"><?php common::printOrderLink('module', $orderBy, $vars, $lang->doc->position);?></th>
<?php endif;?>
<?php if(!in_array($type, array('mine', 'createby'))):?>
<?php if(!in_array($type, array('mine', 'createdby'))):?>
<th class="c-user"><?php common::printOrderLink('addedBy', $orderBy, $vars, $lang->doc->addedByAB);?></th>
<?php endif;?>
<th class="c-date"><?php common::printOrderLink('addedDate', $orderBy, $vars, $lang->doc->addedDate);?></th>
@@ -135,7 +137,7 @@ body {margin-bottom: 25px;}
?>
</td>
<?php endif;?>
<?php if(!in_array($type, array('mine', 'createby'))):?>
<?php if(!in_array($type, array('mine', 'createdby'))):?>
<td class="c-user"><?php echo zget($users, $doc->addedBy);?></td>
<?php endif;?>
<td class="c-datetime"><?php echo formatTime($doc->addedDate, 'Y-m-d');?></td>
+10 -4
View File
@@ -22,20 +22,26 @@
<?php if(!empty($libTree)):?>
<?php foreach($lang->doc->featureBar['tableContents'] as $barType => $barName):?>
<?php $active = $barType == $browseType ? 'btn-active-text' : '';?>
<?php $linkParams = $app->rawMethod == 'tablecontents' ? "type=$type&objectID=$objectID&libID=$libID&moduleID=$moduleID&browseType=$barType": "objectID=$objectID&libID=$libID&moduleID=$moduleID&browseType=$barType";?>
<?php echo html::a($this->createLink('doc', $app->rawMethod, $linkParams), $barName . ($active ? "<span class='label label-light label-badge'>{$pager->recTotal}</span>" : ''), '', "class='btn btn-link $active' id='{$barType}Tab'");?>
<?php $linkParams = "type=$type&libID=$libID&moduleID=$moduleID&browseType=$barType";?>
<?php echo html::a($this->createLink('doc', $app->rawMethod, $linkParams), "<span class='text'>{$barName}</span>" . ($active ? " <span class='label label-light label-badge'>{$pager->recTotal}</span>" : ''), '', "class='btn btn-link $active' id='{$barType}Tab'");?>
<?php endforeach;?>
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php echo $lang->doc->searchDoc;?></a>
<?php endif;?>
</div>
<div class="btn-toolbar pull-right">
<?php
if($canExport)
{
$exportLink = $this->createLink('doc', 'mine2export', "libID=$libID&moduleID=$moduleID", 'html', true);
echo html::a($exportLink, "<i class='icon-export muted'> </i>" . $lang->export, '', "class='btn btn-link export' data-width='480px' id='mine2export'");
}
if(common::hasPriv('doc', 'createLib'))
{
echo html::a(helper::createLink('doc', 'createLib', "type=mine"), '<i class="icon icon-plus"></i> ' . $this->lang->doc->createLib, '', 'class="btn btn-secondary iframe" data-width="800px"');
}
if($libID and common::hasPriv('doc', 'create')) echo $this->doc->printCreateBtn($lib, 'mine', 0, 0);
if($libID and common::hasPriv('doc', 'create')) echo $this->doc->printCreateBtn($lib, $moduleID);
?>
</div>
</div>
@@ -52,7 +58,7 @@
</div>
<div class="sidebar-toggle flex-center"><i class="icon icon-angle-left"></i></div>
<div class="main-col flex-full overflow-visible flex-auto">
<div class="cell<?php if($browseType == 'bySearch') echo ' show';?>" id="queryBox" data-module=<?php echo $type . $libType . 'Doc';?>></div>
<div class="cell<?php if($browseType == 'bysearch') echo ' show';?>" id="queryBox" data-module=<?php echo $type . $libType . 'Doc';?>></div>
<?php include 'mydoclist.html.php'; ?>
</div>
<?php endif;?>
+4 -1
View File
@@ -19,7 +19,7 @@
</div>
<form method='post' class='form-ajax'>
<table class='table table-form'>
<tr><th class='w-120px'></th><td></td><th class='w-100px'></th><td></td></tr>
<tr><th class='w-120px'></th><td></td><th class='w-100px'></th><td></td><td class='w-30px'></td></tr>
<tr>
<th><?php echo $lang->doc->space?></th>
<td colspan='3'><?php echo html::radio('space', $spaceList, key($spaceList), "onchange=changeSpace()");?></td>
@@ -37,6 +37,7 @@
<td class='required'><?php echo html::select('project', $projects, key($projects), "class='form-control picker-select'");?></td>
<th class='executionTH'><?php echo $lang->doc->execution?></th>
<td id='executionBox'><?php echo html::select('execution', array(), '', "class='form-control picker-select' data-placeholder='{$lang->doc->placeholder->execution}' onchange='loadObjectModules(\"execution\", this.value)'")?></td>
<td class='executionHelp pl-0px'><i class='icon icon-help' title='<?php echo $lang->doc->placeholder->execution;?>'></i></td>
</tr>
<tr class='productTR hidden'>
<th><?php echo $lang->doc->product;?></th>
@@ -117,10 +118,12 @@ function changeDocType()
{
var docType = $('[name=type]:not(.hidden):checked').val();
$('.executionTH').removeClass('hidden');
$('.executionHelp').removeClass('hidden');
$('#executionBox').removeClass('hidden');
if(docType == 'api')
{
$('.executionTH').addClass('hidden');
$('.executionHelp').addClass('hidden');
$('#executionBox').addClass('hidden');
$('#project').attr('onchange', "loadObjectModules('project', this.value, '" + docType + "')");
}
+4 -2
View File
@@ -96,7 +96,8 @@
}
echo $commonTitle;
?>
<a title='<?php if(isset($sourcePairs[$file->objectType][$file->objectID])) echo $sourcePairs[$file->objectType][$file->objectID];?>' href='<?php echo $this->createLink(($file->objectType == 'requirement' ? 'story' : $file->objectType), 'view', "objectID=$file->objectID", '', true);?>' class='iframe' data-width='90%'>
<?php $isonlybody = $file->objectType != 'doc';?>
<a title='<?php if(isset($sourcePairs[$file->objectType][$file->objectID])) echo $sourcePairs[$file->objectType][$file->objectID];?>' href='<?php echo $this->createLink(($file->objectType == 'requirement' ? 'story' : $file->objectType), 'view', "objectID=$file->objectID", '', $isonlybody);?>' class='<?php if($isonlybody) echo "iframe";?>' data-width='90%'>
<?php if(isset($sourcePairs[$file->objectType][$file->objectID])) echo $sourcePairs[$file->objectType][$file->objectID];?>
</a>
</td>
@@ -159,7 +160,8 @@
}
echo $commonTitle;
?>
<a href='<?php echo $this->createLink(($file->objectType == 'requirement' ? 'story' : $file->objectType), 'view', "objectID=$file->objectID", '', true);?>' title='<?php if(isset($sourcePairs[$file->objectType][$file->objectID])) echo $sourcePairs[$file->objectType][$file->objectID];?>' class='iframe' data-width='90%'>
<?php $isonlybody = $file->objectType != 'doc';?>
<a href='<?php echo $this->createLink(($file->objectType == 'requirement' ? 'story' : $file->objectType), 'view', "objectID=$file->objectID", '', $isonlybody);?>' title='<?php if(isset($sourcePairs[$file->objectType][$file->objectID])) echo $sourcePairs[$file->objectType][$file->objectID];?>' class='<?php if($isonlybody) echo "iframe";?>' data-width='90%'>
<?php if(isset($sourcePairs[$file->objectType][$file->objectID])) echo $sourcePairs[$file->objectType][$file->objectID];?>
</a>
</div>
+3 -3
View File
@@ -23,7 +23,7 @@
<?php foreach($lang->doc->featureBar['tableContents'] as $barType => $barName):?>
<?php $active = $barType == $browseType ? 'btn-active-text' : '';?>
<?php $linkParams = $app->rawMethod == 'tablecontents' ? "type=$type&objectID=$objectID&libID=$libID&moduleID=$moduleID&browseType=$barType": "objectID=$objectID&libID=$libID&moduleID=$moduleID&browseType=$barType";?>
<?php echo html::a($this->createLink('doc', $app->rawMethod, $linkParams), $barName . ($active ? "<span class='label label-light label-badge'>{$pager->recTotal}</span>" : ''), '', "class='btn btn-link $active' id='{$barType}Tab'");?>
<?php echo html::a($this->createLink('doc', $app->rawMethod, $linkParams), "<span class='text'>{$barName}</span>" . ($active ? " <span class='label label-light label-badge'>{$pager->recTotal}</span>" : ''), '', "class='btn btn-link $active' id='{$barType}Tab'");?>
<?php endforeach;?>
<?php endif;?>
<a class="btn btn-link querybox-toggle" id='bysearchTab'><i class="icon icon-search muted"></i> <?php echo $lang->doc->searchDoc;?></a>
@@ -40,7 +40,7 @@
if($canExport)
{
$exportLink = $this->createLink('doc', $exportMethod, "libID=$libID&docID=0", 'html', true);
$exportLink = $this->createLink('doc', $exportMethod, "libID=$libID&moduleID=$moduleID", 'html', true);
if($libType == 'api') $exportLink = $this->createLink('api', $exportMethod, "libID=$libID", 'html', true);
echo html::a($exportLink, "<i class='icon-export muted'> </i>" . $lang->export, '', "class='btn btn-link export' data-width='480px' id='{$exportMethod}'");
}
@@ -56,7 +56,7 @@
}
elseif($libID and common::hasPriv('doc', 'create'))
{
echo $this->doc->printCreateBtn($lib, $type, $objectID, $moduleID);
echo $this->doc->printCreateBtn($lib, $moduleID);
}
?>
</div>
+22
View File
@@ -16,9 +16,31 @@
<?php js::set('docID', $docID);?>
<?php js::set('linkParams', "objectID=$objectID&%s");?>
<?php js::set('docLang', $lang->doc);?>
<?php js::set('exportMethod', $exportMethod);?>
<?php js::set('libID', $libID);?>
<?php if($app->tab == 'execution'):;?>
<style>.panel-body{min-height: 180px}</style>
<?php endif;?>
<div id="mainMenu" class="clearfix">
<div id="leftBar" class="btn-toolbar pull-left">
<?php echo $objectDropdown;?>
<?php echo html::backButton("<i class='icon icon-back icon-sm'></i> " . $lang->goback, "id='backBtn'", 'btn btn-link')?>
</div>
<div id="crumbs" class="crumbs">
<?php foreach($crumbs as $crumbKey => $crumb):?>
<div class="crumb-item">
<?php if($crumbKey != 0) echo '<div class="separator"> > </div>'?>
<?php echo $crumb;?>
</div>
<?php endforeach;?>
</div>
<div class="btn-toolbar pull-right">
<?php
if($canExport) echo html::a($this->createLink('doc', $exportMethod, "libID=$libID&moduleID=0&docID=$docID"), "<i class='icon-export muted'> </i>" . $lang->export, 'hiddenwin', "class='btn btn-link' id='docExport'");
if(common::hasPriv('doc', 'create')) echo $this->doc->printCreateBtn($lib, $moduleID);
?>
</div>
</div>
<div id='mainContent'class="fade flex">
<?php if($libID):?>
<div id='sideBar' class="panel side side-col col overflow-auto h-full-adjust">
+2
View File
@@ -3716,6 +3716,7 @@ class execution extends control
$period = $type == 'account' ? 'all' : $type;
$date = empty($date) ? '' : date('Y-m-d', $date);
$actions = $this->loadModel('action')->getDynamic($account, $period, $orderBy, $pager, 'all', 'all', $executionID, $date, $direction);
if(empty($recTotal)) $recTotal = count($actions);
/* The header and position. */
$execution = $this->execution->getByID($executionID);
@@ -3735,6 +3736,7 @@ class execution extends control
$this->view->param = $param;
$this->view->dateGroups = $this->action->buildDateGroup($actions, $direction, $type);
$this->view->direction = $direction;
$this->view->recTotal = $recTotal;
$this->display();
}
+3
View File
@@ -26,6 +26,9 @@
.label-action {padding: 0 4px;}
.label-id {margin-left: 4px;}
.timeline > li.active:before {left: -30px;}
.timeline > li.collected:before, .timeline > li.releaseddoc:before {background-color: #FFF;}
.timeline > li.collected > div:after {background-color: #FFAF65;}
.timeline > li.releaseddoc > div:after {background-color: #66A2FF;}
.timeline > li > div:after {left: -27px;}
.timeline .timeline-text {display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
.timeline > li > div > .timeline-tag, .timeline > li > div > .timeline-text > .label-action {color: #838A9D;}
+12 -2
View File
@@ -541,6 +541,8 @@ class executionModel extends model
$lib->type = 'execution';
$lib->main = '1';
$lib->acl = 'default';
$lib->addedBy = $this->app->user->account;
$lib->addedDate = helper::now();
$this->dao->insert(TABLE_DOCLIB)->data($lib)->exec();
$whitelist = explode(',', $sprint->whitelist);
@@ -1603,11 +1605,11 @@ class executionModel extends model
}
/**
* Get project pairs.
* Get execution pairs.
*
* @param int $projectID
* @param string $type all|sprint|stage|kanban
* @param string $mode all|noclosed|stagefilter|withdelete|multiple|leaf|order_asc|empty|noprefix
* @param string $mode all|noclosed|stagefilter|withdelete|multiple|leaf|order_asc|empty|noprefix|withobject
* @access public
* @return array
*/
@@ -1655,6 +1657,10 @@ class executionModel extends model
foreach($allExecutions as $exec) $parents[$exec->parent] = true;
if(strpos($mode, 'order_asc') !== false) $executions = $this->resetExecutionSorts($executions);
if(strpos($mode, 'withobject') !== false)
{
$projectPairs = $this->dao->select('id,name')->from(TABLE_PROJECT)->fetchPairs('id');
}
$pairs = array();
$noMultiples = array();
@@ -1673,6 +1679,8 @@ class executionModel extends model
{
if(isset($allExecutions[$path])) $executionName .= '/' . $allExecutions[$path]->name;
}
if(strpos($mode, 'withobject') !== false) $executionName = zget($projectPairs, $execution->project, '') . $executionName;
if(strpos($mode, 'noprefix') !== false) $executionName = ltrim($executionName, '/');
$pairs[$execution->id] = $executionName;
@@ -3855,6 +3863,8 @@ class executionModel extends model
$burn->estimate -= (int)$finishedEstimate->estimate;
}
$burn->product = 0;
$burn->task = 0;
if(isset($storyPoints[$executionID])) $burn->storyPoint = $storyPoints[$executionID]->storyPoint;
$this->dao->replace(TABLE_BURN)->data($burn)->exec();
+4 -2
View File
@@ -20,7 +20,7 @@
if($period == $type)
{
$active = 'btn-active-text';
$label .= " <span class='label label-light label-badge'>{$pager->recTotal}</span>";
$label .= " <span class='label label-light label-badge'>{$recTotal}</span>";
}
echo html::a(inlink('dynamic', "executionID=$executionID&type=$period"), $label, '', "class='btn btn-link $active' id='{$period}'")
?>
@@ -80,7 +80,9 @@
<?php foreach($actions as $i => $action):?>
<?php if($action->action == 'adjusttasktowait') continue;?>
<?php if(empty($firstAction)) $firstAction = $action;?>
<li <?php if($action->major) echo "class='active'";?>>
<?php $class = $action->major ? 'active' : '';?>
<?php if(in_array($action->action, array('releaseddoc', 'collected'))) $class .= " {$action->action}";?>
<li <?php if($action->major) echo "class='$class'";?>>
<div>
<span class="timeline-tag"><?php echo $action->time?></span>
<span class="timeline-text">
+1
View File
@@ -554,6 +554,7 @@ class groupModel extends model
$data = new stdclass();
$data->account = $account;
$data->group = $groupID;
$data->project = '';
$this->dao->insert(TABLE_USERGROUP)->data($data)->exec();
}
}
+1 -1
View File
@@ -264,7 +264,7 @@ class install extends control
$this->setting->setItem('system.common.global.flow', $this->post->flow);
$this->setting->setItem('system.common.safe.mode', '1');
$this->setting->setItem('system.common.safe.changeWeak', '1');
$this->setting->setItem('system.common.global.cron', 1);
$this->setting->setItem('system.common.global.cron', '1');
$httpType = (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == 'on') ? 'https' : 'http';
if(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) and strtolower($_SERVER['HTTP_X_FORWARDED_PROTO']) == 'https') $httpType = 'https';
+19 -9
View File
@@ -238,6 +238,8 @@ class kanbanModel extends model
$lane->lastEditedTime = helper::now();
$lane->color = '#7ec5ff';
$lane->order = 1;
$lane->groupby = '';
$lane->extra = '';
$this->dao->insert(TABLE_KANBANLANE)->data($lane)->exec();
$laneID = $this->dao->lastInsertId();
@@ -266,6 +268,7 @@ class kanbanModel extends model
$column->order = $order;
$column->limit = -1;
$column->color = '#333';
$column->type = '';
$this->createColumn($regionID, $column);
$order ++;
@@ -2488,6 +2491,10 @@ class kanbanModel extends model
{
$lane->type = $type;
$lane->execution = $executionID;
$lane->region = 0;
$lane->group = 0;
$lane->groupby = '';
$lane->extra = '';
$this->dao->insert(TABLE_KANBANLANE)->data($lane)->exec();
$laneID = $this->dao->lastInsertId();
@@ -2514,9 +2521,10 @@ class kanbanModel extends model
foreach($this->lang->kanban->storyColumn as $colType => $name)
{
$data = new stdClass();
$data->name = $name;
$data->color = '#333';
$data->type = $colType;
$data->name = $name;
$data->color = '#333';
$data->type = $colType;
$data->region = 0;
if(strpos(',developing,developed,', $colType) !== false) $data->parent = $devColumnID;
if(strpos(',testing,tested,', $colType) !== false) $data->parent = $testColumnID;
@@ -2543,9 +2551,10 @@ class kanbanModel extends model
foreach($this->lang->kanban->bugColumn as $colType => $name)
{
$data = new stdClass();
$data->name = $name;
$data->color = '#333';
$data->type = $colType;
$data->name = $name;
$data->color = '#333';
$data->type = $colType;
$data->region = 0;
if(strpos(',fixing,fixed,', $colType) !== false) $data->parent = $resolvingColumnID;
if(strpos(',testing,tested,', $colType) !== false) $data->parent = $testColumnID;
if(strpos(',resolving,test,', $colType) !== false) $data->parent = -1;
@@ -2571,9 +2580,10 @@ class kanbanModel extends model
foreach($this->lang->kanban->taskColumn as $colType => $name)
{
$data = new stdClass();
$data->name = $name;
$data->color = '#333';
$data->type = $colType;
$data->name = $name;
$data->color = '#333';
$data->type = $colType;
$data->region = 0;
if(strpos(',developing,developed,', $colType) !== false) $data->parent = $devColumnID;
if($colType == 'develop') $data->parent = -1;
+1 -1
View File
@@ -1614,7 +1614,7 @@ EOF;
$date = empty($date) ? '' : date('Y-m-d', $date);
$actions = $this->loadModel('action')->getDynamic($this->app->user->account, $type, $orderBy, $pager, 'all', 'all', 'all', $date, $direction);
if(empty($recTotal)) $originTotal = $pager->recTotal;
if(empty($originTotal)) $originTotal = $pager->recTotal;
/* Assign. */
$this->view->type = $type;
+3
View File
@@ -25,6 +25,9 @@
.label-action {padding: 0 4px;}
.label-id {margin-left: 4px;}
.timeline > li.active:before {left: -30px;}
.timeline > li.collected:before, .timeline > li.releaseddoc:before {background-color: #FFF;}
.timeline > li.collected > div:after {background-color: #FFAF65;}
.timeline > li.releaseddoc > div:after {background-color: #66A2FF;}
.timeline > li > div:after {left: -27px;}
.timeline .timeline-text {display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;}
.timeline > li > div > .timeline-tag, .timeline > li > div > .timeline-text > .label-action {color: #838A9D;}
+5 -1
View File
@@ -185,8 +185,12 @@ $lang->my->featureBar['contribute']['requirement']['reviewedBy'] = 'ReviewedByMe
$lang->my->featureBar['contribute']['requirement']['closedBy'] = 'ClosedByMe';
$lang->my->featureBar['contribute']['requirement']['assignedBy'] = 'AssignedByMe';
$lang->my->featureBar['contribute']['bug']['openedBy'] = 'CreatedByMe';
$lang->my->featureBar['contribute']['bug']['resolvedBy'] = 'ResolvedByMe';
$lang->my->featureBar['contribute']['bug']['closedBy'] = 'ClosedByMe';
$lang->my->featureBar['contribute']['bug']['assignedBy'] = 'AssignedByMe';
$lang->my->featureBar['contribute']['story'] = $lang->my->featureBar['contribute']['requirement'];
$lang->my->featureBar['contribute']['bug'] = $lang->my->featureBar['contribute']['requirement'];
$lang->my->featureBar['contribute']['testcase']['openedbyme'] = 'CreatedByMe';
+5 -1
View File
@@ -185,8 +185,12 @@ $lang->my->featureBar['contribute']['requirement']['reviewedBy'] = 'ReviewedByMe
$lang->my->featureBar['contribute']['requirement']['closedBy'] = 'ClosedByMe';
$lang->my->featureBar['contribute']['requirement']['assignedBy'] = 'AssignedByMe';
$lang->my->featureBar['contribute']['bug']['openedBy'] = 'CreatedByMe';
$lang->my->featureBar['contribute']['bug']['resolvedBy'] = 'ResolvedByMe';
$lang->my->featureBar['contribute']['bug']['closedBy'] = 'ClosedByMe';
$lang->my->featureBar['contribute']['bug']['assignedBy'] = 'AssignedByMe';
$lang->my->featureBar['contribute']['story'] = $lang->my->featureBar['contribute']['requirement'];
$lang->my->featureBar['contribute']['bug'] = $lang->my->featureBar['contribute']['requirement'];
$lang->my->featureBar['contribute']['testcase']['openedbyme'] = 'CreatedByMe';
+5 -1
View File
@@ -185,8 +185,12 @@ $lang->my->featureBar['contribute']['requirement']['reviewedBy'] = 'ReviewedByMe
$lang->my->featureBar['contribute']['requirement']['closedBy'] = 'ClosedByMe';
$lang->my->featureBar['contribute']['requirement']['assignedBy'] = 'AssignedByMe';
$lang->my->featureBar['contribute']['bug']['openedBy'] = 'CreatedByMe';
$lang->my->featureBar['contribute']['bug']['resolvedBy'] = 'ResolvedByMe';
$lang->my->featureBar['contribute']['bug']['closedBy'] = 'ClosedByMe';
$lang->my->featureBar['contribute']['bug']['assignedBy'] = 'AssignedByMe';
$lang->my->featureBar['contribute']['story'] = $lang->my->featureBar['contribute']['requirement'];
$lang->my->featureBar['contribute']['bug'] = $lang->my->featureBar['contribute']['requirement'];
$lang->my->featureBar['contribute']['testcase']['openedbyme'] = 'CreatedByMe';
+5 -1
View File
@@ -185,8 +185,12 @@ $lang->my->featureBar['contribute']['requirement']['reviewedBy'] = '由我评审
$lang->my->featureBar['contribute']['requirement']['closedBy'] = '由我关闭';
$lang->my->featureBar['contribute']['requirement']['assignedBy'] = '由我指派';
$lang->my->featureBar['contribute']['bug']['openedBy'] = '由我创建';
$lang->my->featureBar['contribute']['bug']['resolvedBy'] = '由我解决';
$lang->my->featureBar['contribute']['bug']['closedBy'] = '由我关闭';
$lang->my->featureBar['contribute']['bug']['assignedBy'] = '由我指派';
$lang->my->featureBar['contribute']['story'] = $lang->my->featureBar['contribute']['requirement'];
$lang->my->featureBar['contribute']['bug'] = $lang->my->featureBar['contribute']['requirement'];
$lang->my->featureBar['contribute']['testcase']['openedbyme'] = '我建的用例';

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