Merge branch 'master' of https://gitlab.zcorp.cc/easycorp/zentaopms into zentaoipd

This commit is contained in:
tanghucheng
2023-04-14 16:38:09 +08:00
537 changed files with 24278 additions and 14035 deletions
-68
View File
@@ -1,68 +0,0 @@
stages:
- sonarqube
- unit-test
- ui-test
- package
- cleanup-packages
- notify
program-static-analysis:
stage: sonarqube
image:
name: sonarsource/sonar-scanner-cli:latest
entrypoint: [""]
variables:
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache
GIT_DEPTH: "0" # Tells git to fetch all the branches of the project, required by the analysis task
cache:
key: "${CI_JOB_NAME}"
paths:
- .sonar/cache
script:
- sonar-scanner -Dsonar.inclusions=$(git diff --name-only HEAD~1|tr '\n' ',') -Dsonar.analysis.user=${GITLAB_USER_LOGIN}
allow_failure: true
only:
- master # or the name of your main branch
unit-test:
stage: unit-test
script:
- "/home/gitlab-runner/bin/zentao-unittest.sh ${CI_PROJECT_DIR}"
allow_failure: true
only:
- master
- merge_requests
ui-test:
stage: ui-test
script:
- "/home/gitlab-runner/bin/zentao-uitest.sh ${CI_PROJECT_DIR}"
allow_failure: true
only:
- master
- merge_requests
package:
stage: package
script:
- make cizip
allow_failure: true
only:
- master
cleanup-packages:
stage: cleanup-packages
script:
- make clean
when: on_failure
only:
- master
notify:
stage: notify
script:
- "/home/gitlab-runner/bin/ci-notify.php"
when: on_success
only:
- master
- merge_requests
Vendored
+1 -1
View File
@@ -19,7 +19,7 @@ pipeline {
MIDDLE_IMAGE_REPO = "hub.qc.oop.cc/zentao-ztf"
MIDDLE_IMAGE_TAG = """${sh(
returnStdout: true,
script: 'echo $BUILD_ID'
script: 'echo $BUILD_ID-${GIT_COMMIT}'
).trim()}"""
}
+22 -9
View File
@@ -28,8 +28,8 @@ class hostHeartbeatEntry extends baseEntry
/* Check param. */
$status = $this->requestBody->status;
$vms = $this->requestBody->Vms;
$zap = $this->requestBody->port;
$vms = !empty($this->requestBody->Vms) ? $this->requestBody->Vms : array();
$zap = !empty($this->requestBody->port) ? $this->requestBody->port : 0;
$now = helper::now();
if(!$status) return $this->sendError(400, 'Params error.');
@@ -37,7 +37,7 @@ class hostHeartbeatEntry extends baseEntry
$conditionValue = $secret ? $secret : $token;
$this->dao = $this->loadModel('common')->dao;
$hostInfo = $this->dao->select('id,tokenSN')->from(TABLE_ZAHOST)
$hostInfo = $this->dao->select('id,tokenSN,hostType,type')->from(TABLE_ZAHOST)
->beginIF($secret)->where('secret')->eq($secret)->fi()
->beginIF(!$secret)->where('tokenSN')->eq($token)
->andWhere('tokenTime')->gt($now)->fi()
@@ -45,13 +45,15 @@ class hostHeartbeatEntry extends baseEntry
if(empty($hostInfo->id))
{
if(empty($token)) return $this->sendError(400, 'Secret error.');
$hostInfo = $this->dao->select('id,tokenSN')->from(TABLE_ZAHOST)
$hostInfo = $this->dao->select('id,tokenSN,hostType,type')->from(TABLE_ZAHOST)
->where('oldTokenSN')->eq($token)
->andWhere('tokenTime')->gt(date(DT_DATETIME1, strtotime($now) - 30))->fi()
->fetch();
if(empty($hostInfo->id)) return $this->sendError(400, 'Secret error.');
}
$isPhysicsNode = $hostInfo->type == 'node' && $hostInfo->hostType == 'physics' ? true : false;
$host = new stdclass();
$host->status = $status;
if($secret)
@@ -69,7 +71,7 @@ class hostHeartbeatEntry extends baseEntry
foreach($vms as $vm)
{
$heartbeat = strtotime(substr($vm->heartbeat, 0, 19));
$vmData = array(
$vmData = array(
'vnc' => $vm->vncPortOnHost,
'zap' => $vm->agentPortOnHost,
'ztf' => $vm->ztfPortOnHost,
@@ -80,14 +82,25 @@ class hostHeartbeatEntry extends baseEntry
);
if(!$vm->sshPortOnHost) unset($vmData['ssh']);
if($heartbeat > 0) $vmData['heartbeat'] = date("Y-m-d H:i:s", $heartbeat);
$this->dao->update(TABLE_ZAHOST)->data($vmData)->where('mac')->eq($vm->macAddress)->exec();
if($isPhysicsNode)
{
unset($vmData['extranet']);
$this->dao->update(TABLE_ZAHOST)->data($vmData)->where('id')->eq($hostInfo->id)->exec();
}
else
{
$node = $this->loadModel('zanode')->getNodeByMac($vm->macAddress);
if(empty($node)) continue;
if(in_array($node->status, array('restoring', 'creating_img', 'creating_snap')))
$vmData->status = $vm->status = $node->status;
$this->dao->update(TABLE_ZAHOST)->data($vmData)->where('mac')->eq($vm->macAddress)->exec();
}
if($vm->status == 'running')
if($vm->status == 'running' && !$isPhysicsNode)
{
$node = $this->loadModel('zanode')->getNodeByMac($vm->macAddress);
if(!empty($node))
{
$snaps = $this->loadModel('zanode')->getSnapshotList($node->id);
+8 -1
View File
@@ -31,6 +31,7 @@ class hostSubmitEntry extends baseEntry
$image = new stdclass();
$task = $this->requestBody->task;
$image->status = $this->requestBody->status;
$image->status == 'complete' && $image->status = "completed";
$this->dao = $this->loadModel('common')->dao;
$id = $this->dao->select('id')->from(TABLE_ZAHOST)
@@ -40,10 +41,11 @@ class hostSubmitEntry extends baseEntry
if(!$id) return $this->sendError(400, 'Secret error.');
$imageInfo = $this->dao->select('`status`,`from`', 'name')->from(TABLE_IMAGE)
$imageInfo = $this->dao->select('`status`,`from`,name,host')->from(TABLE_IMAGE)
->where('id')->eq($task)
->fetch();
if(empty($imageInfo)) return $this->sendSuccess(200, 'success');
if($imageInfo->from == 'snapshot' && $imageInfo->status == 'restoring')
{
if(in_array($image->status, array('failed', 'completed'))) $image->status = $image->status == 'completed' ? 'restore_completed' : 'restore_failed';
@@ -59,6 +61,11 @@ class hostSubmitEntry extends baseEntry
$this->dao->update(TABLE_IMAGE)->data($image)->where("id")->eq($task)->exec();
if($imageInfo->from != 'zentao' && in_array($imageInfo->status, array('creating', 'restoring')))
{
$this->dao->update(TABLE_ZAHOST)->data(array("status" => "wait"))->where("id")->eq($imageInfo->host)->exec();
}
return $this->sendSuccess(200, 'success');
}
}
+7 -2
View File
@@ -56,11 +56,16 @@ class testcaseEntry extends entry
$stepType = array();
if(isset($this->requestBody->steps))
{
foreach($this->requestBody->steps as $step)
foreach($this->requestBody->steps as $key => $step)
{
if(empty($step->type)) $step->type = 'step';
if(!in_array($step->type, array('step', 'item', 'group'))) $step->type = 'step';
if($step->type == 'group' && (empty($this->requestBody->steps[$key + 1]->type) || $this->requestBody->steps[$key + 1]->type != 'item')) $step->type = 'step';
$steps[] = $step->desc;
$expects[] = $step->expect;
$stepType[] = 'item';
$stepType[] = $step->type;
}
}
+4 -3
View File
@@ -33,9 +33,10 @@ class testcasesEntry extends entry
$param = $moduleID;
}
$this->app->cookie->caseModule = 0;
$this->app->cookie->caseSuite = 0;
$this->app->cookie->preBranch = $branch;
$this->app->cookie->caseModule = 0;
$this->app->cookie->caseSuite = 0;
$this->app->cookie->preBranch = $branch;
$this->app->cookie->showAutoCase = 1;
$control = $this->loadController('testcase', 'browse');
$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));
+1 -1
View File
@@ -21,7 +21,7 @@ class testsuiteEntry extends entry
public function get($testsuiteID)
{
$control = $this->loadController('testsuite', 'view');
$control->view($testsuiteID, $this->param('version', 0));
$control->view($testsuiteID, $this->param('order', 'id_desc'), 0, $this->param('limit', 20), $this->param('page', 1));
$data = $this->getData();
if(!$data or (isset($data->message) and $data->message == '404 Not found')) return $this->send404();
+1 -1
View File
@@ -24,7 +24,7 @@ class testsuitesEntry extends entry
if(empty($productID)) return $this->sendError(400, 'Need product id.');
$control = $this->loadController('testsuite', 'browse');
$control->browse($productID, $this->param('order', 'id_desc'), 0, $this->param('limit', 20), $this->param('page', 1));
$control->browse($productID, 'all', $this->param('order', 'id_desc'), 0, $this->param('limit', 20), $this->param('page', 1));
$data = $this->getData();
if(isset($data->status) and $data->status == 'success')
+9 -6
View File
@@ -87,8 +87,7 @@ $filter->bug->export = new stdclass();
$filter->caselib->create = new stdclass();
$filter->doc->create = new stdclass();
$filter->doc->browse = new stdclass();
$filter->doc->alllibs = new stdclass();
$filter->doc->objectlibs = new stdclass();
$filter->doc->view = new stdclass();
$filter->doc->tablecontents = new stdclass();
$filter->doc->productspace = new stdclass();
$filter->doc->projectspace = new stdclass();
@@ -219,12 +218,12 @@ $filter->caselib->create->cookie['lastLibCaseModule'] = 'int';
$filter->doc->create->cookie['lastDocModule'] = 'int';
$filter->doc->browse->cookie['browseType'] = 'reg::browseType';
$filter->doc->alllibs->cookie['browseType'] = 'reg::browseType';
$filter->doc->objectlibs->cookie['browseType'] = 'reg::browseType';
$filter->doc->objectlibs->cookie['preProductID'] = 'int';
$filter->doc->objectlibs->cookie['preBranch'] = 'reg::word';
$filter->doc->view->cookie['browseType'] = 'reg::browseType';
$filter->doc->view->cookie['preBranch'] = 'reg::word';
$filter->doc->default->cookie['from'] = 'code';
$filter->doc->default->cookie['product'] = 'int';
$filter->doc->default->cookie['preProductID'] = 'int';
$filter->doc->default->cookie['lastProject'] = 'int';
$filter->doc->showfiles->cookie['docFilesViewType'] = 'code';
$filter->doc->tablecontents->cookie['preProductID'] = 'int';
$filter->doc->tablecontents->cookie['preBranch'] = 'reg::word';
@@ -357,6 +356,10 @@ $filter->testtask->cases->cookie['preTaskID'] = 'int';
$filter->testtask->cases->cookie['taskCaseModule'] = 'int';
$filter->testtask->default->cookie['lastProduct'] = 'int';
$filter->testtask->default->cookie['preProductID'] = 'int';
$filter->testcase->browse->cookie['onlyScene'] = 'code';
if(empty($filter->project->testcase)) $filter->project->testcase = new stdclass();
$filter->project->testcase->cookie = array('onlyScene' => 'code');
$filter->todo->export->cookie['checkedItem'] = 'reg::checked';
+5
View File
@@ -357,6 +357,10 @@ define('TABLE_DASHBOARD', '`' . $config->db->prefix . 'dashboard`');
define('TABLE_DATASET', '`' . $config->db->prefix . 'dataset`');
define('TABLE_DATAVIEW', '`' . $config->db->prefix . 'dataview`');
define('TABLE_DIMENSION', '`' . $config->db->prefix . 'dimension`');
define('TABLE_SCENE', '`' . $config->db->prefix . 'scene`');
define('VIEW_SCENECASE', '`ztv_scenecase`');
define('CHANGEVALUE', 100000000);
$config->objectTables['product'] = TABLE_PRODUCT;
$config->objectTables['productplan'] = TABLE_PRODUCTPLAN;
@@ -411,6 +415,7 @@ $config->objectTables['zahost'] = TABLE_ZAHOST;
$config->objectTables['zanode'] = TABLE_ZAHOST;
$config->objectTables['automation'] = TABLE_AUTOMATION;
$config->objectTables['stepResult'] = TABLE_TESTRUN;
$config->objectTables['scene'] = TABLE_SCENE;
$config->newFeatures = array('introduction', 'tutorial', 'youngBlueTheme', 'visions');
$config->disabledFeatures = '';
+258 -37
View File
File diff suppressed because one or more lines are too long
+9445 -9371
View File
File diff suppressed because one or more lines are too long
+3 -1
View File
@@ -135,7 +135,7 @@ class dm extends dao
}
/* Format alias. */
if($alias and ctype_alnum($alias)) $alias = '"' . $alias . '"';
if($alias and !is_numeric($alias) and ctype_alnum($alias)) $alias = '"' . $alias . '"';
return $originField . ' ' . $alias;
}
@@ -298,6 +298,8 @@ class dm extends dao
*/
public function exec($sql = '')
{
if(!empty(dao::$errors)) return new PDOStatement(); // If any error, return an empty statement object to make sure the remain method to execute.
if($sql)
{
$this->sqlobj = new sql();
+6
View File
@@ -280,6 +280,12 @@ class dbh
if(stripos($sql, 'CREATE OR REPLACE VIEW ') === 0) return '';
if(stripos($sql, 'CREATE VIEW') === 0) return '';
if(stripos($sql, 'CREATE FUNCTION') === 0) return '';
if(stripos($sql, 'CREATE UNIQUE INDEX') === 0)
{
preg_match('/ON\ +[0-9a-zA-Z\_\.]+\`([0-9a-zA-Z\_]+)\`/', $sql, $matches);
$tableName = explode('_', $matches[1]);
$sql = preg_replace('/INDEX\ +\`/', 'INDEX `' . strtolower($tableName[1]) . '_', $sql);
}
case 'ALTER':
$sql = $this->formatField($sql);
$sql = $this->formatAttr($sql);
+1 -1
View File
@@ -836,7 +836,7 @@ class gitlab
return array();
}
if($httpCode == 500) return array();
if($httpCode == 500 or $httpCode == 404) return array();
return json_decode($response);
}
}
+318
View File
@@ -0,0 +1,318 @@
<?php
/**
* The xmind library of zentaopms, can be used to bakup and restore a database.
*
* @copyright Copyright 2009-2015 禅道软件(青岛)有限公司(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 Ke Zhao <zhaoke@cnezsoft.com>
* @package Xmind
* @version $Id$
* @link http://www.zentao.net
*/
class xmind
{
/**
* Create module node.
*
* @param DOMDocument $xmlDoc
* @param array $context
* @param DOMElement $productNode
* @param array $moduleNodes
* @access public
* @return void
*/
function createModuleNode($xmlDoc, $context, $productNode, &$moduleNodes)
{
$config = $context['config'];
$moduleList = $context['moduleList'];
foreach($moduleList as $key => $name)
{
$suffix = $config['module'].':'.$key;
$moduleNode = $this->createNode($xmlDoc, $name, $suffix, array('nodeType' => 'module'));
$productNode->appendChild($moduleNode);
$moduleNodes[$key] = $moduleNode;
}
}
/**
* Create scene node.
*
* @param DOMDocument $xmlDoc
* @param array $context
* @param DOMElement $productNode
* @param array $moduleNodes
* @param array $sceneNodes
* @access public
* @return void
*/
function createSceneNode($xmlDoc, $context, $productNode, &$moduleNodes, &$sceneNodes)
{
$sceneMaps = $context['sceneMaps'];
$config = $context['config'];
$topScenes = $context['topScenes'];
foreach($topScenes as $scene)
{
$suffix = $config['scene'].':'.$scene->sceneID;
$sceneNode = $this->createNode($xmlDoc, $scene->sceneName, $suffix, array('nodeType' => 'scene'));
$this->createNextChildScenesNode($scene, $sceneNode, $xmlDoc, $context, $moduleNodes, $sceneNodes);
if(isset($moduleNodes[$scene->moduleID]))
{
$moduleNode = $moduleNodes[$scene->moduleID];
$moduleNode->appendChild($sceneNode);
}
else
{
$productNode->appendChild($sceneNode);
}
$sceneNodes[$scene->sceneID] = $sceneNode;
}
}
/**
* Create next child scene node.
*
* @param object $parentScene
* @param object $parentNode
* @param DOMDocument $xmlDoc
* @param array $context
* @param array $moduleNodes
* @param array $sceneNodes
* @access public
* @return void
*/
function createNextChildScenesNode($parentScene,$parentNode, $xmlDoc, $context, &$moduleNodes, &$sceneNodes)
{
$sceneMaps = $context['sceneMaps'];
$config = $context['config'];
foreach($sceneMaps as $key => $scene)
{
if($scene->parentID != $parentScene->sceneID + CHANGEVALUE) continue;
$suffix = $config['scene'].':'.$scene->sceneID;
$sceneNode = $this->createNode($xmlDoc, $scene->sceneName, $suffix, array('nodeType'=>'scene'));
$this->createNextChildScenesNode($scene, $sceneNode, $xmlDoc, $context, $moduleNodes, $sceneNodes);
$parentNode->appendChild($sceneNode);
$sceneNodes[$scene->sceneID] = $sceneNode;
}
}
/**
* Create test case node.
*
* @param DOMDocument $xmlDoc
* @param array $context
* @param object $productNode
* @param array $moduleNodes
* @param array $sceneNodes
* @access public
* @return void
*/
function createTestcaseNode($xmlDoc, $context, $productNode, &$moduleNodes, &$sceneNodes)
{
$caseList = $context['caseList'];
foreach($caseList as $case)
{
if(empty($case->testcaseID)) continue;
$parentNode = $sceneNodes[$case->sceneID];
if(!isset($parentNode)) $parentNode = $moduleNodes[$case->moduleID];
if(!isset($parentNode)) $parentNode = $productNode;
$this->createOneTestcaseNode($case, $xmlDoc, $context, $parentNode);
}
}
/**
* Create one test case node.
*
* @param object $case
* @param DOMDocument $xmlDoc
* @param array $context
* @param object $parentNode
* @access public
* @return void
*/
function createOneTestcaseNode($case, $xmlDoc, $context, $parentNode)
{
$caseList = $context['caseList'];
$stepList = $context['stepList'];
$config = $context['config'];
$suffix = $config['case'].':'.$case->testcaseID.','.$config['pri'].':'.$case->pri;
$caseNode = $this->createNode($xmlDoc, $case->name, $suffix, array('nodeType'=>'testcase'));
$parentNode->appendChild($caseNode);
$topStepList = $this->findTopStepListByCase($case, $stepList);
foreach($topStepList as $step)
{
$subStepList = $this->findSubStepListByStep($step,$stepList);
$suffix = count($subStepList) > 0 ? $config['group'] : '';
$stepNode = $this->createNode($xmlDoc, $step->desc, $suffix, array('nodeType' => 'step'));
$caseNode->appendChild($stepNode);
if(count($subStepList))
{
foreach($subStepList as $sub)
{
$subNode = $this->createNode($xmlDoc, $sub->desc, '', array('nodeType'=>'substep'));
$stepNode->appendChild($subNode);
if(!empty($sub->expect))
{
$expectNode = $this->createNode($xmlDoc, $sub->expect, '', array('nodeType'=>'expect'));
$subNode->appendChild($expectNode);
}
}
}
if(count($subStepList) == 0 && !empty($step->expect))
{
$expectNode = $this->createNode($xmlDoc, $step->expect, '', array('nodeType'=>'expect'));
$stepNode->appendChild($expectNode);
}
}
}
/**
* Find substep list by step.
*
* @param object $step
* @param array $stepList
* @access public
* @return array
*/
function findSubStepListByStep($step,$stepList)
{
$subList = array();
foreach($stepList as $one)
{
if($one->parentID == $step->stepID)
{
$subList[] = $one;
}
}
return $subList;
}
/**
* Find top step list by case.
*
* @param object $case
* @param array $stepList
* @access public
* @return array
*/
public function findTopStepListByCase($case,$stepList)
{
$topList = array();
foreach($stepList as $step)
{
if($step->parentID == '0' && $step->testcaseID == $case->testcaseID)
{
$topList[] = $step;
}
}
return $topList;
}
/**
* Create xmind node.
*
* @param DOMDocument $xmlDoc
* @param string $text
* @param string $suffix
* @param array $attrs
* @access public
* @return object
*/
public function createNode($xmlDoc, $text, $suffix = '', $attrs=array())
{
$node = $xmlDoc->createElement('node');
$textAttr = $xmlDoc->createAttribute('TEXT');
$textAttrValue = $xmlDoc->createTextNode($this->toText($text,$suffix));
$textAttr->appendChild($textAttrValue);
$node->appendChild($textAttr);
$positionAttr = $xmlDoc->createAttribute("POSITION");
$positionAttrValue = $xmlDoc->createTextNode('right');
$positionAttr->appendChild($positionAttrValue);
$node->appendChild($positionAttr);
foreach($attrs as $key => $value)
{
$attr = $xmlDoc->createAttribute($key);
$attrValue = $xmlDoc->createTextNode($value);
$attr->appendChild($attrValue);
$node->appendChild($attr);
}
return $node;
}
/**
* Add suffix before string.
*
* @param string $str
* @param string $suffix
* @access public
* @return string
*/
public function toText($str, $suffix)
{
if(empty($suffix)) return $str;
return $str . '['.$suffix.']';
}
/**
* Get substring between mark1 and mark2 from kw.
*
* @param string $str
* @param string $suffix
* @access public
* @return string
*/
function getBetween($kw1, $mark1, $mark2)
{
$kw = $kw1;
$kw = '123' . $kw . '123';
$st = strripos($kw, $mark1);
$ed = strripos($kw, $mark2);
if(($st == false || $ed == false) || $st >= $ed) return 0;
$kw = substr($kw, ($st + 1), ($ed - $st - 1));
return $kw;
}
/**
* Judgment ends with a string.
*
* @param string $haystack
* @param string $needle
* @access public
* @return string
*/
function endsWith($haystack, $needle)
{
return $needle === '' || substr_compare($haystack, $needle, -strlen($needle)) === 0;
}
}
+1
View File
@@ -51,6 +51,7 @@ $config->action->objectNameFields['repo'] = 'name';
$config->action->objectNameFields['dataview'] = 'name';
$config->action->objectNameFields['zahost'] = 'name';
$config->action->objectNameFields['zanode'] = 'name';
$config->action->objectNameFields['scene'] = 'title';
$config->action->commonImgSize = 870;
+5 -1
View File
@@ -48,6 +48,9 @@ $lang->action->byQuery = 'Search';
$lang->action->undeleteAction = 'Reset Data';
$lang->action->hideOneAction = 'Hide Data';
$lang->action->refusecase = 'Before restoring the use case, please restore the scene to which the use case belongs';
$lang->action->refusescene = ' Before restoring the use case, please restore the parent scene of this scene ';
$lang->action->trashTips = 'Hinweis: Alle Löschungen in ZenTao sind logische Löschungen.';
$lang->action->textDiff = 'Text Format';
$lang->action->original = 'Original Format';
@@ -156,6 +159,7 @@ $lang->action->objectTypes['stage'] = 'Stage';
$lang->action->objectTypes['patch'] = 'Patch';
$lang->action->objectTypes['repo'] = 'Repo';
$lang->action->objectTypes['dataview'] = 'Data View';
$lang->action->objectTypes['scene'] = 'Scene';
/* Used to describe operation history. */
$lang->action->desc = new stdclass();
@@ -754,7 +758,7 @@ $lang->action->label->testtask = 'Testaufgaben|testtask|view|caseID=%s';
$lang->action->label->testsuite = 'Test Suite|testsuite|view|suiteID=%s';
$lang->action->label->caselib = 'Fallbibliothek|testsuite|libview|libID=%s';
$lang->action->label->todo = 'Todo|todo|view|todoID=%s';
$lang->action->label->doclib = 'Dok Bibliothek|doc|browse|libID=%s';
$lang->action->label->doclib = 'Dok Bibliothek|doc|teamspace|objectID=%s&libID=%s';
$lang->action->label->doc = 'Dok|doc|view|docID=%s';
$lang->action->label->user = 'Benutzer|user|view|account=%s';
$lang->action->label->testreport = 'Berichte|testreport|view|report=%s';
+5 -1
View File
@@ -48,6 +48,9 @@ $lang->action->byQuery = 'Search';
$lang->action->undeleteAction = 'Reset Data';
$lang->action->hideOneAction = 'Hide Data';
$lang->action->refusecase = 'Before restoring the use case, please restore the scene to which the use case belongs';
$lang->action->refusescene = ' Before restoring the use case, please restore the parent scene of this scene ';
$lang->action->trashTips = 'Note: Delete in ZenTao is logic.';
$lang->action->textDiff = 'Text Format';
$lang->action->original = 'Original Format';
@@ -156,6 +159,7 @@ $lang->action->objectTypes['stage'] = 'Stage';
$lang->action->objectTypes['patch'] = 'Patch';
$lang->action->objectTypes['repo'] = 'Repo';
$lang->action->objectTypes['dataview'] = 'Data View';
$lang->action->objectTypes['scene'] = 'Scene';
/* Used to describe operation history. */
$lang->action->desc = new stdclass();
@@ -754,7 +758,7 @@ $lang->action->label->testtask = 'Request|testtask|view|caseID=%s';
$lang->action->label->testsuite = 'Test Suite|testsuite|view|suiteID=%s';
$lang->action->label->caselib = 'Case Library|caselib|view|libID=%s';
$lang->action->label->todo = 'Todo|todo|view|todoID=%s';
$lang->action->label->doclib = 'Doc Library|doc|objectLibs|type=%s&objectID=%s&libID=%s';
$lang->action->label->doclib = 'Doc Library|doc|teamspace|objectID=%s&libID=%s';
$lang->action->label->doc = 'Doc|doc|view|docID=%s';
$lang->action->label->user = 'User|user|view|account=%s';
$lang->action->label->testreport = 'Report|testreport|view|report=%s';
+5 -1
View File
@@ -48,6 +48,9 @@ $lang->action->byQuery = 'Search';
$lang->action->undeleteAction = 'Reset Data';
$lang->action->hideOneAction = 'Hide Data';
$lang->action->refusecase = 'Before restoring the use case, please restore the scene to which the use case belongs';
$lang->action->refusescene = ' Before restoring the use case, please restore the parent scene of this scene ';
$lang->action->trashTips = 'Note: Les suppressions dans ZenTao sont purement logiques.';
$lang->action->textDiff = 'Text Format';
$lang->action->original = 'Original Format';
@@ -156,6 +159,7 @@ $lang->action->objectTypes['stage'] = 'Stage';
$lang->action->objectTypes['patch'] = 'Patch';
$lang->action->objectTypes['repo'] = 'Repo';
$lang->action->objectTypes['dataview'] = 'Data View';
$lang->action->objectTypes['scene'] = 'Scene';
/* Used to describe operation history. */
$lang->action->desc = new stdclass();
@@ -754,7 +758,7 @@ $lang->action->label->testtask = 'Recette|testtask|view|caseID=%s';
$lang->action->label->testsuite = 'Cahier Recette|testsuite|view|suiteID=%s';
$lang->action->label->caselib = 'Library Recette|testsuite|libview|libID=%s';
$lang->action->label->todo = 'Agenda|todo|view|todoID=%s';
$lang->action->label->doclib = 'Bibliothèque|doc|browse|libID=%s';
$lang->action->label->doclib = 'Bibliothèque|doc|teamspace|objectID=%s&libID=%s';
$lang->action->label->doc = 'Document|doc|view|docID=%s';
$lang->action->label->user = 'Utilisateur|user|view|account=%s';
$lang->action->label->testreport = 'Rapport|testreport|view|report=%s';
+4
View File
@@ -48,6 +48,9 @@ $lang->action->history->old = 'Giá trị cũ';
$lang->action->history->new = 'Giá trị mới';
$lang->action->history->diff = 'So sánh';
$lang->action->refusecase = 'Before restoring the use case, please restore the scene to which the use case belongs';
$lang->action->refusescene = ' Before restoring the use case, please restore the parent scene of this scene ';
$lang->action->dynamic = new stdclass();
$lang->action->dynamic->today = 'Hôm nay';
$lang->action->dynamic->yesterday = 'Hôm qua';
@@ -123,6 +126,7 @@ $lang->action->objectTypes['stage'] = 'Stage';
$lang->action->objectTypes['patch'] = 'Patch';
$lang->action->objectTypes['repo'] = 'Repo';
$lang->action->objectTypes['dataview'] = 'Data View';
$lang->action->objectTypes['scene'] = 'Scene';
/* Used to describe operation history. */
$lang->action->desc = new stdclass();
+6 -1
View File
@@ -48,6 +48,9 @@ $lang->action->byQuery = '搜索';
$lang->action->undeleteAction = '还原数据';
$lang->action->hideOneAction = '隐藏数据';
$lang->action->refusecase = '还原用例之前,请先还原该用例所属场景';
$lang->action->refusescene = '还原场景之前,请先还原该场景的父场景';
$lang->action->trashTips = '提示:为了保证系统的完整性,禅道系统的删除都是标记删除。';
$lang->action->textDiff = '文本格式';
$lang->action->original = '原始格式';
@@ -156,6 +159,8 @@ $lang->action->objectTypes['stage'] = '阶段';
$lang->action->objectTypes['patch'] = '补丁';
$lang->action->objectTypes['repo'] = '代码库';
$lang->action->objectTypes['dataview'] = '中间表';
$lang->action->objectTypes['scene'] = '场景';
/* 用来描述操作历史记录。*/
$lang->action->desc = new stdclass();
@@ -754,7 +759,7 @@ $lang->action->label->testtask = '测试单|testtask|view|caseID=%s';
$lang->action->label->testsuite = '测试套件|testsuite|view|suiteID=%s';
$lang->action->label->caselib = '用例库|caselib|view|libID=%s';
$lang->action->label->todo = '待办|todo|view|todoID=%s';
$lang->action->label->doclib = '文档库|doc|tablecontents|type=%s&objectID=%s&libID=%s';
$lang->action->label->doclib = '文档库|doc|teamspace|objectID=%s&libID=%s';
$lang->action->label->doc = '文档|doc|view|docID=%s';
$lang->action->label->user = '用户|user|view|account=%s';
$lang->action->label->testreport = '报告|testreport|view|report=%s';
+4
View File
@@ -46,6 +46,9 @@ $lang->action->comment = '備註';
$lang->action->undeleteAction = '還原數據';
$lang->action->hideOneAction = '隱藏數據';
$lang->action->refusecase = 'Before restoring the use case, please restore the scene to which the use case belongs';
$lang->action->refusescene = ' Before restoring the use case, please restore the parent scene of this scene ';
$lang->action->trashTips = '提示:為了保證系統的完整性,禪道系統的刪除都是標記刪除。';
$lang->action->textDiff = '文本格式';
$lang->action->original = '原始格式';
@@ -136,6 +139,7 @@ $lang->action->objectTypes['kanbancolumn'] = '看板列';
$lang->action->objectTypes['kanbancard'] = '看板卡片';
$lang->action->objectTypes['repo'] = '代码库';
$lang->action->objectTypes['dataview'] = '数据表';
$lang->action->objectTypes['scene'] = 'Scene';
/* 用來描述操作歷史記錄。*/
$lang->action->desc = new stdclass();
+23 -1
View File
@@ -1709,7 +1709,6 @@ class actionModel extends model
$method = 'tablecontents';
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);
}
@@ -1946,6 +1945,29 @@ class actionModel extends model
if($release->shadow) $this->dao->update(TABLE_BUILD)->set('deleted')->eq(0)->where('id')->eq($release->shadow)->exec();
}
if($action->objectType == 'case')
{
$case = $this->dao->select('*')->from(TABLE_CASE)->where('id')->eq($action->objectID)->fetch();
if($case->scene)
{
$scene = $this->dao->select('*')->from(VIEW_SCENECASE)->where('id')->eq($case->scene)->fetch();
if($scene->deleted)
{
return print(js::error($this->lang->action->refusecase));
}
}
}
if($action->objectType == 'scene')
{
$scene = $this->dao->select('*')->from("zt_scene")->where('id')->eq($action->objectID)->fetch();
if($scene->parent)
{
$scenerow = $this->dao->select('*')->from(VIEW_SCENECASE)->where('id')->eq($scene->parent)->fetch();
if($scenerow->deleted) return print(js::error($this->lang->action->refusescene));
}
}
/* Update deleted field in object table. */
$table = $this->config->objectTables[$action->objectType];
$this->dao->update($table)->set('deleted')->eq(0)->where('id')->eq($action->objectID)->exec();
+6
View File
@@ -102,6 +102,11 @@
<tr>
<td><?php echo zget($lang->action->objectTypes, $action->objectType, '');?></td>
<td><?php echo $action->objectID;?></td>
<?php if($action->objectType == 'scene'): ?>
<td class='text-left'>
<?php echo $action->objectName;?>
</td>
<?php else: ?>
<td class='text-left'>
<?php
$params = $action->objectType == 'user' ? "account={$action->objectName}" : "id={$action->objectID}";
@@ -146,6 +151,7 @@
}
?>
</td>
<?php endif ?>
<?php if($currentObjectType == 'execution'):?>
<td class="c-name flex" title="<?php echo $projectList[$action->project]->name;?>">
<span class="text-ellipsis"><?php echo $projectList[$action->project]->name;?></span>
+1 -1
View File
@@ -872,7 +872,7 @@ class api extends control
$response['result'] = 'success';
$response['status'] = $status;
$response['url'] = $result['url'];
$response['url'] = htmlspecialchars($result['url']);
$response['data'] = $data;
return print(json_encode($response));
}
+4 -3
View File
@@ -12,6 +12,7 @@
$lang->api->common = 'API';
$lang->api->getModel = 'Super Model API';
$lang->api->sql = 'SQL Query API';
$lang->api->manage = 'API management';
$lang->api->index = 'API Space';
$lang->api->editLib = 'Edit';
@@ -60,7 +61,7 @@ $lang->api->defaultVersion = "Current Version";
$lang->api->zentaoAPI = "Zentao API v1";
$lang->api->search = "Search";
$lang->api->allLibs = "AllLibs";
$lang->api->noLinked = "No Linked";
$lang->api->noLinked = "No Linked {$lang->productCommon} and {$lang->projectCommon}";
$lang->api->addCatalog = 'Add Catalog';
$lang->api->editCatalog = 'Edit Catalog';
$lang->api->deleteCatalog = 'Delete Catalog';
@@ -108,7 +109,7 @@ $lang->api->structAddedBy = 'CreatedBy';
$lang->api->structAddedDate = 'Created';
$lang->api->name = 'API Library Name';
$lang->api->baseUrl = 'Base URL';
$lang->api->baseUrlDesc = 'Site or path, e.g., api.zentao.com or /v1.';
$lang->api->baseUrlDesc = 'Site or path, e.g., http://api.zentao.com or /v1.';
$lang->api->desc = 'Beschreibung';
$lang->api->control = 'Access Control';
$lang->api->noLib = 'No API library yet.';
@@ -180,7 +181,7 @@ $lang->api->requestTypeOptions['multipart/form-data'] = 'multipart
$lang->api->libTypeList = array();
$lang->api->libTypeList['product'] = $lang->productCommon . ' Api Library';
$lang->api->libTypeList['project'] = $lang->projectCommon . ' Api Library';
$lang->api->libTypeList['nolink'] = 'No Linked Api Library';
$lang->api->libTypeList['nolink'] = 'Independent Api Library';
$lang->api->statusOptions = array(
'done' => 'Done',
+4 -3
View File
@@ -12,6 +12,7 @@
$lang->api->common = 'API';
$lang->api->getModel = 'Super Model API';
$lang->api->sql = 'SQL Query API';
$lang->api->manage = 'API management';
$lang->api->index = 'API Space';
$lang->api->editLib = 'Edit';
@@ -60,7 +61,7 @@ $lang->api->defaultVersion = "Current Version";
$lang->api->zentaoAPI = "Zentao API v1";
$lang->api->search = "Search";
$lang->api->allLibs = "AllLibs";
$lang->api->noLinked = "No Linked";
$lang->api->noLinked = "No Linked {$lang->productCommon} and {$lang->projectCommon}";
$lang->api->addCatalog = 'Add Catalog';
$lang->api->editCatalog = 'Edit Catalog';
$lang->api->deleteCatalog = 'Delete Catalog';
@@ -108,7 +109,7 @@ $lang->api->structAddedBy = 'CreatedBy';
$lang->api->structAddedDate = 'Created';
$lang->api->name = 'API Library Name';
$lang->api->baseUrl = 'Base URL';
$lang->api->baseUrlDesc = 'Site or path, e.g., api.zentao.com or /v1.';
$lang->api->baseUrlDesc = 'Site or path, e.g., http://api.zentao.com or /v1.';
$lang->api->desc = 'Description';
$lang->api->control = 'Access Control';
$lang->api->noLib = 'No API library yet.';
@@ -180,7 +181,7 @@ $lang->api->requestTypeOptions['multipart/form-data'] = 'multipart
$lang->api->libTypeList = array();
$lang->api->libTypeList['product'] = $lang->productCommon . ' Api Library';
$lang->api->libTypeList['project'] = $lang->projectCommon . ' Api Library';
$lang->api->libTypeList['nolink'] = 'No Linked Api Library';
$lang->api->libTypeList['nolink'] = 'Independent Api Library';
$lang->api->statusOptions = array(
'done' => 'Done',
+4 -3
View File
@@ -12,6 +12,7 @@
$lang->api->common = 'API';
$lang->api->getModel = 'Super Model API';
$lang->api->sql = 'SQL Query API';
$lang->api->manage = 'API management';
$lang->api->index = 'API Space';
$lang->api->editLib = 'Edit';
@@ -60,7 +61,7 @@ $lang->api->defaultVersion = "Current Version";
$lang->api->zentaoAPI = "Zentao API v1";
$lang->api->search = "Search";
$lang->api->allLibs = "AllLibs";
$lang->api->noLinked = "No Linked";
$lang->api->noLinked = "No Linked {$lang->productCommon} and {$lang->projectCommon}";
$lang->api->addCatalog = 'Add Catalog';
$lang->api->editCatalog = 'Edit Catalog';
$lang->api->deleteCatalog = 'Delete Catalog';
@@ -108,7 +109,7 @@ $lang->api->structAddedBy = 'CreatedBy';
$lang->api->structAddedDate = 'Created';
$lang->api->name = 'API Library Name';
$lang->api->baseUrl = 'Base URL';
$lang->api->baseUrlDesc = 'Site or path, e.g., api.zentao.com or /v1.';
$lang->api->baseUrlDesc = 'Site or path, e.g., http://api.zentao.com or /v1.';
$lang->api->desc = 'Description';
$lang->api->control = 'Access Control';
$lang->api->noLib = 'No API library yet.';
@@ -180,7 +181,7 @@ $lang->api->requestTypeOptions['multipart/form-data'] = 'multipart
$lang->api->libTypeList = array();
$lang->api->libTypeList['product'] = $lang->productCommon . ' Api Library';
$lang->api->libTypeList['project'] = $lang->projectCommon . ' Api Library';
$lang->api->libTypeList['nolink'] = 'No Linked Api Library';
$lang->api->libTypeList['nolink'] = 'Independent Api Library';
$lang->api->statusOptions = array(
'done' => 'Done',
+4 -3
View File
@@ -12,6 +12,7 @@
$lang->api->common = 'API接口';
$lang->api->getModel = '超级model调用接口';
$lang->api->sql = 'SQL查询接口';
$lang->api->manage = '接口管理';
$lang->api->index = '接口空间';
$lang->api->editLib = '编辑库';
@@ -60,7 +61,7 @@ $lang->api->defaultVersion = "当前版本";
$lang->api->zentaoAPI = "禅道API文档v1";
$lang->api->search = "搜索";
$lang->api->allLibs = "全部库";
$lang->api->noLinked = "无关联";
$lang->api->noLinked = "未关联{$lang->productCommon}和{$lang->projectCommon}";
$lang->api->addCatalog = '添加目录';
$lang->api->editCatalog = '编辑目录';
$lang->api->deleteCatalog = '删除目录';
@@ -108,7 +109,7 @@ $lang->api->structAddedBy = '创建人';
$lang->api->structAddedDate = '创建时间';
$lang->api->name = '库名称';
$lang->api->baseUrl = '请求基础路径';
$lang->api->baseUrlDesc = '网址或者路径,比如 test.zentao.net 或者 /v1';
$lang->api->baseUrlDesc = '网址或者路径,比如 http://test.zentao.net 或者 /v1';
$lang->api->desc = '描述';
$lang->api->control = '访问控制';
$lang->api->noLib = '暂时没有库。';
@@ -180,7 +181,7 @@ $lang->api->requestTypeOptions['multipart/form-data'] = 'multipart
$lang->api->libTypeList = array();
$lang->api->libTypeList['product'] = $lang->productCommon . '接口库';
$lang->api->libTypeList['project'] = $lang->projectCommon . '接口库';
$lang->api->libTypeList['nolink'] = '无关联接口库';
$lang->api->libTypeList['nolink'] = '独立接口库';
$lang->api->statusOptions = array(
'done' => '开发完成',
+4 -4
View File
@@ -986,13 +986,13 @@ class apiModel extends model
$normalObjects = $closedObjects = array();
$libs = $this->loadModel('doc')->getApiLibs();
$products = $this->dao->select('t1.id, t1.name, t1.status')->from(TABLE_PRODUCT)->alias('t1')
$products = $this->dao->select('t1.id, t1.order, t1.name, t1.status')->from(TABLE_PRODUCT)->alias('t1')
->leftjoin(TABLE_DOCLIB)->alias('t2')->on('t2.product=t1.id')
->where('t2.id')->gt(0)
->andWhere('t1.vision')->eq($this->config->vision)
->andWhere('t1.deleted')->eq(0)
->andWhere('t2.id')->in(array_keys($libs))
->orderBy('id_desc')
->orderBy('order_asc')
->fetchAll('id');
foreach($products as $id => $product)
@@ -1007,14 +1007,14 @@ class apiModel extends model
}
}
$projects = $this->dao->select('t1.id, t1.name, t1.status')->from(TABLE_PROJECT)->alias('t1')
$projects = $this->dao->select('t1.id, t1.order, t1.name, t1.status')->from(TABLE_PROJECT)->alias('t1')
->leftjoin(TABLE_DOCLIB)->alias('t2')->on('t2.project=t1.id')
->where('t2.id')->gt(0)
->andWhere('t1.vision')->eq($this->config->vision)
->andWhere('t1.deleted')->eq(0)
->beginIF(!$this->app->user->admin)->andWhere('t1.id')->in($this->app->user->view->projects)->fi()
->andWhere('t2.id')->in(array_keys($libs))
->orderBy('t1.hasProduct_asc, id_desc')
->orderBy('t1.hasProduct_asc, order_asc')
->fetchAll('id');
foreach($projects as $id => $project)
+2 -2
View File
@@ -341,11 +341,11 @@ $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']['title'] = 'My Collection Document';
$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']['title'] = 'Recently Update Document';
$lang->block->default['doc']['4']['block'] = 'docrecentupdate';
$lang->block->default['doc']['4']['grid'] = 8;
+2 -2
View File
@@ -341,11 +341,11 @@ $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']['title'] = 'My Collection Document';
$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']['title'] = 'Recently Update Document';
$lang->block->default['doc']['4']['block'] = 'docrecentupdate';
$lang->block->default['doc']['4']['grid'] = 8;
+2 -2
View File
@@ -341,11 +341,11 @@ $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']['title'] = 'My Collection Document';
$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']['title'] = 'Recently Update Document';
$lang->block->default['doc']['4']['block'] = 'docrecentupdate';
$lang->block->default['doc']['4']['grid'] = 8;
+2 -2
View File
@@ -341,11 +341,11 @@ $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']['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']['title'] = '最近更新的文档';
$lang->block->default['doc']['4']['block'] = 'docrecentupdate';
$lang->block->default['doc']['4']['grid'] = 8;
+2 -2
View File
@@ -219,7 +219,7 @@ class blockModel extends model
->orWhere('t3.status')->ne('suspended')
->markRight(1)
->andWhere('t1.status')->in('wait,doing')
->andWhere('t1.deadline')->ne('0000-00-00')
->andWhere('t1.deadline')->notZeroDate()
->andWhere('t1.deadline')->lt($today)
->andWhere('t1.deleted')->eq(0)
->andWhere('t3.deleted')->eq(0)
@@ -228,7 +228,7 @@ class blockModel extends model
->leftJoin(TABLE_PRODUCT)->alias('t2')->on('t1.product=t2.id')
->where('t1.assignedTo')->eq($this->app->user->account)
->andWhere('t1.status')->eq('active')
->andWhere('t1.deadline')->ne('0000-00-00')
->andWhere('t1.deadline')->notZeroDate()
->andWhere('t1.deadline')->lt($today)
->andWhere('t1.deleted')->eq(0)
->andWhere('t2.deleted')->eq(0)
@@ -13,14 +13,14 @@
<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 {border: unset; flex: 0 1 50%; padding: 8px; width: 0;}
.block-docmycollection .doc-list > .doc-box > button.btn {padding: 5px 10px; height: 100%; width: 100%; cursor: pointer; white-space: nowrap; 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 .date-interval {float: right; padding: 8px 0 8px 12px;}
.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 .file-icon {margin-right: 2px; width: 14px;}
.block-docmycollection .doc-list > .doc-box .plug-title {height: 16px; overflow: hidden;}
.block-docmycollection.block-sm .doc-list > .doc-box {flex: 0 1 100%;}
@@ -13,14 +13,14 @@
<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 {border: unset; flex: 0 1 33%; padding: 8px; width: 0;}
.block-docrecentupdate .doc-list > .doc-box > button.btn {padding: 5px 10px; height: 100%; width: 100%; cursor: pointer; white-space: nowrap; 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 .date-interval {float: right; padding: 8px 0 8px 12px;}
.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 .file-icon {margin-right: 2px; width: 14px;}
.block-docrecentupdate .doc-list > .doc-box .plug-title {height: 16px; overflow: hidden;}
.block-docrecentupdate.block-sm .doc-list > .doc-box {flex: 0 1 100%;}
+1 -1
View File
@@ -11,7 +11,7 @@
*/
?>
<style>
.block-docstatistic .flex {display: flex; flex-wrap: nowrap; flex-direction: row; justify-content: space-between; flex: auto;}
.block-docstatistic .flex {display: flex; flex-wrap: nowrap; flex-direction: row; justify-content: space-around; 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%;}
+2 -5
View File
@@ -414,11 +414,8 @@ class buildModel extends model
$build->bugs = '';
$build = fixer::input('post')
->setDefault('project', 0)
->setDefault('execution', 0)
->setDefault('product', 0)
->setDefault('branch', 0)
->setDefault('builds', '')
->setDefault('project,execution,product,branch', 0)
->setDefault('builds,stories,bugs', '')
->cleanInt('product')
->add('createdBy', $this->app->user->account)
->add('createdDate', helper::now())
+2 -1
View File
@@ -65,6 +65,7 @@ class chart extends control
$filters = $this->post->filters;
$fieldSettings = $this->post->fieldSettings;
$langs = $this->post->langs;
$sql = $this->post->sql;
$clientLang = $this->app->getClientLang();
$fieldPairs = array();
@@ -91,7 +92,7 @@ class chart extends control
if($type == 'select')
{
$fieldSetting = $fieldSettings[$field];
$options = $this->chart->getSysOptions(zget($fieldSetting, 'type', ''), zget($fieldSetting, 'object', ''), zget($fieldSetting, 'field', ''));
$options = $this->chart->getSysOptions(zget($fieldSetting, 'type', ''), zget($fieldSetting, 'object', ''), zget($fieldSetting, 'field', ''), $sql);
}
$filterHtml = array();
+23 -2
View File
@@ -36,15 +36,36 @@ function resizeChart()
}
}
function waitForRepaint(callback)
{
window.requestAnimationFrame(function()
{
window.requestAnimationFrame(callback);
});
}
/**
* Init picker.
*
* @access public
* @return void
*/
function initPicker($row, pickerName = 'picker-select')
function initPicker($row, pickerName = 'picker-select', onready = false)
{
$row.find('.' + pickerName).picker({'maxDropHeight': pickerHeight});
$row.find('.' + pickerName).picker(
{
maxDropHeight: pickerHeight,
onReady: function()
{
if(!onready) return;
if(!$row.find('.picker')) return;
if(window.getComputedStyle($row.find('.picker').find('.picker-selections')[0]).getPropertyValue('width') !== 'auto')
{
var pickerWidth = $row.find('.picker')[0].getBoundingClientRect().width;
$row.find('.picker').find('.picker-selections').css('width', pickerWidth);
}
}
});
$row.find("." + pickerName).each(function(index)
{
if($(this).hasClass('required')) $(this).siblings("div .picker").addClass('required');
+25 -9
View File
@@ -159,14 +159,15 @@ function calcPreviewGrowFilter(resize = false)
chart.filters.forEach(function(filter, index)
{
var nowItem = '.filter-item-' + index;
var leftPadding = parseInt($filterItems.find(nowItem).css('padding-left'));
var rightPadding = parseInt($filterItems.find(nowItem).css('padding-right'));
var spanWidth = $filterItems.find(nowItem).find('.input-group-addon').first()[0].getBoundingClientRect().width;
var $nowDom = $filterItems.find(nowItem);
var leftPadding = parseInt($nowDom.css('padding-left'));
var rightPadding = parseInt($nowDom.css('padding-right'));
var spanWidth = $nowDom.find('.input-group-addon').first()[0].getBoundingClientRect().width;
var filterWidth = ((filter.type == 'input' || filter.type == 'select') ? WIDTH_INPUT : WIDTH_DATE) + (spanWidth + leftPadding + rightPadding);
/* Clear the flex-basis and set flex-basic again. */
$filterItems.find(nowItem).css('flex-basis', '');
$filterItems.find(nowItem).css('flex-basis', filterWidth);
$nowDom.css('flex-basis', '');
$nowDom.css('flex-basis', filterWidth);
if(nowWidth - filterWidth >= 0)
{
nowWidth -= filterWidth;
@@ -185,12 +186,27 @@ function calcPreviewGrowFilter(resize = false)
$filterItems.children().removeClass('filter-item-grow');
chart.filters.forEach(function(filter, index)
{
var nowItem = '.filter-item-' + index;
if(canGrowTotal >= index + 1) $filterItems.find(nowItem).addClass('filter-item-grow');
var $nowDom = $filterItems.find('.filter-item-' + index);
if(canGrowTotal >= index + 1) $nowDom.addClass('filter-item-grow');
if(filter.type == 'select' && $nowDom.find('.picker').length) $nowDom.find('.picker').find('.picker-selections').css('width', WIDTH_INPUT);
});
var queryType =(!lineWrap && nowWidth >= 60) ? '.query-inside' : '.query-outside';
$filterBox.find(queryType).removeClass('hidden');
/* Set picker-selection width, default 128px. */
waitForRepaint(function()
{
chart.filters.forEach(function(filter, index)
{
var $nowDom = $filterItems.find('.filter-item-' + index);
if(filter.type == 'select' && $nowDom.find('.picker').length)
{
var pickerWidth = $nowDom.hasClass('filter-item-grow') ? $nowDom.find('.picker')[0].getBoundingClientRect().width : WIDTH_INPUT;
$nowDom.find('.picker').find('.picker-selections').css('width', pickerWidth);
}
});
});
});
}
@@ -206,7 +222,7 @@ function renderFilters(chart)
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)
$.post(createLink('chart', 'ajaxGetFilterForm', 'chartID=' + chart.id), {fieldList: fieldNames, fieldSettings: chart.fieldSettings, filters: chart.filters, langs: chart.langs, sql: chart.sql}, function(resp)
{
resp = JSON.parse(resp);
var $filterItems = $('#filterItems' + chart.currentGroup + '_' + chart.id + ' .filter-items');
@@ -230,7 +246,7 @@ function renderFilterItem(filter, resp, index, step)
search: resp[index].item
};
var html = $($.zui.formatString(tpl, data))
initPicker(html);
initPicker(html, 'picker-select', true);
initDatepicker(html);
return html;
}
+1 -1
View File
@@ -4,7 +4,7 @@ $lang->chart->query = 'Query';
$lang->chart->toDesign = 'To Design';
$lang->chart->group = 'Group';
$lang->chart->field = 'Field';
$lang->chart->field = 'Related Field';
$lang->chart->agg = 'Aggregate';
$lang->chart->chooseField = 'Choose field';
$lang->chart->aggType = 'Aggregate type';
+1 -1
View File
@@ -4,7 +4,7 @@ $lang->chart->query = 'Query';
$lang->chart->toDesign = 'To Design';
$lang->chart->group = 'Group';
$lang->chart->field = 'Field';
$lang->chart->field = 'Related Field';
$lang->chart->agg = 'Aggregate';
$lang->chart->chooseField = 'Choose field';
$lang->chart->aggType = 'Aggregate type';
+1 -1
View File
@@ -4,7 +4,7 @@ $lang->chart->query = 'Query';
$lang->chart->toDesign = 'To Design';
$lang->chart->group = 'Group';
$lang->chart->field = 'Field';
$lang->chart->field = 'Related Field';
$lang->chart->agg = 'Aggregate';
$lang->chart->chooseField = 'Choose field';
$lang->chart->aggType = 'Aggregate type';
+2 -2
View File
@@ -477,8 +477,8 @@ class chartModel extends model
$series[] = array('name' => $seriesName, 'data' => $yData, 'type' => 'bar', 'stack' => $stack);
}
$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}]';
$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":"#ccc","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":"#ccc","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);
+2 -1
View File
@@ -41,10 +41,11 @@ $lang->company = new stdclass();
$lang->dept = new stdclass();
$lang->group = new stdclass();
$lang->user = new stdclass();
$lang->bi = new stdclass();
$lang->screen = new stdclass();
$lang->report = new stdclass();
$lang->pivot = new stdclass();
$lang->chart = new stdclass();
$lang->report = new stdclass();
$lang->repo = new stdclass();
$lang->jenkins = new stdclass();
$lang->gitlab = new stdclass();
+3 -2
View File
@@ -176,10 +176,11 @@ $lang->devops->common = 'DevOps';
$lang->doc->common = 'Doc';
$lang->repo->common = 'Code';
$lang->repo->codeRepo = 'Code Repo';
$lang->bi->common = 'BI';
$lang->screen->common = 'Screen';
$lang->report->common = 'BI';
$lang->pivot->common = 'Pivot Table';
$lang->chart->common = 'Chart';
$lang->report->common = 'Report';
$lang->system->common = 'System';
$lang->admin->common = 'Admin';
$lang->story->common = 'Story';
@@ -288,7 +289,7 @@ $lang->doc->project = $lang->projectCommon;
$lang->doc->api = 'API';
$lang->doc->execution = $lang->execution->common;
$lang->doc->custom = 'Custom';
$lang->doc->wiki = 'WIKI';
$lang->doc->wiki = 'Wiki';
$lang->doc->apiDoc = 'API Docuemnt';
$lang->doc->apiStruct = 'Data Structure';
$lang->doc->mySpace = 'My Space';
+3 -2
View File
@@ -176,10 +176,11 @@ $lang->devops->common = 'DevOps';
$lang->doc->common = 'Doc';
$lang->repo->common = 'Code';
$lang->repo->codeRepo = 'Code Repo';
$lang->bi->common = 'BI';
$lang->screen->common = 'Screen';
$lang->report->common = 'BI';
$lang->pivot->common = 'Pivot Table';
$lang->chart->common = 'Chart';
$lang->report->common = 'Report';
$lang->system->common = 'System';
$lang->admin->common = 'Admin';
$lang->story->common = 'Story';
@@ -288,7 +289,7 @@ $lang->doc->project = $lang->projectCommon;
$lang->doc->api = 'API';
$lang->doc->execution = $lang->execution->common;
$lang->doc->custom = 'Custom';
$lang->doc->wiki = 'WIKI';
$lang->doc->wiki = 'Wiki';
$lang->doc->apiDoc = 'API Docuemnt';
$lang->doc->apiStruct = 'Data Structure';
$lang->doc->mySpace = 'My Space';
+3 -2
View File
@@ -176,10 +176,11 @@ $lang->devops->common = 'DevOps';
$lang->doc->common = 'Doc';
$lang->repo->common = 'Code';
$lang->repo->codeRepo = 'Code Repo';
$lang->bi->common = 'BI';
$lang->screen->common = 'Screen';
$lang->report->common = 'BI';
$lang->pivot->common = 'Pivot Table';
$lang->chart->common = 'Chart';
$lang->report->common = 'Report';
$lang->system->common = 'System';
$lang->admin->common = 'Admin';
$lang->story->common = 'Story';
@@ -288,7 +289,7 @@ $lang->doc->project = $lang->projectCommon;
$lang->doc->api = 'API';
$lang->doc->execution = $lang->execution->common;
$lang->doc->custom = 'Custom';
$lang->doc->wiki = 'WIKI';
$lang->doc->wiki = 'Wiki';
$lang->doc->apiDoc = 'API Docuemnt';
$lang->doc->apiStruct = 'Data Structure';
$lang->doc->mySpace = 'My Space';
+19 -18
View File
@@ -9,7 +9,7 @@ $lang->navIcons['qa'] = "<i class='icon icon-test'></i>";
$lang->navIcons['devops'] = "<i class='icon icon-devops'></i>";
$lang->navIcons['kanban'] = "<i class='icon icon-kanban'></i>";
$lang->navIcons['doc'] = "<i class='icon icon-doc'></i>";
$lang->navIcons['report'] = "<i class='icon icon-statistic'></i>";
$lang->navIcons['bi'] = "<i class='icon icon-statistic'></i>";
$lang->navIcons['system'] = "<i class='icon icon-group'></i>";
$lang->navIcons['admin'] = "<i class='icon icon-cog-outline'></i>";
@@ -42,7 +42,7 @@ $lang->mainNav->qa = "{$lang->navIcons['qa']} {$lang->qa->common}|qa|inde
$lang->mainNav->devops = "{$lang->navIcons['devops']} DevOps|repo|browse|";
$lang->mainNav->kanban = "{$lang->navIcons['kanban']} {$lang->kanban->common}|kanban|space|";
$lang->mainNav->doc = "{$lang->navIcons['doc']} {$lang->doc->common}|doc|index|";
$lang->mainNav->report = "{$lang->navIcons['report']} {$lang->report->common}|screen|browse|";
$lang->mainNav->bi = "{$lang->navIcons['bi']} {$lang->bi->common}|screen|browse|";
$lang->mainNav->system = "{$lang->navIcons['system']} {$lang->system->common}|my|team|";
$lang->mainNav->admin = "{$lang->navIcons['admin']} {$lang->admin->common}|admin|index|";
@@ -57,7 +57,7 @@ $lang->mainNav->menuOrder[30] = 'qa';
$lang->mainNav->menuOrder[35] = 'devops';
$lang->mainNav->menuOrder[40] = 'kanban';
$lang->mainNav->menuOrder[45] = 'doc';
$lang->mainNav->menuOrder[50] = 'report';
$lang->mainNav->menuOrder[50] = 'bi';
$lang->mainNav->menuOrder[55] = 'system';
$lang->mainNav->menuOrder[60] = 'admin';
@@ -340,7 +340,7 @@ $lang->execution->menu->storyGroup = array('link' => "{$lang->common->story}|exe
$lang->execution->menu->story = array('link' => "$lang->SRCommon|execution|story|executionID=%s", 'subModule' => 'story', 'alias' => 'storykanban,linkstory');
$lang->execution->menu->qa = array('link' => "{$lang->qa->common}|execution|bug|executionID=%s", 'subModule' => 'bug,testcase,testtask,testreport', 'alias' => 'qa,bug,testcase,testtask,testreport');
$lang->execution->menu->devops = array('link' => "{$lang->repo->common}|repo|browse|repoID=0&branchID=&objectID=%s", 'subModule' => 'repo');
$lang->execution->menu->doc = array('link' => "{$lang->doc->common}|doc|tableContents|type=execution&objectID=%s", 'subModule' => 'doc');
$lang->execution->menu->doc = array('link' => "{$lang->doc->common}|execution|doc|objectID=%s", 'subModule' => 'doc');
$lang->execution->menu->build = array('link' => "{$lang->build->common}|execution|build|executionID=%s", 'subModule' => 'build');
$lang->execution->menu->action = array('link' => "$lang->dynamic|execution|dynamic|executionID=%s");
$lang->execution->menu->settings = array('link' => "$lang->settings|execution|view|executionID=%s", 'subModule' => 'personnel', 'alias' => 'edit,manageproducts,team,whitelist,addwhitelist,managemembers', 'class' => 'dropdown dropdown-hover');
@@ -489,7 +489,7 @@ $lang->devops->menu->set['subMenu']->repo = array('link' => "{$lang->devops
$lang->devops->menu->set['subMenu']->gitlab = array('link' => 'GitLab|gitlab|browse', 'subModule' => 'gitlab');
$lang->devops->menu->set['subMenu']->gogs = array('link' => 'Gogs|gogs|browse', 'subModule' => 'gogs');
$lang->devops->menu->set['subMenu']->gitea = array('link' => 'Gitea|gitea|browse', 'subModule' => 'gitea');
$lang->devops->menu->set['subMenu']->jenkins = array('link' => 'Jenkins|jenkins|browse', 'subModule' => '');
$lang->devops->menu->set['subMenu']->jenkins = array('link' => 'Jenkins|jenkins|browse', 'subModule' => 'jenkins');
$lang->devops->menu->set['subMenu']->sonarqube = array('link' => 'SonarQube|sonarqube|browse', 'subModule' => 'sonarqube');
$lang->devops->menu->set['subMenu']->setrules = array('link' => "{$lang->devops->rules}|repo|setrules");
@@ -503,7 +503,7 @@ $lang->doc->menu->my = array('link' => "{$lang->doc->mySpace}|doc|mySpace
$lang->doc->menu->product = array('link' => "{$lang->doc->productSpace}|doc|productSpace|", 'alias' => 'productspace');
$lang->doc->menu->project = array('link' => "{$lang->doc->projectSpace}|doc|projectSpace|", 'alias' => 'projectspace');
$lang->doc->menu->api = array('link' => "{$lang->doc->apiSpace}|api|index", 'alias' => 'api');
$lang->doc->menu->custom = array('link' => "{$lang->doc->teamSpace}|doc|tableContents|type=custom", 'alias' => 'tablecontents');
$lang->doc->menu->custom = array('link' => "{$lang->doc->teamSpace}|doc|teamSpace|", 'alias' => 'teamspace');
$lang->doc->dividerMenu = ',product,';
@@ -515,16 +515,16 @@ $lang->doc->menuOrder[20] = 'project';
$lang->doc->menuOrder[25] = 'api';
$lang->doc->menuOrder[30] = 'custom';
/* Report menu.*/
$lang->report->menu = new stdclass();
$lang->report->menu->screen = array('link' => "{$lang->screen->common}|screen|browse");
$lang->report->menu->pivot = array('link' => "{$lang->pivot->common}|pivot|preview");
$lang->report->menu->chart = array('link' => "{$lang->chart->common}|chart|preview");
/* BI menu.*/
$lang->bi->menu = new stdclass();
$lang->bi->menu->screen = array('link' => "{$lang->screen->common}|screen|browse");
$lang->bi->menu->pivot = array('link' => "{$lang->pivot->common}|pivot|preview");
$lang->bi->menu->chart = array('link' => "{$lang->chart->common}|chart|preview");
/* Report menu order. */
$lang->report->menuOrder[5] = 'screen';
$lang->report->menuOrder[10] = 'pivot';
$lang->report->menuOrder[15] = 'chart';
/* BI menu order. */
$lang->bi->menuOrder[5] = 'screen';
$lang->bi->menuOrder[10] = 'pivot';
$lang->bi->menuOrder[15] = 'chart';
/* Company menu.*/
$lang->company->menu = new stdclass();
@@ -611,9 +611,10 @@ $lang->navGroup->doc = 'doc';
$lang->navGroup->doclib = 'doc';
$lang->navGroup->api = 'doc';
$lang->navGroup->screen = 'report';
$lang->navGroup->pivot = 'report';
$lang->navGroup->chart = 'report';
$lang->navGroup->screen = 'bi';
$lang->navGroup->pivot = 'bi';
$lang->navGroup->chart = 'bi';
$lang->navGroup->report = 'bi';
$lang->navGroup->qa = 'qa';
$lang->navGroup->bug = 'qa';
+3 -2
View File
@@ -176,10 +176,11 @@ $lang->devops->common = 'DevOps';
$lang->doc->common = '文档';
$lang->repo->common = '代码';
$lang->repo->codeRepo = '代码库';
$lang->bi->common = 'BI';
$lang->screen->common = '大屏';
$lang->report->common = 'BI';
$lang->pivot->common = '透视表';
$lang->chart->common = '图表';
$lang->report->common = '统计';
$lang->system->common = '组织';
$lang->admin->common = '后台';
$lang->story->common = $lang->SRCommon;
@@ -288,7 +289,7 @@ $lang->doc->project = $lang->projectCommon . '库';
$lang->doc->api = '接口库';
$lang->doc->execution = "{$lang->execution->common}库";
$lang->doc->custom = '自定义库';
$lang->doc->wiki = 'WIKI';
$lang->doc->wiki = 'Wiki';
$lang->doc->apiDoc = '文档';
$lang->doc->apiStruct = '数据结构';
$lang->doc->mySpace = '我的空间';
+1 -1
View File
@@ -153,7 +153,7 @@ $lang->devops->common = 'DevOps';
$lang->doc->common = '文檔';
$lang->repo->common = '代碼';
$lang->repo->codeRepo = '代碼庫';
$lang->report->common = 'BI';
$lang->report->common = '统计';
$lang->system->common = '組織';
$lang->admin->common = '後台';
$lang->task->common = '任務';
-1
View File
@@ -605,7 +605,6 @@ class commonModel extends model
if(strpos('|bug|execution|kanbanspace|', "|$objectType|") !== false) $needPrintDivider = true;
$hasPriv = common::hasPriv($module, $createMethod);
if($hasPriv and $objectType == 'doc' and !common::hasPriv('doc', 'tableContents')) $hasPriv = false;
if(!$hasPriv and $objectType == 'doc' and common::hasPriv('api', 'create')) $hasPriv = true;
if(!$hasPriv) continue;
+5
View File
@@ -0,0 +1,5 @@
<?php
css::import($jsRoot . 'mindmap/css/zui.mindmap.css');
js::import($jsRoot . 'mindmap/js/hotkey.min.js');
js::import($jsRoot . 'mindmap/js/zui.mindmap.js?v=2');
?>
+11 -1
View File
@@ -75,7 +75,17 @@ class datatableModel extends model
$module = zget($this->config->datatable->moduleAlias, "$module-$method", $module);
if(!isset($this->config->$module)) $this->loadModel($module);
if(isset($this->config->datatable->$datatableId->$key)) $setting = json_decode($this->config->datatable->$datatableId->$key);
if(isset($this->config->datatable->$datatableId->$key))
{
if($datatableId == 'testcaseBrowse' && $key == 'tablecols' && $this->cookie->onlyScene)
{
$setting = json_decode('[{"id":"id","order":1,"show":true,"width":"70px","fixed":"left"},{"id":"title","order":2,"show":true,"width":"auto","fixed":"left"},{"id":"openedBy","order":8,"show":true,"width":"80px","fixed":"no"},{"id":"openedDate","order":9,"show":true,"width":"90px","fixed":"no"},{"id":"lastEditedBy","order":16,"show":true,"width":"80px","fixed":"no"},{"id":"lastEditedDate","order":17,"show":true,"width":"90px","fixed":"no"},{"id":"actions","order":23,"show":true,"width":"150px","fixed":"right"}]');
}
else
{
$setting = json_decode($this->config->datatable->$datatableId->$key);
}
}
$fieldList = $this->getFieldList($module);
if(empty($setting))
+6 -1
View File
@@ -34,6 +34,8 @@ $config->doc->markdown->create = array('id' => 'contentMarkdown', 'tools' => 'wi
$config->doc->iconList['html'] = 'rich-text';
$config->doc->iconList['markdown'] = 'markdown';
$config->doc->iconList['url'] = 'text-link';
$config->doc->iconList['text'] = 'wiki-file';
$config->doc->iconList['template'] = 'wiki-file';
$config->doc->iconList['word'] = 'word';
$config->doc->iconList['ppt'] = 'ppt';
$config->doc->iconList['excel'] = 'excel';
@@ -45,10 +47,13 @@ $config->doc->objectIconList['mine'] = 'icon-contacts';
$config->doc->objectIconList['custom'] = 'icon-groups';
$config->doc->spaceMethod['mine'] = 'myspace';
$config->doc->spaceMethod['view'] = 'myspace';
$config->doc->spaceMethod['collect'] = 'myspace';
$config->doc->spaceMethod['createdby'] = 'myspace';
$config->doc->spaceMethod['product'] = 'productspace';
$config->doc->spaceMethod['project'] = 'projectspace';
$config->doc->spaceMethod['execution'] = 'projectspace';
$config->doc->spaceMethod['custom'] = 'tablecontents';
$config->doc->spaceMethod['custom'] = 'teamspace';
$config->doc->search['module'] = 'doc';
$config->doc->search['fields']['title'] = $lang->doc->title;
+104 -57
View File
@@ -63,6 +63,7 @@ class doc extends control
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';
if(empty($orderBy) and ($type == 'editedby')) $orderBy = 'status,editedDate_desc';
/* Save session, load module. */
$uri = $this->app->getURI(true);
@@ -70,16 +71,25 @@ class doc extends control
$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');
if($moduleID) $libID = $this->tree->getById($moduleID)->root;
list($libs, $libID, $object, $objectID, $objectDropdown) = $this->doc->setMenuByType('mine', 0, $libID);
if($type != 'mine')
{
$objectTitle = '';
if($type == 'view') $objectTitle = $this->lang->doc->myView;
if($type == 'collect') $objectTitle = $this->lang->doc->myCollection;
if($type == 'createdby') $objectTitle = $this->lang->doc->myCreation;
if($type == 'editedby') $objectTitle = $this->lang->doc->myEdited;
if($objectTitle) $objectDropdown = "<div id='sidebarHeader'><div class='title' title='{$objectTitle}'>{$objectTitle}</div></div>";
}
/* Build the search form. */
$queryID = $browseType == 'bysearch' ? (int)$param : 0;
$params = "libID=$libID&moduleID=$moduleID&browseType=bySearch&param=myQueryID&orderBy=$orderBy";
if($this->app->rawMethod == 'myspace') $params = "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);
@@ -102,26 +112,27 @@ class doc extends control
$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')
elseif($type == 'view' or $type == 'collect' or $type == 'createdby' or $type == 'editedby')
{
$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');
$this->view->orderBy = $orderBy;
$this->view->browseType = $browseType;
$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, 0, $browseType);
$this->view->pager = $pager;
$this->view->type = $type;
$this->view->objectID = 0;
$this->view->canExport = ($this->config->edition != 'open' and common::hasPriv('doc', 'mine2export') and $type == 'mine');
$this->view->libType = 'lib';
$this->view->title = $this->lang->doc->common;
$this->view->moduleID = $moduleID;
$this->view->docs = $docs;
$this->view->users = $this->user->getPairs('noletter');
$this->view->orderBy = $orderBy;
$this->view->browseType = $browseType;
$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, 0, $browseType);
$this->view->pager = $pager;
$this->view->type = $type;
$this->view->objectID = 0;
$this->view->canExport = ($this->config->edition != 'open' and common::hasPriv('doc', 'mine2export') and $type == 'mine');
$this->view->libType = 'lib';
$this->view->objectDropdown = $objectDropdown;
$this->display();
}
@@ -386,7 +397,6 @@ class doc extends control
$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);
$params = "docID=" . $docResult['id'];
$link = isonlybody() ? 'parent' : $this->createLink('doc', 'view', $params);
$response = array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $link);
@@ -412,14 +422,15 @@ class doc extends control
{
$excludedModel = $this->config->vision == 'lite' ? '' : 'kanban';
$objects = $this->project->getPairsByProgram('', 'all', false, 'order_asc', $excludedModel);
$this->view->executions = array();
if($lib->type == 'execution')
{
$execution = $this->loadModel('execution')->getById($lib->execution);
$objectID = $execution->project;
$libs = $this->doc->getLibs('execution', $extra = "withObject,$unclosed", $libID, $lib->execution);
$this->view->execution = $execution;
$this->view->execution = $execution;
$this->view->executions = array(0 => '') + $this->execution->getPairs($objectID, 'sprint,stage', 'multiple,leaf,noprefix');
}
$this->view->executions = array(0 => '') + $this->loadModel('execution')->getPairs($objectID, 'sprint,stage', 'multiple,leaf,noprefix');
}
elseif($linkType == 'execution')
{
@@ -539,16 +550,25 @@ class doc extends control
if(!empty($changes)) $this->action->logHistory($actionID, $changes);
}
$link = $this->session->docList ? $this->session->docList : $this->createLink('doc', 'index');
$link = $this->createLink('doc', 'view', "docID={$docID}") . "#app={$this->app->tab}";
$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')
if(!$this->doc->checkPrivDoc($doc))
{
$link = $this->createLink('doc', 'view', "docID=$docID") . "#app={$this->app->tab}";
$moduleName = 'doc';
if($this->app->tab == 'execution')
{
$moduleName = 'execution';
$methodName = 'doc';
}
else
{
$methodName = zget($this->config->doc->spaceMethod, $lib->type);
}
$params = "objectID=$objectID&libID={$doc->lib}";
$link = $this->createLink($moduleName, $methodName, $params);
}
if(isonlybody()) return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent'));
@@ -654,7 +674,7 @@ class doc extends control
if($from == 'lib')
{
$method = 'tableContents';
$method = 'teamSpace';
$objectID = 0;
if($objectType == 'product')
{
@@ -671,7 +691,6 @@ class doc extends control
$objectID = $doc->execution;
}
$params = "objectID={$objectID}&libID={$doc->lib}";
if($method == 'tableContents') $params = "type=$objectType&" . $params;
$response['locate'] = $this->createLink('doc', $method, $params);
}
}
@@ -1102,6 +1121,14 @@ class doc extends control
public function view($docID = 0, $version = 0, $appendLib = 0)
{
$doc = $this->doc->getById($docID);
if(!$this->doc->checkPrivDoc($doc))
{
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')));
helper::end(print(js::locate('back')));
}
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'));
@@ -1197,28 +1224,21 @@ class doc extends control
$doc = $docID ? $doc : '';
/* Crumbs links array. */
$methodName = in_array($type, array('product', 'project')) ? $objectType . 'Space' : 'tableContents';
$moduleName = 'doc';
$methodName = in_array($type, array('product', 'project')) ? $objectType . 'Space' : 'teamSpace';
$linkParams = "objectID={$objectID}&libID={$lib->id}";
if($this->app->tab == 'execution' or $objectType == 'custom')
if($this->app->tab == 'execution')
{
$linkParams = "objectType=$objectType&$linkParams";
$methodName = 'tableContents';
$moduleName = 'execution';
$methodName = 'doc';
$linkParams = "executionID=$objectID";
}
if($type == 'mine')
elseif($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;
@@ -1229,7 +1249,6 @@ class doc extends control
$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.
@@ -1264,11 +1283,14 @@ class doc extends control
*/
public function tableContents($type = 'custom', $objectID = 0, $libID = 0, $moduleID = 0, $browseType = 'all', $orderBy = 'status,id_desc', $param = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
$isFirstLoad = $libID == 0 ? true : false;
$this->session->set('createProjectLocate', $this->app->getURI(true), 'doc');
$this->session->set('structList', $this->app->getURI(true), 'doc');
$uri = $this->app->getURI(true);
$this->session->set('createProjectLocate', $uri, 'doc');
$this->session->set('structList', $uri, 'doc');
$this->session->set('spaceType', $type, 'doc');
$this->session->set('docList', $uri, 'doc');
if($moduleID) $libID = $this->tree->getById($moduleID)->root;
$isFirstLoad = $libID == 0 ? true : false;
if(empty($browseType)) $browseType = 'all';
list($libs, $libID, $object, $objectID, $objectDropdown) = $this->doc->setMenuByType($type, $objectID, $libID);
@@ -1281,7 +1303,7 @@ class doc extends control
$queryID = $browseType == 'bySearch' ? (int)$param : 0;
$params = "objectID=$objectID&libID=$libID&moduleID=0&browseType=bySearch&orderBy=$orderBy&param=myQueryID";
if($this->app->rawMethod == 'tablecontents') $params = "type=$type&" . $params;
$actionURL = $this->createLink('doc', $this->app->rawMethod, $params);
$actionURL = $this->createLink($this->app->rawModule, $this->app->rawMethod, $params);
if($libType == 'api')
{
$this->loadModel('api')->buildSearchForm($lib, $queryID, $actionURL, $libs, $type);
@@ -1298,7 +1320,7 @@ class doc extends control
if($libType == 'api')
{
$this->loadModel('api');
$this->session->set('objectName', $this->lang->doc->api, 'admin');
$this->session->set('objectName', $this->lang->doc->api, 'doc');
$this->view->libs = $libs;
$this->view->apiID = 0;
@@ -1307,8 +1329,7 @@ class doc extends control
}
else
{
if(in_array($type, array('product', 'project'))) $this->session->set('objectName', $this->lang->doc->common, 'admin');
if($this->config->vision == 'lite' or in_array($type, array('execution', 'custom'))) $this->session->set('objectName', '', 'admin');
if(in_array($type, array('product', 'project'))) $this->session->set('objectName', $this->lang->doc->common, 'doc');
$this->view->docs = $browseType == 'bySearch' ? $this->doc->getDocsBySearch($type, $objectID, $libID, $queryID, $orderBy, $pager) : $this->doc->getDocs($libID, $moduleID, $browseType, $orderBy, $pager);
}
@@ -1360,6 +1381,9 @@ class doc extends control
*/
public function productSpace($objectID = 0, $libID = 0, $moduleID = 0, $browseType = 'all', $orderBy = 'status,id_desc', $param = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
$products = $this->product->getPairs('nocode', 0, '', 'all');
$objectID = $this->product->saveState($objectID, $products);
echo $this->fetch('doc', 'tableContents', "type=product&objectID=$objectID&libID=$libID&moduleID=$moduleID&browseType=$browseType&orderBy=$orderBy&param=$param&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID");
}
@@ -1380,9 +1404,32 @@ class doc extends control
*/
public function projectSpace($objectID = 0, $libID = 0, $moduleID = 0, $browseType = 'all', $orderBy = 'status,id_desc', $param = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
$projects = $this->project->getPairsByProgram();
$objectID = $this->project->saveState($objectID, $projects);
echo $this->fetch('doc', 'tableContents', "type=project&objectID=$objectID&libID=$libID&moduleID=$moduleID&browseType=$browseType&orderBy=$orderBy&param=$param&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID");
}
/**
* Show team space.
*
* @param int $objectID
* @param int $libID
* @param int $moduleID
* @param string $browseType all|draft|bysearch
* @param string $orderBy
* @param int $param
* @param int $recTotal
* @param int $recPerPage
* @param int $pageID
* @access public
* @return void
*/
public function teamSpace($objectID = 0, $libID = 0, $moduleID = 0, $browseType = 'all', $orderBy = 'status,id_desc', $param = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
echo $this->fetch('doc', 'tableContents', "type=custom&objectID=$objectID&libID=$libID&moduleID=$moduleID&browseType=$browseType&orderBy=$orderBy&param=$param&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID");
}
/**
* Select lib type.
*
@@ -1411,13 +1458,13 @@ class doc extends control
$spaceList = $this->lang->doc->spaceList;
$typeList = $this->lang->doc->types;
if(!common::hasPriv('doc', 'create')) unset($spaceList['mine'], $spaceList['custom'], $typeList['doc']);
if(!common::hasPriv('doc', 'mySpace')) unset($spaceList['mine']);
if(!common::hasPriv('doc', 'productSpace')) unset($spaceList['product']);
if(!common::hasPriv('doc', 'projectSpace')) unset($spaceList['project']);
if(!common::hasPriv('doc', 'tableContents')) unset($spaceList['custom']);
if(!common::hasPriv('api', 'index')) unset($spaceList['api']);
if(!common::hasPriv('api', 'create')) unset($spaceList['api'], $typeList['api']);
if(!common::hasPriv('doc', 'create')) unset($spaceList['mine'], $spaceList['custom'], $typeList['doc']);
if(!common::hasPriv('doc', 'mySpace')) unset($spaceList['mine']);
if(!common::hasPriv('doc', 'productSpace')) unset($spaceList['product']);
if(!common::hasPriv('doc', 'projectSpace')) unset($spaceList['project']);
if(!common::hasPriv('doc', 'teamSpace')) unset($spaceList['custom']);
if(!common::hasPriv('api', 'index')) unset($spaceList['api']);
if(!common::hasPriv('api', 'create')) unset($spaceList['api'], $typeList['api']);
$products = $this->loadModel('product')->getPairs();
$projects = $this->project->getPairsByProgram('', 'all', false, 'order_asc', 'kanban');
+8 -2
View File
@@ -90,7 +90,9 @@ ol, ul {margin-bottom: 0}
.tree li > a {white-space: nowrap; text-overflow: ellipsis; overflow: hidden;}
.side-col .menu-actions {position: absolute; top: 0; right: 0; padding: 7px 8px;}
.menu-actions i {font-size: 15px; color: #8c8c8c;}
#whiteListBox .input-group:last-child {margin-top: 10px;}
#whiteListBox .chosen-container .chosen-results {max-height: 180px;}
#whiteListBox .chosen-container-active .chosen-single {border-color: #2e7fff !important;}
.c-product, .c-execution, .c-lib {width: 80px !important;}
@@ -104,8 +106,12 @@ 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);}
#content .detail-content.article-content {overflow-y: auto; height: calc(100vh - 200px); padding-right: 20px;}
#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;}
#outlineMenu {background: #fff; position: absolute; height: calc(100vh - 180px)!important; overflow-y: auto; top: 50px; right: 25px;}
.pl-0px {padding-left:0px !important;}
.icon {cursor: pointer;}
#mainMenu .pull-right .createDropdown li > a .file-icon {margin-bottom: 1px;}
#queryBox .btn-save-form, #queryBox #toggle-queries{display: none;}
-3
View File
@@ -1,10 +1,8 @@
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;}
.doc-title input::-webkit-input-placeholder {color: #D8DBDE;}
.doc-title.required:after {top: 4px; right: 0; left: 12px; display: inline-table;}
#savePath {display:inline-block; width:320px; overflow:hidden; white-space: nowrap; padding-right:8px; position: relative; top:7px;}
#headerBox {border-bottom: 1px solid #e3e3e3;}
#headerBox td:last-child {padding-right: 24px;}
.contentmarkdown.required:after, .contenthtml.required:after {right:3px;}
@@ -39,5 +37,4 @@ body {overflow: hidden;}
.aclBox .radio-inline{display:block; padding-bottom:5px;}
.aclBox .radio-inline+.radio-inline {margin-left: 0px !important;}
#whiteListBox .input-group:last-child {margin-top: 10px;}
.fullscreen-save, .markdown-fullscreen-save {position: fixed; top: 10px; right: 30px; z-index: 999999;}
-2
View File
@@ -1,10 +1,8 @@
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;}
.doc-title input::-webkit-input-placeholder {color: #D8DBDE;}
.doc-title.required:after {top: 4px; right: 0; left: 12px; display: inline-table;}
#savePath {display:inline-block; width:320px; overflow:hidden; white-space: nowrap; height: 19px; padding-top: 4px; padding-right:8px;}
.contenthtml.required:after {right:3px;}
#headerBox {border-bottom: 1px solid #e3e3e3;}
#headerBox td:last-child {padding-right: 24px;}
+1
View File
@@ -1,3 +1,4 @@
#lib_chosen.chosen-container .chosen-results {max-height: 100px;}
.radio-inline+.radio-inline { margin-top: 0; margin-left: 0px;}
.radio-inline {margin-right: 10px;}
#mainContent{height:310px;}
+1 -1
View File
@@ -49,7 +49,7 @@ 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 .c-name > .ajaxCollect {float: right; position: relative; right: 10px; top: 0px; padding: 0 6px;}
table.table > thead > tr {height: 32px;}
#bysearchTab::before {display: none;}
+19 -11
View File
@@ -1,8 +1,8 @@
.h-full-adjust {overflow-y: auto; height: calc(100vh - 120px);}
.h-full-adjust {overflow-y: auto; height: calc(100vh - 125px);}
.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: 10px;}
.main-col .doc-title .title {margin-right: 10px; line-height: 32px; font-size: 25px;}
.main-col .doc-title .title {margin-right: 10px; line-height: 32px; font-size: 20px;}
.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;}
@@ -21,22 +21,26 @@
.main-col iframe {min-height: 380px;}
.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 .user-time{margin-right: 4px}
.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;}
.article-content img {margin: 0;}
.article-content.comment .comment-content {width: 94%;}
#outlineMenu {max-width: 200px;}
#outlineMenu .tree li > a {text-overflow: clip;}
.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-toggle {position: absolute; right: 55px; top: 50px;}
.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-content li.text-ellipsis.active>a {font-weight: 700;}
#outline li.has-list.open:before {content: unset;}
#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;}
.flex {display: flex;}
@@ -61,12 +65,16 @@
#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%;}
.detail+.detail {padding-top: 0;}
.comment-edit-form .form-actions {display: flex;}
#content .detail-content.article-content::-webkit-scrollbar,
#outlineMenu::-webkit-scrollbar,
#history::-webkit-scrollbar {height: 0px; width: 0px; background: transparent;}
#content .detail-content.article-content::-moz-scrollbar,
#outlineMenu::-moz-scrollbar,
#hostory::-moz-scrollbar {height: 0px; width: 0px; background: transparent;}
.main-col iframe {min-height: unset;}
+8 -75
View File
@@ -29,7 +29,12 @@ function loadObjectModules(objectType, objectID, docType)
function loadExecutions(projectID)
{
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()});
$('#executionBox').load(link, function()
{
var $extension = $('#executionBox').find('select');
$extension.attr('onchange', "loadObjectModules('execution', this.value)").picker();
if($extension.hasClass('disabled')) $('#executionBox').find('.picker').addClass('disabled');
});
loadObjectModules('project', projectID);
}
@@ -280,7 +285,6 @@ $(document).ready(function()
$(function()
{
$('.split-row').splitRow();
updateCrumbs();
});
var $pageSetting = $('#pageSetting');
@@ -327,12 +331,11 @@ $(document).ready(function()
*/
function locateNewLib(type, objectID, libID)
{
var method = 'tableContents';
var params = 'type=' + type + '&objectID=' + objectID + '&libID=' + libID;
var method = 'teamSpace';
var params = 'objectID=' + objectID + '&libID=' + libID;
if(type == 'product' || type == 'project')
{
method = type + 'Space';
params = 'objectID=' + objectID + '&libID=' + libID;
}
else if(type == 'mine')
{
@@ -343,47 +346,6 @@ function locateNewLib(type, objectID, libID)
location.href = createLink('doc', method, params);
}
/**
* Set save path.
*
* @access public
* @return void
*/
function setSavePath()
{
var getSubPath = function($obj)
{
var $td = $obj.parent();
var usePicker = $td.find('.picker').length == 1;
var subPath = $obj.find('option:checked').text();
if(usePicker) subPath = $td.find('.picker .picker-selection-text').text();
return subPath;
}
savePath = defaultSave;
if($('#modalBasicInfo #product').length == 1)
{
savePath += getSubPath($('#modalBasicInfo #product')) + '/';
}
else if($('#modalBasicInfo #project').length == 1 && $('#modalBasicInfo #execution').length == 0)
{
savePath += getSubPath($('#modalBasicInfo #project')) + '/';
}
else if($('#modalBasicInfo #project').length == 1 && $('#modalBasicInfo #execution').length == 1)
{
var executionID = $('#modalBasicInfo #execution').val();
if(executionID == '0' || executionID == '') savePath += getSubPath($('#modalBasicInfo #project')) + '/';
if(executionID != '0' && executionID != '') savePath += getSubPath($('#modalBasicInfo #execution')) + '/';
}
else if($('#modalBasicInfo #execution').length == 1)
{
savePath += getSubPath($('#modalBasicInfo #execution')) + '/';
}
savePath += getSubPath($('#modalBasicInfo #module'));
$('#savePath').html(savePath).attr('title', savePath);
}
/**
* Submit form.
*
@@ -398,32 +360,3 @@ function submit(object)
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);
}
+1 -2
View File
@@ -6,7 +6,7 @@ $(function()
setTimeout(function(){$('.CodeMirror').height($(document).height() - 112);}, 100);
$('iframe.ke-edit-iframe').contents().find('.article-content').css('padding', '20px 20px 0 20px');
setSavePath();
if(objectType == 'project') loadExecutions($('#project').val());
/* Change for show create error. */
$('#contentBox #content').attr('id', 'contentHTML');
@@ -15,7 +15,6 @@ $(function()
{
$('#modalBasicInfo #copyTitle').html($('.doc-title #editorTitle').val().replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;"));
});
$('#modalBasicInfo').on('hide.zui.modal', function(){setSavePath();});
$('#saveDraft').click(function()
{
-3
View File
@@ -6,9 +6,6 @@ $(function()
setTimeout(function(){$('.CodeMirror').height($(document).height() - 112);}, 100);
$('iframe.ke-edit-iframe').contents().find('.article-content').css('padding', '20px 20px 0 20px');
setSavePath();
$('#modalBasicInfo').on('hide.zui.modal', function(){setSavePath();});
$('#saveDraft').click(function()
{
if($('#editorTitle').val() == '')
+8 -11
View File
@@ -9,20 +9,17 @@
*/
function redirectParentWindow(objectType, libID, moduleID, docType)
{
config.onlybody = 'no';
var link = '';
if(docType == 'api')
{
parent.$.closeModal(function()
{
new parent.$.zui.ModalTrigger({
iframe : createLink('api', 'create', 'libID=' + libID + '&moduleID=' + moduleID),
width: '85%'
}).show();
});
return false;
link = createLink('api', 'create', 'libID=' + libID + '&moduleID=' + moduleID);
}
else
{
link = createLink('doc', 'create', 'objectType=' + objectType + '&objectID=0&libID=' + libID + '&moduleID=' + moduleID + '&docType=' + docType) + '#app=doc';
}
config.onlybody = 'no';
var link = createLink('doc', 'create', 'objectType=' + objectType + '&objectID=0&libID=' + libID + '&moduleID=' + moduleID + '&docType=' + docType) + '#app=doc';
window.parent.$.apps.open(link);
}
+22 -17
View File
@@ -8,6 +8,12 @@ $(function()
})
$('.menu-actions > a').blur(function() {$(this).css('background', 'none');})
$('.comment-edit-form').ajaxForm({
success: function(data) {
location.reload();
}
})
})
/**
@@ -141,25 +147,30 @@ $(function()
$('.outline').height($('.article-content').height());
$('body').on('click', '.outline-toggle i.icon-angle-right', function()
$('body').on('click', '.outline-toggle i.icon-menu-arrow-left', function()
{
$('.outline').css({'min-width' : '180px', 'border-left' : '2px solid #efefef'});
$(this).removeClass('icon-angle-right').addClass('icon-angle-left').css('left', '-9px');
$(this).removeClass('icon-menu-arrow-left').addClass('icon-menu-arrow-right').css('left', '-9px');
$('.outline').removeClass('hidden');
$('.outline-content').show();
if($('#sidebar>.cell').is(':visible')) $('#sidebar .icon.icon-angle-right').trigger("click");
}).on('click', '.outline-toggle i.icon-angle-left', function()
if($('#sidebar>.cell').is(':visible')) $('#sidebar .icon.icon-menu-arrow-right').trigger("click");
}).on('click', '.outline-toggle i.icon-menu-arrow-right', function()
{
$(this).removeClass('icon-angle-left').addClass('icon-angle-right');
$(this).removeClass('icon-menu-arrow-right').addClass('icon-menu-arrow-left');
$('.outline').css({'min-width' : '180px', 'border-left' : 'none'});
$('.outline-content').hide();
$('.outline').addClass('hidden');
}).on('click', '#outline li', function(e)
{
$('#outline li.active').removeClass('active');
$(e.target).closest('li').addClass('active');
}).on('click', '.comment-edit-form .btn-hide-form', function()
{
$('.comment-edit-form #submit').attr('disabled', false);
});
$('#outline li.has-list').addClass('open in');
$('#outline li.has-list>i+ul').prev('i').remove();
$('.outline-toggle i.icon-menu-arrow-left').trigger('click');
$(document).on('click', '.detail-content a', function(event)
{
@@ -190,15 +201,7 @@ $(function()
});
})
$('#sidebar .icon.icon-angle-right').click(function()
{
if($('#sidebar>.cell').is(':hidden') && $('.outline-content').is(':visible'))
{
$('.outline .outline-toggle i.icon-angle-left').trigger("click");
}
})
$('.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()
{
@@ -207,13 +210,11 @@ $(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');
}
})
@@ -222,8 +223,12 @@ $(function()
$('#closeBtn').on('click', function()
{
$('#history').addClass('hidden');
$('#outlineMenu').removeClass('hidden');
$('#hisTrigger').removeClass('text-primary');
})
$('#history').find('.btn.pull-right').removeClass('pull-right');
if($('.files-list').length)
{
$('#content .detail-content.article-content').css('height', 'calc(100vh - 300px)');
}
$('.outline .outline-toggle i.icon-menu-arrow-left').trigger("click");
})
+6 -6
View File
@@ -25,7 +25,7 @@ $lang->doclib->privateACL = "Private <span class='acl-tip'>(Only creators and wh
$lang->doclib->tip = new stdclass();
$lang->doclib->tip->selectExecution = "When execution is empty, the library created is the {$lang->projectCommon} library";
$lang->doclib->type['wiki'] = 'WIKI';
$lang->doclib->type['wiki'] = 'Wiki';
$lang->doclib->type['api'] = 'API';
$lang->doclib->aclListA = array();
@@ -121,10 +121,10 @@ $lang->doc->update = 'Update';
$lang->doc->nextStep = 'Next';
$lang->doc->closed = 'Closed';
$lang->doc->saveDraft = 'Save Draft';
$lang->doc->defaultSave = 'Default Save: ';
$lang->doc->position = 'Position';
$lang->doc->person = 'Person';
$lang->doc->team = 'Team';
$lang->doc->manage = 'Document Management';
$lang->doc->moduleDoc = 'Nach Modulen';
$lang->doc->searchDoc = 'Suche';
@@ -141,6 +141,7 @@ $lang->doc->myDoc = 'Meine Dokumente';
$lang->doc->myView = 'Recently Viewed';
$lang->doc->myCollection = 'Meine Favoriten';
$lang->doc->myCreation = 'Created By';
$lang->doc->myEdited = 'Edited By';
$lang->doc->myLib = 'My Library';
$lang->doc->tableContents = 'Catalog';
$lang->doc->addCatalog = 'Add Catalog';
@@ -252,13 +253,12 @@ $lang->doc->typeList['word'] = 'Word';
$lang->doc->typeList['ppt'] = 'PPT';
$lang->doc->typeList['excel'] = 'Excel';
$lang->doc->createList['html'] = 'Create Document';
$lang->doc->createList['template'] = 'Create By Template';
$lang->doc->createList['template'] = 'Wiki';
$lang->doc->createList['word'] = 'Word';
$lang->doc->createList['ppt'] = 'PPT';
$lang->doc->createList['excel'] = 'Excel';
$lang->doc->types['doc'] = 'WIKI';
$lang->doc->types['doc'] = 'Wiki';
$lang->doc->types['api'] = 'API';
$lang->doc->contentTypeList['html'] = 'HTML';
@@ -307,7 +307,7 @@ $lang->doc->versionNotFount = 'Existiert nicht in diesem Build.';
$lang->doc->noDoc = 'Keine Dokumente. ';
$lang->doc->noArticle = 'No articles.';
$lang->doc->noLib = 'No libraries.';
$lang->doc->noBook = 'The WIKI library has not created a manual, please create a new one :)';
$lang->doc->noBook = 'The Wiki library has not created a manual, please create a new one :)';
$lang->doc->cannotCreateOffice = 'Sorry, %s file can only be created in ZenTao Biz Series or above. Contact Philip@easysoft.ltd to know more about ZenTao Biz Series and ZenTao Max Series.';
$lang->doc->notSetOffice = "<p>To create a %s document, you need to configure <a href='%s' target='_parent'>office convert</a>.<p>";
$lang->doc->noSearchedDoc = 'Nichts gesucht.';
+6 -6
View File
@@ -25,7 +25,7 @@ $lang->doclib->privateACL = "Private <span class='acl-tip'>(Only creators and wh
$lang->doclib->tip = new stdclass();
$lang->doclib->tip->selectExecution = "When execution is empty, the library created is the {$lang->projectCommon} library";
$lang->doclib->type['wiki'] = 'WIKI';
$lang->doclib->type['wiki'] = 'Wiki';
$lang->doclib->type['api'] = 'API';
$lang->doclib->aclListA = array();
@@ -121,10 +121,10 @@ $lang->doc->update = 'Update';
$lang->doc->nextStep = 'Next';
$lang->doc->closed = 'Closed';
$lang->doc->saveDraft = 'Save Draft';
$lang->doc->defaultSave = 'Default Save: ';
$lang->doc->position = 'Position';
$lang->doc->person = 'Person';
$lang->doc->team = 'Team';
$lang->doc->manage = 'Document Management';
$lang->doc->moduleDoc = 'By Module';
$lang->doc->searchDoc = 'Search';
@@ -141,6 +141,7 @@ $lang->doc->myDoc = 'My Documents';
$lang->doc->myView = 'Recently Viewed';
$lang->doc->myCollection = 'My Favorites';
$lang->doc->myCreation = 'Created By';
$lang->doc->myEdited = 'Edited By';
$lang->doc->myLib = 'My Library';
$lang->doc->tableContents = 'Directory';
$lang->doc->addCatalog = 'Add Catalog';
@@ -252,13 +253,12 @@ $lang->doc->typeList['word'] = 'Word';
$lang->doc->typeList['ppt'] = 'PPT';
$lang->doc->typeList['excel'] = 'Excel';
$lang->doc->createList['html'] = 'Create Document';
$lang->doc->createList['template'] = 'Create By Template';
$lang->doc->createList['template'] = 'Wiki';
$lang->doc->createList['word'] = 'Word';
$lang->doc->createList['ppt'] = 'PPT';
$lang->doc->createList['excel'] = 'Excel';
$lang->doc->types['doc'] = 'WIKI';
$lang->doc->types['doc'] = 'Wiki';
$lang->doc->types['api'] = 'API';
$lang->doc->contentTypeList['html'] = 'HTML';
@@ -307,7 +307,7 @@ $lang->doc->versionNotFount = 'It does not exist in this build.';
$lang->doc->noDoc = 'No documents. ';
$lang->doc->noArticle = 'No articles.';
$lang->doc->noLib = 'No libraries.';
$lang->doc->noBook = 'The WIKI library has not created a manual, please create a new one :)';
$lang->doc->noBook = 'The Wiki library has not created a manual, please create a new one :)';
$lang->doc->cannotCreateOffice = 'Sorry, %s file can only be created in ZenTao Biz Series or above. Contact Philip@easysoft.ltd to know more about ZenTao Biz Series and ZenTao Max Series.';
$lang->doc->notSetOffice = "<p>To create a %s document, you need to configure <a href='%s'>office convert</a>.<p>";
$lang->doc->noSearchedDoc = 'No documents found.';
+6 -6
View File
@@ -25,7 +25,7 @@ $lang->doclib->privateACL = "Private <span class='acl-tip'>(Only creators and wh
$lang->doclib->tip = new stdclass();
$lang->doclib->tip->selectExecution = "When execution is empty, the library created is the {$lang->projectCommon} library";
$lang->doclib->type['wiki'] = 'WIKI';
$lang->doclib->type['wiki'] = 'Wiki';
$lang->doclib->type['api'] = 'API';
$lang->doclib->aclListA = array();
@@ -121,10 +121,10 @@ $lang->doc->update = 'Update';
$lang->doc->nextStep = 'Next';
$lang->doc->closed = 'Closed';
$lang->doc->saveDraft = 'Save Draft';
$lang->doc->defaultSave = 'Default Save: ';
$lang->doc->position = 'Position';
$lang->doc->person = 'Person';
$lang->doc->team = 'Team';
$lang->doc->manage = 'Document Management';
$lang->doc->moduleDoc = 'Par Module';
$lang->doc->searchDoc = 'Rechercher';
@@ -141,6 +141,7 @@ $lang->doc->myDoc = 'Mes Documents';
$lang->doc->myView = 'Recently Viewed';
$lang->doc->myCollection = 'Mes Favoris';
$lang->doc->myCreation = 'Created By';
$lang->doc->myEdited = 'Edited By';
$lang->doc->myLib = 'My Library';
$lang->doc->tableContents = 'Catalog';
$lang->doc->addCatalog = 'Add Catalog';
@@ -252,13 +253,12 @@ $lang->doc->typeList['word'] = 'Word';
$lang->doc->typeList['ppt'] = 'PPT';
$lang->doc->typeList['excel'] = 'Excel';
$lang->doc->createList['html'] = 'Create Document';
$lang->doc->createList['template'] = 'Create By Template';
$lang->doc->createList['template'] = 'Wiki';
$lang->doc->createList['word'] = 'Word';
$lang->doc->createList['ppt'] = 'PPT';
$lang->doc->createList['excel'] = 'Excel';
$lang->doc->types['doc'] = 'WIKI';
$lang->doc->types['doc'] = 'Wiki';
$lang->doc->types['api'] = 'API';
$lang->doc->contentTypeList['html'] = 'HTML';
@@ -307,7 +307,7 @@ $lang->doc->versionNotFount = "N'existe pas dans ce build.";
$lang->doc->noDoc = 'Aucun documents. ';
$lang->doc->noArticle = 'No articles.';
$lang->doc->noLib = 'No libraries.';
$lang->doc->noBook = 'The WIKI library has not created a manual, please create a new one :)';
$lang->doc->noBook = 'The Wiki library has not created a manual, please create a new one :)';
$lang->doc->cannotCreateOffice = 'Désolé, %s peut seulement être créé dans Série ZenTao Biz ou plus. Coordonnées Philip@easysoft.ltd En savoir plus sur les séries zentao biz et zentao Max.';
$lang->doc->notSetOffice = "<p>To create a %s document, you need to configure <a href='%s' target='_parent'>office convert</a>.<p>";
$lang->doc->noSearchedDoc = 'Aucun documents trouvé.';
+7 -7
View File
@@ -25,7 +25,7 @@ $lang->doclib->privateACL = "私有 <span class='acl-tip'>(仅创建者和有%
$lang->doclib->tip = new stdclass();
$lang->doclib->tip->selectExecution = "执行为空时,创建的库为{$lang->projectCommon}库";
$lang->doclib->type['wiki'] = 'WIKI文档库';
$lang->doclib->type['wiki'] = 'Wiki文档库';
$lang->doclib->type['api'] = '接口库';
$lang->doclib->aclListA = array();
@@ -121,10 +121,10 @@ $lang->doc->update = '更新';
$lang->doc->nextStep = '下一步';
$lang->doc->closed = '已关闭';
$lang->doc->saveDraft = '存为草稿';
$lang->doc->defaultSave = '默认存入:';
$lang->doc->position = '所在位置';
$lang->doc->person = '个人';
$lang->doc->team = '团队';
$lang->doc->manage = '文档管理';
$lang->doc->moduleDoc = '按模块浏览';
$lang->doc->searchDoc = '搜索';
@@ -141,6 +141,7 @@ $lang->doc->myDoc = '我的文档';
$lang->doc->myView = '最近浏览';
$lang->doc->myCollection = '我的收藏';
$lang->doc->myCreation = '我创建的';
$lang->doc->myEdited = '我编辑的';
$lang->doc->myLib = '我的个人库';
$lang->doc->tableContents = '目录';
$lang->doc->addCatalog = '添加目录';
@@ -252,13 +253,12 @@ $lang->doc->typeList['word'] = 'Word';
$lang->doc->typeList['ppt'] = 'PPT';
$lang->doc->typeList['excel'] = 'Excel';
$lang->doc->createList['html'] = '创建文档';
$lang->doc->createList['template'] = '由模板创建';
$lang->doc->createList['template'] = 'Wiki文档';
$lang->doc->createList['word'] = 'Word';
$lang->doc->createList['ppt'] = 'PPT';
$lang->doc->createList['excel'] = 'Excel';
$lang->doc->types['doc'] = 'WIKI文档';
$lang->doc->types['doc'] = 'Wiki文档';
$lang->doc->types['api'] = '接口文档';
$lang->doc->contentTypeList['html'] = 'HTML';
@@ -307,7 +307,7 @@ $lang->doc->versionNotFount = '该版本文档不存在';
$lang->doc->noDoc = '暂时没有文档。';
$lang->doc->noArticle = '暂时没有文章。';
$lang->doc->noLib = '暂时没有库。';
$lang->doc->noBook = 'WIKI库还未创建手册,请新建 :)';
$lang->doc->noBook = 'Wiki库还未创建手册,请新建 :)';
$lang->doc->cannotCreateOffice = '<p>对不起,企业版才能创建%s文档。<p><p>试用企业版,请联系我们:4006-8899-23 &nbsp; 0532-86893032。</p>';
$lang->doc->notSetOffice = "创建%s文档,需要配置<a href='%s'>Office转换设置</a>。";
$lang->doc->noSearchedDoc = '没有搜索到任何文档。';
@@ -341,7 +341,7 @@ $lang->doc->noticeAcl['doc']['private'] = '只有创建者自己可以访问。'
$lang->doc->placeholder = new stdclass();
$lang->doc->placeholder->url = '相应的链接地址';
$lang->doc->placeholder->execution = '执行为空时,创建文件在项目库下';
$lang->doc->placeholder->execution = '执行为空时,创建文档在项目库下';
$lang->doc->summary = "本页共 <strong>%s</strong> 个附件,共计 <strong>%s</strong>,其中<strong>%s</strong>。";
$lang->doc->ge = '个';
+102 -95
View File
@@ -54,7 +54,7 @@ class docModel extends model
->andWhere('project')->eq(0)
->andWhere('execution')->eq(0)
->fi()
->orderBy('`order`_asc, id_desc')
->orderBy('order_asc, id_asc')
->fetchAll('id');
$libs = array_filter($libs, array($this, 'checkPrivLib'));
@@ -386,11 +386,6 @@ class docModel extends model
$allLibIDList = array_keys($allLibs);
$hasPrivDocIdList = $this->getPrivDocs(0, $moduleID);
$files = $this->dao->select('*')->from(TABLE_FILE)
->where('objectType')->eq('doc')
->andWhere('objectID')->in($hasPrivDocIdList)
->fetchGroup('objectID');
if($browseType == "all")
{
$docs = $this->getDocs(0, 0, $browseType, $sort, $pager);
@@ -422,13 +417,14 @@ class docModel extends model
->andWhere('actor')->eq($this->app->user->account)
->andWhere('action')->eq('edited')
->fetchAll('objectID');
$docs = $this->dao->select('*')->from(TABLE_DOC)
->where('deleted')->eq(0)
$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($query)
->andWhere('lib')->in($allLibIDList)
->beginIF($this->config->doc->notArticleType)->andWhere('type')->notIN($this->config->doc->notArticleType)->fi()
->andWhere('addedBy', 1)->eq($this->app->user->account)
->orWhere('id')->in(array_keys($docIDList))
->andWhere('t1.lib')->in($allLibIDList)
->beginIF($this->config->doc->notArticleType)->andWhere('t1.type')->notIN($this->config->doc->notArticleType)->fi()
->andWhere('t1.addedBy', 1)->eq($this->app->user->account)
->orWhere('t1.id')->in(array_keys($docIDList))
->markRight(1)
->orderBy($sort)
->page($pager)
@@ -436,12 +432,13 @@ class docModel extends model
}
elseif($browseType == "openedbyme")
{
$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)
$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')->in($allLibIDList)
->andWhere('t1.id')->in($hasPrivDocIdList)
->beginIF($this->config->doc->notArticleType)->andWhere('t1.type')->notIN($this->config->doc->notArticleType)->fi()
->andWhere('t1.addedBy')->eq($this->app->user->account)
->orderBy($sort)
->page($pager)
->fetchAll('id');
@@ -454,11 +451,13 @@ class docModel extends model
->andWhere('objectID')->in($hasPrivDocIdList)
->andWhere('action')->eq('edited')
->fetchAll('objectID');
$docs = $this->dao->select('*')->from(TABLE_DOC)
->where('deleted')->eq(0)
->andWhere('id')->in(array_keys($docIDList))
->andWhere('lib')->in($allLibIDList)
->beginIF($this->config->doc->notArticleType)->andWhere('type')->notIN($this->config->doc->notArticleType)->fi()
$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.id')->in(array_keys($docIDList))
->andWhere('t1.lib')->in($allLibIDList)
->beginIF($this->config->doc->notArticleType)->andWhere('t1.type')->notIN($this->config->doc->notArticleType)->fi()
->orderBy($sort)
->page($pager)
->fetchAll('id');
@@ -490,44 +489,27 @@ class docModel extends model
if(empty($docs)) return array();
/* Get projects, executions and products by docIdList. */
$docContents = $this->dao->select('*')->from(TABLE_DOCCONTENT)->where('doc')->in(array_keys($docs))->orderBy('version,doc')->fetchAll('doc');
foreach($docs as $index => $doc)
if(in_array($browseType, array('bySearch', 'openedbyme', 'editedbyme')))
{
$docs[$index]->fileSize = 0;
if(isset($files[$index]))
$objects = array();
list($objects['project'], $objects['execution'], $objects['product']) = $this->getObjectsByDoc(array_keys($docs));
foreach($docs as $docID => $doc)
{
$docContent = $docContents[$index];
$fileSize = 0;
foreach($files[$index] as $file)
$doc->objectID = zget($doc, $doc->objectType, 0);
$doc->objectName = '';
if(isset($objects[$doc->objectType]))
{
if(strpos(",{$docContent->files},", ",{$file->id},") === false) continue;
$fileSize += $file->size;
}
if($fileSize < 1024)
{
$fileSize .= 'B';
}
elseif($fileSize < 1024 * 1024)
{
$fileSize = round($fileSize / 1024, 2) . 'KB';
}
elseif($fileSize < 1024 * 1024 * 1024)
{
$fileSize = round($fileSize / 1024 / 1024, 2) . 'MB';
$doc->objectName = $objects[$doc->objectType][$doc->objectID];
}
else
{
$fileSize = round($fileSize / 1024 / 1024 / 1024, 2) . 'G';
if($doc->objectType == 'mine') $doc->objectName = $this->lang->doc->person;
if($doc->objectType == 'custom') $doc->objectName = $this->lang->doc->team;
}
$docs[$index]->fileSize = $fileSize;
}
}
$docs = $this->processCollector($docs);
return $docs;
return $this->processCollector($docs);
}
/**
@@ -666,7 +648,7 @@ class docModel extends model
->andWhere('t2.actor')->eq($this->app->user->account)
->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(!common::hasPriv('doc', 'teamSpace'))->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()
@@ -675,18 +657,31 @@ class docModel extends model
->page($pager, 't1.id')
->fetchAll('id');
}
elseif($type == 'createdby')
elseif($type == 'createdby' || $type == 'editedby')
{
$docIDList = array_keys($docIDList);
if($type == 'editedby')
{
$editDocs = $this->dao->select('objectID')->from(TABLE_ACTION)
->where('objectType')->eq('doc')
->andWhere('action')->eq('edited')
->andWhere('actor')->eq($this->app->user->account)
->andWhere('vision')->eq($this->config->vision)
->fetchPairs();
$docIDList = array_intersect($docIDList, $editDocs);
}
$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.id')->in($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(!common::hasPriv('doc', 'teamSpace'))->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)
@@ -766,14 +761,6 @@ class docModel extends model
->fetch();
if(!$doc) return false;
if(!$this->checkPrivDoc($doc))
{
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')));
helper::end(print(js::locate('back')));
die;
}
$docs = $this->processCollector(array($doc->id => $doc));
$doc = $docs[$doc->id];
@@ -852,7 +839,7 @@ class docModel extends model
$now = helper::now();
$doc = fixer::input('post')
->callFunc('title', 'trim')
->setDefault('content', '')
->setDefault('content,template,templateType,chapterType', '')
->add('addedBy', $this->app->user->account)
->add('addedDate', $now)
->add('editedBy', $this->app->user->account)
@@ -891,6 +878,7 @@ class docModel extends model
$docContent->title = $doc->title;
$docContent->content = $doc->contentType == 'html' ? $doc->content : $doc->contentMarkdown;
$docContent->type = $doc->contentType;
$docContent->digest = '';
$docContent->version = 1;
unset($doc->contentMarkdown, $doc->contentType, $doc->url);
@@ -1092,7 +1080,7 @@ class docModel extends model
$products = $this->product->getPairs();
$this->config->doc->search['params']['project']['values'] = array('' => '') + $this->loadModel('project')->getPairsByProgram('', 'all', false, 'order_asc', 'kanban') + array('all' => $this->lang->doc->allProjects);
$this->config->doc->search['params']['execution']['values'] = array('' => '') + $this->loadModel('execution')->getPairs(0, 'sprint,stage', 'multiple,leaf,noprefix') + array('all' => $this->lang->doc->allExecutions);
$this->config->doc->search['params']['execution']['values'] = array('' => '') + $this->loadModel('execution')->getPairs(0, 'sprint,stage', 'multiple,leaf,noprefix,withobject') + array('all' => $this->lang->doc->allExecutions);
$this->config->doc->search['params']['lib']['values'] = array('' => '') + $this->loadModel('doc')->getLibs('all', 'withObject') + array('all' => $this->lang->doclib->all);
$this->config->doc->search['params']['product']['values'] = array('' => '') + $products + array('all' => $this->lang->doc->allProduct);
@@ -2518,12 +2506,12 @@ class docModel extends model
foreach($moduleDocs[0] as $doc)
{
if(!$docID and $currentMethod != 'tablecontents') $docID = $doc->id;
if(!$docID and $currentMethod != 'teamspace') $docID = $doc->id;
$class = common::hasPriv('doc', 'updateOrder') ? ' sortDoc' : '';
$treeMenu[0] .= '<li' . " class='" . ($doc->id == $docID ? 'active' : 'doc') . "$class'" . " data-id=$doc->id>";
if($currentMethod == 'tablecontents')
if($currentMethod == 'teamspace')
{
$treeMenu[0] .= '<div class="tree-group"><span class="tail-info">' . zget($users, $doc->editedBy) . ' &nbsp;' . $doc->editedDate . '</span>';
}
@@ -2595,11 +2583,11 @@ class docModel extends model
}
else
{
if(!$docID and $currentMethod != 'tablecontents') $docID = $doc->id;
if(!$docID and $currentMethod != 'teamspace') $docID = $doc->id;
$class = common::hasPriv('doc', 'updateOrder') ? ' sortDoc' : '';
$treeMenu[$module->id] .= '<li' . " class='" . ($doc->id == $docID ? 'active' : 'doc') . "$class'" . " data-id=$doc->id>";
if($currentMethod == 'tablecontents')
if($currentMethod == 'teamspace')
{
$treeMenu[$module->id] .= '<div class="tree-group"><span class="tail-info">' . zget($users, $doc->editedBy) . ' &nbsp;' . $doc->editedDate . '</span>';
}
@@ -2617,7 +2605,7 @@ class docModel extends model
}
$treeMenu[$module->id] .= '</div>';
}
elseif($currentMethod == 'tablecontents')
elseif($currentMethod == 'teamspace')
{
$class = common::hasPriv('doc', 'updateOrder') ? 'sortDoc' : '';
$treeMenu[$module->id] .= html::a(inlink('view', "docID={$doc->id}"), "<i class='icon icon-file-text text-muted'></i> &nbsp;" . $doc->title, '', "data-app='{$this->app->tab}' class='doc-title $class' title='{$doc->title}'");
@@ -2641,7 +2629,7 @@ class docModel extends model
{
$moduleClass = common::hasPriv('tree', 'updateOrder') ? 'sort-module' : '';
$li = "<div class='tree-group'><span class='module-name'><a class='$moduleClass' title='{$module->name}'>" . $module->name . '</a></span>';
if($currentMethod != 'tablecontents')
if($currentMethod != 'teamspace')
{
if(common::hasPriv('tree', 'edit') or common::hasPriv('tree', 'browse') or common::hasPriv('tree', 'browse') or common::hasPriv('tree', 'updateOrder'))
{
@@ -2749,7 +2737,6 @@ class docModel extends model
*/
public function setMenuByType($type, $objectID, $libID, $appendLib = 0)
{
$this->session->set('docList', $this->app->getURI(true), $this->app->tab);
if(empty($type))
{
$doclib = $this->getLibById($libID);
@@ -2761,15 +2748,8 @@ class docModel extends model
$objectDropdown = '';
if(in_array($type, array('project', 'product', 'execution')))
{
$objects = $this->getOrderedObjects($type);
$objectID = $this->loadModel($type)->saveState($objectID, $objects);
$table = $this->config->objectTables[$type];
$libs = $this->getLibsByObject($type, $objectID, '', $appendLib);
if(($libID == 0 or !isset($libs[$libID])) and !empty($libs)) $libID = reset($libs)->id;
$object = $this->dao->select('id,name,status')->from($table)->where('id')->eq($objectID)->fetch();
$objectTitle = zget($objects, $objectID, '');
$objectDropdown = $this->select($type, $objectTitle, $objectID);
$table = $this->config->objectTables[$type];
$object = $this->dao->select('id,name,status')->from($table)->where('id')->eq($objectID)->fetch();
if(empty($object))
{
@@ -2777,11 +2757,32 @@ class docModel extends model
$methodName = ($type == 'project' and $this->config->vision != 'lite') ? 'createGuide' : 'create';
return print(js::locate(helper::createLink($type, $methodName, $param)));
}
$objects = $this->getOrderedObjects($type);
$objectID = $this->loadModel($type)->saveState($objectID, $objects);
$libs = $this->getLibsByObject($type, $objectID, '', $appendLib);
if(($libID == 0 or !isset($libs[$libID])) and !empty($libs)) $libID = reset($libs)->id;
$objectTitle = zget($objects, $objectID, '');
if($this->app->tab != 'doc' and isset($libs[$libID]))
{
$objectTitle = zget($libs[$libID], 'name', '');
$objectDropdown = "<div id='sidebarHeader'><div class='title' title='{$objectTitle}'>{$objectTitle}</div></div>";
}
else
{
$objectDropdown = $this->select($type, $objectTitle, $objectID);
}
}
else
{
$libs = $this->getLibsByObject($type, 0, '', $appendLib);
if($libID == 0 and !empty($libs)) $libID = reset($libs)->id;
if(isset($libs[$libID]))
{
$objectTitle = zget($libs[$libID], 'name', '');
$objectDropdown = "<div id='sidebarHeader'><div class='title' title='{$objectTitle}'>{$objectTitle}</div></div>";
}
$object = new stdclass();
$object->id = 0;
@@ -3131,6 +3132,15 @@ class docModel extends model
$myCreation->hasAction = false;
$myCreation->active = $libType == 'createdby' ? 1 : 0;
$myCreation = new stdclass();
$myCreation->id = 0;
$myCreation->name = $this->lang->doc->myEdited;
$myCreation->type = 'editedBy';
$myCreation->objectType = 'doc';
$myCreation->objectID = 0;
$myCreation->hasAction = false;
$myCreation->active = $libType == 'editedby' ? 1 : 0;
$libTree = array();
$libTree[] = $myLib;
if(common::hasPriv('doc', 'myView')) $libTree[] = $myView;
@@ -3162,21 +3172,18 @@ class docModel extends model
foreach($this->lang->doc->createList as $typeKey => $typeName)
{
if($this->config->edition != 'max' and $typeKey == 'template') continue;
$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={$lib->type}&objectID=$objectID&libID={$lib->id}&moduleID=$moduleID&type=html&from=template";
$docType = zget($this->config->doc->iconList, $typeKey);
$icon = html::image("static/svg/{$docType}.svg", "class='file-icon'");
$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' and $this->config->edition == 'max') $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");
$html .= html::a(helper::createLink('doc', 'create', $params, '', $class ? true : false), $icon . ' ' . $typeName, '', "class='$class' $attr");
$html .= "</li>";
$printDivider = false;
if($typeKey == 'template') $printDivider = true;
if($this->config->edition != 'max' and $typeKey == 'html') $printDivider = true;
if($printDivider) $html .= '<li class="divider"></li>';
if($typeKey == 'template') $html .= '<li class="divider"></li>';
}
$html .= '</ul></div>';
@@ -3264,7 +3271,7 @@ class docModel extends model
if($action == 'collect')
{
$collectCount = $this->dao->select('count(*) as count')->from(TABLE_DOCACTION)->where('doc')->eq($docID)->andWhere('action')->eq('collect')->fetch('count');
$this->dao->update(TABLE_DOC)->set('collector')->eq($collectCount)->where('id')->eq($docID)->exec();
$this->dao->update(TABLE_DOC)->set('collects')->eq($collectCount)->where('id')->eq($docID)->exec();
}
return $actionID;
@@ -3300,7 +3307,7 @@ class docModel extends model
if($action->action == 'collect')
{
$collectCount = $this->dao->select('count(*) as count')->from(TABLE_DOCACTION)->where('doc')->eq($action->doc)->andWhere('action')->eq('collect')->fetch('count');
$this->dao->update(TABLE_DOC)->set('collector')->eq($collectCount)->where('id')->eq($action->doc)->exec();
$this->dao->update(TABLE_DOC)->set('collects')->eq($collectCount)->where('id')->eq($action->doc)->exec();
}
}
@@ -3316,7 +3323,7 @@ class docModel extends model
$actionGroup = $this->dao->select('*')->from(TABLE_DOCACTION)->where('doc')->in(array_keys($docs))->andWhere('action')->eq('collect')->fetchGroup('doc', 'actor');
foreach($docs as $docID => $doc)
{
$doc->collector = '';
$doc->collector = '';
if(isset($actionGroup[$docID])) $doc->collector = ',' . implode(',', array_keys($actionGroup[$docID])) . ',';
}
return $docs;
+5 -3
View File
@@ -28,7 +28,6 @@
</div>
</div>
<div class="actions">
<span class='text'><?php echo$lang->doc->diff?></span>
<?php echo html::a("javascript:fullScreen()", '<span class="icon-fullscreen"></span>', '', "title='{$lang->fullscreen}' class='btn btn-link fullscreen-btn'");?>
<?php if(common::hasPriv('doc', 'collect')):?>
<?php $star = strpos($doc->collector, ',' . $this->app->user->account . ',') !== false ? 'star' : 'star-empty';?>
@@ -74,7 +73,10 @@
<div class="">
<div class="detail-content article-content table-col">
<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>
<span class='user-time text-muted'><i class='icon icon-contacts'></i> <?php echo zget($users, $doc->addedBy) . " {$lang->colon} " . substr($doc->addedDate, 0, 10) . (common::checkNotCN() ? ' ' : '') . $lang->doc->createAB;?></span>
<!-- <span data-url="<?php echo $this->createLink('doc', 'collect', "objectID=$doc->id&objectType=doc");?>" title="<?php echo $lang->doc->collect;?>" class='user-time ajaxCollect text-muted'><?php echo html::image("static/svg/{$star}.svg", "class='$star'");?> <?php echo $doc->collects;?></span> -->
<span class='user-time text-muted'><i class='icon-star'></i> <?php echo $doc->collects;?></span>
<span class='user-time text-muted'><i class='icon-eye'></i> <?php echo $doc->views;?></span>
<?php if($doc->keywords):?>
<span class='keywords'>
<?php foreach($doc->keywords as $keywords):?>
@@ -158,7 +160,7 @@
<?php echo $outline;?>
</div>
</div>
<div class="outline-toggle"><i class="icon icon-angle-right"></i></div>
<div class="outline-toggle"><i class="icon icon-menu-arrow-left"></i></div>
<?php endif;?>
<div id="history" class='panel hidden' style="margin-left: 2px;">
<?php
+1 -1
View File
@@ -25,7 +25,7 @@
<?php if($objectType == 'custom' and empty($libs)):?>
<?php echo html::a(helper::createLink('doc', 'createLib', "type=custom&objectID=$objectID"), '<i class="icon icon-plus"></i> ' . $lang->doc->createLib, '', 'class="iframe hidden createCustomLib"');?>
<?php endif;?>
<form class="load-indicator main-form form-ajax" id="dataform" method='post' enctype='multipart/form-data'>
<form class="load-indicator main-form form-ajax form-watched" id="dataform" method='post' enctype='multipart/form-data'>
<table class='table table-form'>
<tbody>
<tr>
+1 -1
View File
@@ -24,7 +24,7 @@
<div class='main-header'>
<h2><?php echo $lang->doc->createLib;?></h2>
</div>
<form method='post' class='main-form form-ajax no-stash' enctype='multipart/form-data' >
<form method='post' class='main-form form-ajax no-stash form-watched' enctype='multipart/form-data' >
<table class='table table-form'>
<?php if(in_array($type, array('product', 'project', 'execution'))):?>
<tr class='objectBox'>
+3 -5
View File
@@ -22,14 +22,13 @@
<?php echo html::a(helper::createLink('doc', 'createLib', "type=custom&objectID=$objectID"), '<i class="icon icon-plus"></i> ' . $lang->doc->createLib, '', 'class="iframe hidden createCustomLib"');?>
<?php endif;?>
<div id="mainContent" class="main-content">
<form class="load-indicator main-form form-ajax" id="dataform" method='post' enctype='multipart/form-data'>
<form class="load-indicator main-form form-ajax form-watched" id="dataform" method='post' enctype='multipart/form-data'>
<table class='table table-form'>
<tbody>
<tr id='headerBox'>
<td width='90px'><?php echo html::backButton("<i class='icon icon-back icon-sm'></i> " . $lang->goback, "id='backBtn'", 'btn btn-secondary');?></td>
<td class="doc-title" colspan='3'><?php echo html::input('title', '', "placeholder='{$lang->doc->titlePlaceholder}' id='editorTitle' class='form-control' required");?></td>
<td class="text-right btn-tools">
<span id='savePath' class='text-gray'></span>
<?php echo html::commonButton($lang->doc->saveDraft, "id='saveDraft' data-placement='bottom'", "btn btn-secondary");?>
<?php echo html::a('#modalBasicInfo', $lang->release->common, '', "data-toggle='modal' id='basicInfoLink' class='btn btn-primary'");?>
</td>
@@ -71,7 +70,7 @@
<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 id='executionBox'><?php echo html::select('execution', $executions, isset($execution) ? $objectID : '', "class='form-control chosen' 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>
@@ -149,13 +148,12 @@
</div>
<?php js::set('textType', $config->doc->textTypes);?>
<?php js::set('docType', $docType);?>
<?php js::set('holders', $lang->doc->placeholder);?>
<?php js::set('objectType', $objectType);?>
<?php js::set('type', 'doc');?>
<?php js::set('requiredFields', ',' . $config->doc->create->requiredFields . ',');?>
<?php js::set('libNotEmpty', sprintf($lang->error->notempty, $lang->doc->lib));?>
<?php js::set('keywordsNotEmpty', sprintf($lang->error->notempty, $lang->doc->keywords));?>
<?php js::set('from', $from);?>
<?php js::set('defaultSave', $lang->doc->defaultSave);?>
<?php js::set('titleNotEmpty', sprintf($lang->error->notempty, $lang->doc->title));?>
<?php js::set('contentNotEmpty', sprintf($lang->error->notempty, $lang->doc->content));?>
<?php include '../../common/view/footer.lite.html.php';?>
+2 -3
View File
@@ -20,7 +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;}
.table-files .btn {padding: 2px;}
</style>
<?php if(common::checkNotCN()):?>
<style>
@@ -42,7 +42,6 @@ body {margin-bottom: 25px;}
</div>
<?php else:?>
<?php $vars = "objectID=$objectID&$libID=$libID&moduleID=$moduleID&browseType=$browseType&orderBy=%s&param=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}";?>
<?php if($app->rawMethod == 'tablecontents') $vars = "type=$type&" . $vars;?>
<div>
<form class='main-table' method='post' id='docListForm'>
<table class="table table-files has-sort-head">
@@ -82,7 +81,7 @@ body {margin-bottom: 25px;}
</td>
<td class="c-name" title='<?php echo $doc->title;?>'>
<?php
$docType = $doc->type == 'text' ? 'wiki-file' : $doc->type;
$docType = zget($config->doc->iconList, $doc->type);
$icon = html::image("static/svg/{$docType}.svg", "class='file-icon'");
if(common::hasPriv('doc', 'view'))
{
+1 -1
View File
@@ -26,7 +26,7 @@
<?php echo $lib->type != 'book' ? $lang->doc->editLib : $lang->doc->editBook;?>
</h2>
</div>
<form method='post' class='load-indicator main-form form-ajax'>
<form method='post' class='load-indicator main-form form-ajax form-watched'>
<table class='table table-form'>
<?php if(in_array($lib->type, array('product', 'project', 'execution'))):?>
<tr>
+1 -1
View File
@@ -26,7 +26,7 @@
<small> <?php echo $lang->arrow . ' ' . $lang->doc->edit;?></small>
</h2>
</div>
<form class='load-indicator main-form form-ajax' method='post' enctype='multipart/form-data' id='dataform'>
<form class='load-indicator main-form form-ajax form-watched' method='post' enctype='multipart/form-data' id='dataform'>
<table class='table table-form'>
<?php if(strpos('product|project|execution', $type) !== false):?>
<tr>
+1 -4
View File
@@ -20,7 +20,7 @@
</style>
<?php $backLink = $app->session->docList ? $app->session->docList : $this->createLink('doc', 'view', "docID={$doc->id}") . "#app={$this->app->tab}";?>
<div id="mainContent" class="main-content">
<form class="load-indicator main-form form-ajax" id="dataform" method='post' enctype='multipart/form-data'>
<form class="load-indicator main-form form-ajax form-watched" id="dataform" method='post' enctype='multipart/form-data'>
<table class='table table-form'>
<tbody>
<tr id='headerBox'>
@@ -28,7 +28,6 @@
<td class="doc-title" colspan='3'><?php echo html::input('title', $doc->title, "placeholder='{$lang->doc->titlePlaceholder}'' id='editorTitle' class='form-control' required");?></td>
<td class="text-right btn-tools">
<?php if($doc->status == 'draft'):?>
<span id='savePath' class='text-gray'></span>
<?php echo html::commonButton($lang->doc->saveDraft, "id='saveDraft'", "btn btn-secondary");?>
<?php echo html::commonButton($lang->release->common, "id='saveRelease'", "btn btn-primary");?>
<?php else:?>
@@ -148,8 +147,6 @@ $(function()
<?php js::set('confirmUpdateContent', $lang->doc->confirmUpdateContent);?>
<?php js::set('docID', $doc->id);?>
<?php js::set('draft', $doc->draft);?>
<?php js::set('holders', $lang->doc->placeholder);?>
<?php js::set('type', 'doc');?>
<?php js::set('defaultSave', $lang->doc->defaultSave);?>
<?php js::set('titleNotEmpty', sprintf($lang->error->notempty, $lang->doc->title));?>
<?php include '../../common/view/footer.html.php';?>
+30 -23
View File
@@ -24,7 +24,8 @@
.tree-icon {position: absolute; right: 0;}
.tree li.has-input {overflow: hidden;}
.tree li.has-input > input.input-bro {margin-left: 15px;}
.img-lib {flex: 0 0 14px; height: 14px; margin-right: 5px;}
.img-lib {flex: 0 0 14px; height: 14px; margin-right: 5px; margin-bottom: 2px;}
.file-icon {width: 14px; margin-bottom: 4px;}
.tree-icon {position: absolute; right: 0;}
.tree li > a {max-width: 100%; padding: 2px;}
.file-tree a.show-icon > div,
@@ -55,6 +56,7 @@ i.btn-info, i.btn-info:hover {border: none; background: #fff; box-shadow: unset;
[lang^=zh] #leftBar .selectBox #currentItem {width: 180px;}
#leftBar .selectBox #currentItem > .text {overflow: hidden; text-align: left; flex: 0 1 100%;}
.dropdown-in-tree {max-height: 293px; overflow-y: auto;}
.before-tree-item {flex: 0 0 14px; margin-right: 5px;}
</style>
<?php
@@ -67,6 +69,7 @@ js::set('objectType', isset($type) ? $type : '');
js::set('objectID', isset($objectID) ? $objectID : '');
js::set('isFirstLoad', isset($isFirstLoad) ? $isFirstLoad: '');
js::set('canViewFiles', common::hasPriv('doc', 'showfiles'));
js::set('spaceMethod', $config->doc->spaceMethod);
?>
<div id="fileTree" class="file-tree menu-active-primary menu-hover-primary">
@@ -232,7 +235,7 @@ $(function()
var imgObj = {
'annex': 'annex',
'api': 'interface',
'lib': 'wiki-file-lib',
'lib': 'wiki',
'execution': 'wiki-file-lib',
'text': 'wiki-file',
'word': 'word',
@@ -257,7 +260,7 @@ $(function()
var $item = '<a href="' + link + '" style="position: relative" data-has-children="' + hasChild + '" title="' + item.name + '" data-id="' + item.id + '" class="' + libClass + '" data-type="' + item.type + '" data-action="' + item.hasAction + '">';
$item += '<div class="text h-full w-full flex-start overflow-hidden">';
if((libClass == 'lib' && item.type != 'execution') || (item.type == 'execution' && item.hasAction)) $item += '<div class="img-lib" style="background-image:url(static/svg/' + imgObj[item.type || 'lib'] + '.svg)"></div>';
if((libClass == 'lib' && item.type != 'execution') || (item.type == 'execution' && item.hasAction)) $item += '<i class="before-tree-item icon icon-' + imgObj[item.type] +'-lib"></i>';
if(['text', 'word', 'ppt', 'excel'].indexOf(item.type) !== -1) $item += '<div class="img-lib" style="background-image:url(static/svg/' + imgObj[item.type] + '.svg)"></div>';
$item += '<div class="tree-text">';
$item += item.name;
@@ -353,13 +356,13 @@ $(function()
var libClass = '.' + moduleType + 'LibDorpdown';
if(!$(this).hasClass('lib')) libClass = '.' + moduleType + 'ModuleDorpdown';
$(this).find('.icon').removeClass('hidden');
$(this).find('.icon-drop').removeClass('hidden');
$(this).addClass('show-icon');
if($(libClass).find('li').length == 0) return false;
}).on('mouseout', 'a', function()
{
if(!$(this).closest('a').hasClass('hover')) $(this).find('.icon').addClass('hidden');
if(!$(this).closest('a').hasClass('hover')) $(this).find('.icon-drop').addClass('hidden');
$(this).removeClass('show-icon');
}).on('click', 'a', function()
{
@@ -434,6 +437,7 @@ $(function()
if(!libID) libID = 0;
if(!moduleID) moduleID = 0;
linkParams = linkParams.replace('%s', 'libID=' + libID + '&moduleID=' + moduleID);
var moduleName = config.currentModule;
var methodName = '';
if(config.currentModule == 'api')
{
@@ -445,27 +449,28 @@ $(function()
methodName = 'showFiles';
linkParams = 'type=' + objectType + '&objectID=' + objectID;
}
else if(objectType == 'mine' || objectType == 'view' || objectType == 'collect' || objectType == 'createdby')
{
var mySpaceType = 'mine';
if(type == 'view' || type == 'collect') mySpaceType = type;
if(type == 'createdBy' || type == 'createdby') mySpaceType = 'createdby';
methodName = 'mySpace';
linkParams = 'type='+ mySpaceType + '&libID=' + libID + '&moduleID=' + moduleID;
}
else if(['text', 'word', 'ppt', 'excel'].indexOf(type) !== -1)
{
methodName = 'view';
linkParams = 'docID=' + moduleID;
}
else if(objectType == 'execution')
{
moduleName = 'execution';
methodName = 'doc';
linkParams = 'executionID=0';
}
else
{
methodName = objectType == 'execution' || objectType == 'custom' ? 'tableContents' : objectType + 'Space';
linkParams = objectType == 'execution' || objectType == 'custom' ? 'type=' + objectType + '&' + linkParams : linkParams;
methodName = spaceMethod[objectType] ? spaceMethod[objectType] : 'teamSpace';
if(['mine', 'view', 'collect', 'createdby', 'editedby'].indexOf(objectType) !== -1)
{
type = ['view', 'collect', 'createdby', 'editedby'].indexOf(type.toLowerCase()) !== -1 ? type.toLowerCase() : 'mine';
linkParams = 'type=' + type + '&' + linkParams;
}
}
location.href = createLink(config.currentModule, methodName, linkParams);
location.href = createLink(moduleName, methodName, linkParams);
}
$('body').on('click', function()
@@ -478,13 +483,13 @@ $(function()
if($hoverItem.length)
{
$hoverItem.removeClass('hover');
$hoverItem.find('.icon').addClass('hidden');
$hoverItem.find('.icon-drop').addClass('hidden');
}
$dropdown.remove();
}
}).on('click', '.sidebar-toggle', function()
{
var $icon = $(this).find('.icon');
var $icon = $(this).find('.icon-drop');
if($('#sideBar').hasClass('hidden'))
{
$icon.addClass('icon-angle-left');
@@ -542,7 +547,8 @@ $(function()
$rootDom.after($input);
$li.addClass('open in has-list');
}
$rootDom.parent().find('input').focus();
$input = $rootDom.parent().find('input');
$input.focus();
break;
case 'addCataBro' :
moduleData.createType = 'same';
@@ -550,7 +556,8 @@ $(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').addClass('input-bro').focus();
$input = $('#fileTree').find('input').addClass('input-bro');
$input.focus();
break;
case 'addCataChild' :
moduleData.parentID = item.id;
@@ -568,9 +575,9 @@ $(function()
moduleData.isUpdate = true;
$rootDom.addClass('open in has-list');
}
$rootDom.append($input);
$rootDom.find('input').focus();
$input = $rootDom.find('input');
$input.focus();
break;
}
}).on('click', '#versionSwitcher a', function()
+11 -3
View File
@@ -16,17 +16,18 @@ body {margin-bottom: 25px;}
#docListForm th.c-user {width: 80px;}
#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 .c-object {width: 180px;}
#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 .c-name > .ajaxCollect {float: right; position: relative; right: 10px; top: 0px; padding: 0 6px;}
#docListForm table.table > thead > tr {height: 32px;}
#docListForm .checkbox-primary {line-height: 16px;}
#docListForm table .checkbox-primary {top: -2px;}
#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;}
.table-files .btn {padding: 2px;}
</style>
<?php if(common::checkNotCN()):?>
<style>
@@ -34,6 +35,7 @@ body {margin-bottom: 25px;}
#docListForm th.c-user {width: 102px !important;}
</style>
<?php endif;?>
<?php js::set('isMyCollection', $type == 'collect' ? 1 : 0);?>
<?php if(empty($docs)):?>
<div class="table-empty-tip">
<p>
@@ -96,7 +98,7 @@ body {margin-bottom: 25px;}
</td>
<td class="c-name" title='<?php echo $doc->title;?>'>
<?php
$docType = $doc->type == 'text' ? 'wiki-file' : $doc->type;
$docType = zget($config->doc->iconList, $doc->type);
$icon = html::image("static/svg/{$docType}.svg", "class='file-icon'");
if(common::hasPriv('doc', 'view'))
{
@@ -192,5 +194,11 @@ $(function()
return checkedTotal ? checkedSummary.replace('%total%', checkedTotal) : pageSummary;
}
});
$('.ajaxCollect').click(function()
{
if(isMyCollection) window.location.reload();
});
});
</script>
+1
View File
@@ -19,6 +19,7 @@
<?php js::set('treeData', $libTree)?>
<div id="mainMenu" class="clearfix">
<div id="leftBar" class="btn-toolbar pull-left">
<?php echo $objectDropdown;?>
<?php if(!empty($libTree)):?>
<?php foreach($lang->doc->featureBar['tableContents'] as $barType => $barName):?>
<?php $active = $barType == $browseType ? 'btn-active-text' : '';?>
+2 -2
View File
@@ -36,7 +36,7 @@
<th><?php echo $lang->doc->project;?></th>
<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 id='executionBox'><?php echo html::select('execution', array(), '', "class='form-control picker-select' 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'>
@@ -53,7 +53,6 @@
</table>
</form>
</div>
<?php js::set('holders', $lang->doc->placeholder);?>
<script>
$(function(){changeSpace()});
@@ -73,6 +72,7 @@ function changeSpace()
$('#typeapi').toggleClass('hidden', space == 'mine' || space == 'custom');
$('#typedoc').closest('.radio-inline').toggleClass('hidden', space == 'api');
$('#typeapi').closest('.radio-inline').toggleClass('hidden', space == 'mine' || space == 'custom');
$('#docType').toggleClass('hidden', $('#docType [name=type]:not(.hidden)').length == 1);
var docType = $('[name=type]:not(.hidden):checked').val();
if(space == 'project' && docType) $('#project').change();
+1 -1
View File
@@ -22,7 +22,7 @@
<?php if($libType != 'api'):?>
<?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 $linkParams = "objectID=$objectID&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;?>
<?php endif;?>
+3 -9
View File
@@ -24,19 +24,13 @@
<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;?>
<?php $gobackLink = $this->session->docList ? $this->session->docList : inlink('teamSpace', "objectID=0&libID=$libID");?>
<?php echo html::a($gobackLink, "<i class='icon-back'></i> " . $lang->goback, '', "class='btn btn-link'");?>
</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('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(common::hasPriv('doc', 'create')) echo $this->doc->printCreateBtn($lib, $moduleID);
?>
</div>
+3 -3
View File
@@ -1829,7 +1829,7 @@ class execution extends control
if($this->app->tab == 'doc')
{
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('doc', 'objectLibs', "type=execution")));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('doc', 'projectSpace', "objectID=$executionID")));
}
if(!empty($projectID) and strpos(',kanban,agileplus,waterfallplus,', ",$project->model,") !== false)
@@ -4181,9 +4181,9 @@ class execution extends control
* @access public
* @return void
*/
public function doc($executionID)
public function doc($executionID, $libID = 0, $moduleID = 0, $browseType = 'all', $orderBy = 'status,id_desc', $param = 0, $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
$this->locate($this->createLink('doc', 'objectLibs', "type=execution&objectID=$executionID&from=execution"));
echo $this->fetch('doc', 'tableContents', "type=execution&objectID=$executionID&libID=$libID&moduleID=$moduleID&browseType=$browseType&orderBy=$orderBy&param=$param&recTotal=$recTotal&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID");
}
/**
-4
View File
@@ -2212,10 +2212,6 @@ class executionModel extends model
{
$link = helper::createLink('doc', $method, "type=execution&objectID=%s&from=execution");
}
elseif($module == 'api')
{
$link = helper::createLink('doc', 'tableContents', "type=execution&objectID=%s&from=execution");
}
elseif(in_array($module, array('issue', 'risk', 'opportunity', 'pssp', 'auditplan', 'nc', 'meeting')))
{
$link = helper::createLink($module, 'browse', "executionID=%s&from=execution");
+4 -4
View File
@@ -128,15 +128,15 @@
<div class="panel block-docs" style="height: 240px">
<div class="panel-heading">
<div class="panel-title"><?php echo $lang->execution->doclib;?></div>
<?php if(common::hasPriv('doc', 'objectLibs')):?>
<?php if(common::hasPriv('execution', 'doc')):?>
<nav class="panel-actions nav nav-default">
<li><?php common::printLink('doc', 'objectLibs', "type=execution&executionID=$execution->id&from=execution", strtoupper($lang->more), '', "title=$lang->more");?></li>
<li><?php common::printLink('execution', 'doc', "executionID=$execution->id", strtoupper($lang->more), '', "title=$lang->more");?></li>
</nav>
<?php endif;?>
</div>
<div class="panel-body">
<div class="row row-grid">
<?php if(common::hasPriv('doc', 'objectLibs')):?>
<?php if(common::hasPriv('execution', 'doc')):?>
<?php $i = 0;?>
<?php foreach($docLibs as $libID => $docLib):?>
<?php if($i > 8) break;?>
@@ -144,7 +144,7 @@
<?php if($libID == 'files'):?>
<?php echo html::a($this->createLink('doc', 'showFiles', "type=execution&objectID=$execution->id"), "<i class='icon icon-folder text-yellow'></i> " . $docLib->name);?>
<?php else:?>
<?php echo html::a($this->createLink('doc', 'objectLibs', "type=execution&objectID={$execution->id}&libID=$libID"), "<i class='icon icon-folder text-yellow'></i> " . $docLib->name, '', "data-app='execution' title='$docLib->name'");?>
<?php echo html::a($this->createLink('execution', 'doc', "objectID={$execution->id}&libID=$libID"), "<i class='icon icon-folder text-yellow'></i> " . $docLib->name, '', "data-app='execution' title='$docLib->name'");?>
<?php endif;?>
</div>
<?php $i++;?>
+2
View File
@@ -0,0 +1,2 @@
.main-content>.center-block {max-width: 800px;}
#giteaForm table {width: 600px;}
-1
View File
@@ -22,7 +22,6 @@
<tr>
<th><?php echo $lang->gitea->name;?></th>
<td class='required'><?php echo html::input('name', '', "class='form-control'");?></td>
<td class="tips-git"></td>
</tr>
<tr>
<th><?php echo $lang->gitea->url;?></th>
+26 -5
View File
@@ -132,7 +132,7 @@ class gitlab extends control
* @access public
* @return void
*/
public function bindUser($gitlabID)
public function bindUser($gitlabID, $type = 'all')
{
$userPairs = $this->loadModel('user')->getPairs('noclosed|noletter');
@@ -140,7 +140,7 @@ class gitlab extends control
$user = $this->gitlab->apiGetCurrentUser($gitlab->url, $gitlab->token);
if(!isset($user->is_admin) or !$user->is_admin) return print(js::alert($this->lang->gitlab->tokenLimit) . js::locate($this->createLink('gitlab', 'edit', array('gitlabID' => $gitlabID))));
$zentaoUsers = $this->dao->select('account,email,realname')->from(TABLE_USER)->fetchAll('account');
$zentaoUsers = $this->dao->select('account,email,realname')->from(TABLE_USER)->where('deleted')->eq('0')->fetchAll('account');
if($_POST)
{
@@ -188,11 +188,32 @@ class gitlab extends control
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->server->http_referer));
}
$gitlabUsers = $this->gitlab->apiGetUsers($gitlabID);
$bindedUsers = $this->gitlab->getUserAccountIdPairs($gitlabID);
$matchedResult = $this->gitlab->getMatchedUsers($gitlabID, $gitlabUsers, $zentaoUsers);
$matchedResult = array_column(json_decode(json_encode($matchedResult), true), null, "email");
$gitlabUsers = array_filter($gitlabUsers, function($item) use($bindedUsers, $userPairs, $type)
{
if($type == 'all') return true;
if(in_array($item->id, $bindedUsers))
{
$zentaoAccount = isset($item->zentaoAccount) ? zget($userPairs, $item->zentaoAccount, '') : '';
return $type == 'binded' ? !empty($zentaoAccount) : empty($zentaoAccount);
}
return $type == 'binded' ? false : true;
});
$this->view->title = $this->lang->gitlab->bindUser;
$this->view->zentaoUsers = $zentaoUsers;
$this->view->userPairs = $userPairs;
$this->view->gitlabUsers = $this->gitlab->apiGetUsers($gitlabID);
$this->view->bindedUsers = $this->gitlab->getUserAccountIdPairs($gitlabID);
$this->view->matchedResult = $this->gitlab->getMatchedUsers($gitlabID, $this->view->gitlabUsers, $zentaoUsers);
$this->view->type = $type;
$this->view->gitlabID = $gitlabID;
$this->view->gitlabUsers = $gitlabUsers;
$this->view->bindedUsers = $bindedUsers;
$this->view->matchedResult = $matchedResult;
$this->display();
}
+7
View File
@@ -1,2 +1,9 @@
#publicTip {padding-left: 10px;}
.table-form>tbody>tr>th {width: 110px;}
.gitlab-bind .btn-info{background-color: unset;color:unset;padding: 6px 6px;}
.gitlab-bind .btn-info.active{color: #2e7fff;background-color: rgba(239,239,239,.8);
border-color: rgba(0,0,0,0);}
.gitlab-bind-all{padding: 1px 6px;margin-left: 5px;border-radius: 10px;background: white;}
.img-circle {border-radius: 50%;}
.gitlab-account-desc{color: #9EA3B0;font-size: 12px;}
.gitlab-user-select .chosen-container{max-width: 200px;}
+2
View File
@@ -0,0 +1,2 @@
.main-content>.center-block {max-width: 800px;}
#gitlabForm table {width: 600px;}
+11
View File
@@ -0,0 +1,11 @@
$(document).ready(function()
{
$('.gitlab-user-bind').change(function()
{
var user = zentaoUsers[$(this).val()];
if(user !== undefined)
{
$(this).parent().parent().find('.email').text(user.email)
}
});
});
+5 -2
View File
@@ -5,7 +5,7 @@ $lang->gitlab->search = 'Search';
$lang->gitlab->create = 'Create GitLab';
$lang->gitlab->edit = 'Edit GitLab';
$lang->gitlab->view = 'View GitLab';
$lang->gitlab->bindUser = 'Bind User';
$lang->gitlab->bindUser = 'Permission Setting';
$lang->gitlab->webhook = 'Webhook';
$lang->gitlab->bindProduct = "Import {$lang->productCommon}";
$lang->gitlab->importIssue = 'Import Issue';
@@ -13,9 +13,12 @@ $lang->gitlab->delete = 'Delete GitLab';
$lang->gitlab->confirmDelete = 'Do you want to delete this GitLab server?';
$lang->gitlab->gitlabAvatar = 'Avatar';
$lang->gitlab->gitlabAccount = 'GitLab Account';
$lang->gitlab->gitlabEmail = 'Email';
$lang->gitlab->gitlabEmail = 'GitLab User\'s Email';
$lang->gitlab->zentaoEmail = 'Zentao User\'s Email';
$lang->gitlab->zentaoAccount = 'Zentao Account';
$lang->gitlab->accountDesc = '(Automatically match users with the same email)';
$lang->gitlab->bindingStatus = 'Binding Status';
$lang->gitlab->all = 'All';
$lang->gitlab->notBind = 'Not bind';
$lang->gitlab->binded = 'Binded';
$lang->gitlab->bindedError = 'The bound user has been deleted or modified. Please bind again.';
+5 -2
View File
@@ -5,7 +5,7 @@ $lang->gitlab->search = 'Search';
$lang->gitlab->create = 'Create GitLab';
$lang->gitlab->edit = 'Edit GitLab';
$lang->gitlab->view = 'View GitLab';
$lang->gitlab->bindUser = 'Bind User';
$lang->gitlab->bindUser = 'Permission Setting';
$lang->gitlab->webhook = 'Webhook';
$lang->gitlab->bindProduct = "Import {$lang->productCommon}";
$lang->gitlab->importIssue = 'Import Issue';
@@ -13,9 +13,12 @@ $lang->gitlab->delete = 'Delete GitLab';
$lang->gitlab->confirmDelete = 'Do you want to delete this GitLab server?';
$lang->gitlab->gitlabAvatar = 'Avatar';
$lang->gitlab->gitlabAccount = 'GitLab Account';
$lang->gitlab->gitlabEmail = 'Email';
$lang->gitlab->gitlabEmail = 'GitLab User\'s Email';
$lang->gitlab->zentaoEmail = 'Zentao User\'s Email';
$lang->gitlab->zentaoAccount = 'Zentao Account';
$lang->gitlab->accountDesc = '(Automatically match users with the same email)';
$lang->gitlab->bindingStatus = 'Binding Status';
$lang->gitlab->all = 'All';
$lang->gitlab->notBind = 'Not bind';
$lang->gitlab->binded = 'Binded';
$lang->gitlab->bindedError = 'The bound user has been deleted or modified. Please bind again.';

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