Merge branch 'release/zentaopms_18.3' of https://gitlab.zcorp.cc/easycorp/zentaopms into release/zentaopms_18.3

This commit is contained in:
wangyidong
2023-03-29 08:28:20 +08:00
75 changed files with 860 additions and 624 deletions
+11
View File
File diff suppressed because one or more lines are too long
+9 -7
View File
File diff suppressed because one or more lines are too long
+37
View File
@@ -1 +1,38 @@
UPDATE `zt_doc` SET `type` = 'text' WHERE `type` = 'url';
UPDATE `zt_doclib` SET `acl` = 'private' WHERE `type` = 'custom' and `acl` = 'custom';
UPDATE `zt_doclib` SET `acl` = 'private' WHERE `type` = 'product' AND `acl` = 'custom';
UPDATE `zt_doclib` SET `acl` = 'private' WHERE `type` = 'project' AND `acl` = 'custom';
UPDATE `zt_doclib` SET `acl` = 'default' WHERE `type` = 'project' AND `acl` IN ('open', 'private');
UPDATE `zt_doclib` SET `acl` = 'private' WHERE `type` = 'api' and `acl` = 'custom';
UPDATE `zt_doclib` SET `acl` = 'default' WHERE `type` = 'api' and `acl` = 'open';
ALTER TABLE `zt_doclib` ADD `addedBy` varchar(30) NOT NULL AFTER `order`;
ALTER TABLE `zt_doclib` ADD `addedDate` datetime NOT NULL AFTER `addedBy`;
/* Update doc lib. */
UPDATE zt_doclib AS t1
INNER JOIN (SELECT * FROM zt_action WHERE `objectType` = 'doclib' AND `action` = 'created') AS t2 ON t1.`id` = t2.`objectID`
SET t1.`addedDate` = t2.`date`, t1.`addedBy` = t2.`actor`;
UPDATE zt_doclib AS t1
INNER JOIN (SELECT * FROM zt_action WHERE `objectType` = 'docLib' AND `action` = 'Created') AS t2 ON t1.`id` = t2.`objectID`
SET t1.`addedDate` = t2.`date`, t1.`addedBy` = t2.`actor`;
/* Update the product master library. */
UPDATE zt_doclib AS t1
INNER JOIN zt_product AS t2 ON t1.`product` = t2.`id`
SET t1.`addedDate` = t2.`createdDate`, t1.`addedBy` = t2.`createdBy`
WHERE t1.`type` = 'product' AND t1.`main` = '1';
/* Update the project master library. */
UPDATE zt_doclib AS t1
INNER JOIN zt_project AS t2 ON t1.`project` = t2.`id`
SET t1.`addedDate` = t2.`openedDate`, t1.`addedBy` = t2.`openedBy`
WHERE t1.`type` = 'project' AND t1.`main` = '1';
/* Update the execution master library. */
UPDATE zt_doclib AS t1
INNER JOIN zt_project AS t2 ON t1.`execution` = t2.`id`
SET t1.`addedDate` = t2.`openedDate`, t1.`addedBy` = t2.`openedBy`
WHERE t1.`type` = 'execution' AND t1.`main` = '1';
-1
View File
@@ -296,7 +296,6 @@ class router extends baseRouter
$productProject = $productProject->value;
list($productCommon, $projectCommon) = explode('_', $productProject);
$lang->productCommon = isset($this->config->productCommonList[$this->clientLang][(int)$productCommon]) ? $this->config->productCommonList[$this->clientLang][(int)$productCommon] : $this->config->productCommonList['en'][0];
$lang->projectCommon = isset($this->config->projectCommonList[$this->clientLang][(int)$projectCommon]) ? $this->config->projectCommonList[$this->clientLang][(int)$projectCommon] : $this->config->projectCommonList['en'][0];
}
if(!defined('IN_UPGRADE'))
{
+2 -2
View File
@@ -2,10 +2,10 @@
$config->api = new stdClass();
$config->api->createlib = new stdclass();
$config->api->createlib->requiredFields = 'name';
$config->api->createlib->requiredFields = 'name,baseUrl';
$config->api->editlib = new stdclass();
$config->api->editlib->requiredFields = 'name';
$config->api->editlib->requiredFields = 'name,baseUrl';
$config->api->struct = new stdClass();
$config->api->struct->requiredFields = 'name,params';
+24 -25
View File
@@ -333,26 +333,27 @@ class api extends control
* @access public
* @return void
*/
public function createLib($type = 'normal')
public function createLib($type = 'product')
{
if(!empty($_POST))
{
$libID = $type == 'demo' ? $this->api->createDemoData($this->post->name, $this->post->baseUrl) : $this->doc->createApiLib();
if(dao::isError()) return $this->sendError(dao::getError());
/* If the created api library of imported zentao api library, return directly. */
if($type == 'demo') return $this->sendSuccess(array('locate' => $this->createLink('api', 'index', "libID=$libID")));
$libID = $this->doc->createApiLib();
if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
/* Record action for create api library. */
$this->action->create('docLib', $libID, 'Created');
$this->action->create('doclib', $libID, 'created');
if(!helper::isAjaxRequest()) return print(js::locate($this->createLink('api', 'index', "libID=$libID"), 'parent.parent'));
return $this->sendSuccess(array('locate' => $this->createLink('api', 'index', "libID=$libID")));
return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => $this->createLink('api', 'index', "libID=$libID")));
}
$this->view->type = $type;
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->users = $this->user->getPairs('nocode|noclosed');
$this->lang->api->aclList['default'] = sprintf($this->lang->doclib->aclList['default'], $this->lang->{$type}->common);
$this->view->type = $type;
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->users = $this->user->getPairs('nocode|noclosed');
$this->view->projects = $this->loadModel('project')->getPairsByModel();
$this->view->products = $this->loadModel('product')->getPairs();
$this->display();
}
@@ -366,28 +367,26 @@ class api extends control
*/
public function editLib($id)
{
$doc = $this->doc->getLibById($id);
$lib = $this->doc->getLibById($id);
if(!empty($_POST))
{
$lib = fixer::input('post')->join('groups', ',')->join('users', ',')->get();
if($lib->acl == 'private') $lib->users = $this->app->user->account;
$this->doc->updateApiLib($id, $doc, $lib);
$this->doc->updateApiLib($id);
if(dao::isError()) return $this->sendError(dao::getError());
$res = array(
'message' => $this->lang->saveSuccess,
'closeModal' => true,
'callback' => "redirectParentWindow($id)",
);
return $this->sendSuccess($res);
return $this->sendSuccess(array('message' => $this->lang->saveSuccess, 'closeModal' => true, 'callback' => "redirectParentWindow($id)"));
}
$this->view->doc = $doc;
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->users = $this->user->getPairs('nocode|noclosed');
$type = !empty($lib->product) ? 'product' : 'project';
$this->lang->api->aclList['default'] = sprintf($this->lang->doclib->aclList['default'], $this->lang->{$type}->common);
$this->view->lib = $lib;
$this->view->type = $type;
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->users = $this->user->getPairs('nocode|noclosed');
$this->view->projects = $this->loadModel('project')->getPairsByModel();
$this->view->products = $this->loadModel('product')->getPairs();
$this->display();
}
+2
View File
@@ -100,3 +100,5 @@ ol, ul {margin-bottom: 0}
form .table-data, #content .table-data {border: 1px solid #e2e2e3;}
.table-data thead {background: #f9f9f9;}
#aclBox .acl-tip {color: #838a9d;}
+4 -2
View File
@@ -47,7 +47,7 @@
.article-content.comment {width: 100% !important;}
.cell .detail .detail-title {padding-left: 5px; list-style: none;}
.menu-actions {position: absolute; top: 7px; right: 45px; padding: 7px 8px;}
.menu-actions {top: 5px!important; right: 45px;}
.no-content {width: 100px; height: 100px; margin: 0 auto;}
.notice {text-align: center; padding-left: 15px; padding-top: 20px;}
.no-content-button {text-align: center; padding-top: 20px;}
@@ -65,6 +65,8 @@
.tree-actions a {display: inline-block; margin-left: 5px; font-size: 13px; opacity: .6;}
.tree li.active > .tree-group a {font-weight: 700; color: #0c64eb;}
.base-url {background: #f3f3f3; margin: 0; border-top: 1px solid #eee;}
.base-url {margin: 0; border-bottom: 1px solid #eee;}
.base-url > p {margin: 0; padding-left: 20px; color: black;}
.detail+.detail {border-top: 0px;}
.menu-title {display: flex; align-items: center; justify-content: space-between;}
.vision-drop.dropdown {padding-right: 35px;}
+23 -10
View File
@@ -19,23 +19,36 @@ function loadDocModule(libID)
*/
function toggleAcl(acl, type)
{
if(acl == 'custom')
{
$('#whiteListBox').removeClass('hidden');
}
else
if(acl == 'open')
{
$('#whiteListBox').addClass('hidden');
}
if(type == 'lib')
else
{
var notice = typeof(noticeAcl[acl]) != 'undefined' ? noticeAcl[acl] : '';
$('#noticeAcl').html(notice);
$('#whiteListBox').removeClass('hidden');
}
}
/**
* Toggle lib type.
*
* @param string $libType
* @access public
* @return void
*/
function toggleLibType(libType)
{
if(libType == 'project')
{
$('#projectBox').removeClass('hidden');
$('#productBox').addClass('hidden');
$('#acldefault').next('.acl-tip').html($('#acldefault').next('.acl-tip').html().replace(productLang, projectLang));
}
else
{
var notice = typeof(noticeAcl[acl]) != 'undefined' ? noticeAcl[acl] : '';
$('#noticeAcl').html(notice);
$('#projectBox').addClass('hidden');
$('#productBox').removeClass('hidden');
$('#acldefault').next('.acl-tip').html($('#acldefault').next('.acl-tip').html().replace(projectLang, productLang));
}
}
+1 -1
View File
@@ -10,4 +10,4 @@ $(document).ready(function()
}
}
})
});
});
+11 -3
View File
@@ -64,9 +64,9 @@ $lang->api->allLibs = "AllLibs";
/* Common access control lang. */
$lang->api->whiteList = 'Whitelist';
$lang->api->aclList['open'] = 'Open';
$lang->api->aclList['private'] = 'Private';
$lang->api->aclList['custom'] = 'Custom';
$lang->api->aclList['open'] = "Public <span class='acl-tip'>(Users who can access doccan access it)</span>";
$lang->api->aclList['default'] = "Default <span class='acl-tip'>(Users who can access the selected %s or users in the whiltelist can access it)</span>";
$lang->api->aclList['private'] = "Private <span class='acl-tip'> (Only the one who created it or users in the whiltelist can access it)</span>";
$lang->api->group = 'Group';
$lang->api->user = 'User';
@@ -148,6 +148,10 @@ $lang->api->default = 'Default';
$lang->api->desc = 'Beschreibung';
$lang->api->customType = 'Custom Structure';
$lang->api->format = 'Format';
$lang->api->libType = 'Api Library Type';
$lang->api->product = $lang->productCommon;
$lang->api->project = $lang->projectCommon;
$lang->api->methodOptions = array(
'GET' => 'GET',
'POST' => 'POST',
@@ -169,6 +173,10 @@ $lang->api->requestTypeOptions['application/json'] = 'applicati
$lang->api->requestTypeOptions['application/x-www-form-urlencoded'] = 'application/x-www-form-urlencoded';
$lang->api->requestTypeOptions['multipart/form-data'] = 'multipart/form-data';
$lang->api->libTypeList = array();
$lang->api->libTypeList['product'] = $lang->productCommon . ' Api Library';
$lang->api->libTypeList['project'] = $lang->projectCommon . ' Api Library';
$lang->api->statusOptions = array(
'done' => 'Done',
'doing' => 'Doing',
+11 -3
View File
@@ -64,9 +64,9 @@ $lang->api->allLibs = "AllLibs";
/* Common access control lang. */
$lang->api->whiteList = 'Whitelist';
$lang->api->aclList['open'] = 'Open';
$lang->api->aclList['private'] = 'Private';
$lang->api->aclList['custom'] = 'Custom';
$lang->api->aclList['open'] = "Public <span class='acl-tip'>(Users who can access doccan access it)</span>";
$lang->api->aclList['default'] = "Default <span class='acl-tip'>(Users who can access the selected %s or users in the whiltelist can access it)</span>";
$lang->api->aclList['private'] = "Private <span class='acl-tip'> (Only the one who created it or users in the whiltelist can access it)</span>";
$lang->api->group = 'Group';
$lang->api->user = 'User';
@@ -148,6 +148,10 @@ $lang->api->default = 'Default';
$lang->api->desc = 'Description';
$lang->api->customType = 'Custom Structure';
$lang->api->format = 'Format';
$lang->api->libType = 'Api Library Type';
$lang->api->product = $lang->productCommon;
$lang->api->project = $lang->projectCommon;
$lang->api->methodOptions = array(
'GET' => 'GET',
'POST' => 'POST',
@@ -169,6 +173,10 @@ $lang->api->requestTypeOptions['application/json'] = 'applicati
$lang->api->requestTypeOptions['application/x-www-form-urlencoded'] = 'application/x-www-form-urlencoded';
$lang->api->requestTypeOptions['multipart/form-data'] = 'multipart/form-data';
$lang->api->libTypeList = array();
$lang->api->libTypeList['product'] = $lang->productCommon . ' Api Library';
$lang->api->libTypeList['project'] = $lang->projectCommon . ' Api Library';
$lang->api->statusOptions = array(
'done' => 'Done',
'doing' => 'Doing',
+11 -3
View File
@@ -64,9 +64,9 @@ $lang->api->allLibs = "AllLibs";
/* Common access control lang. */
$lang->api->whiteList = 'Whitelist';
$lang->api->aclList['open'] = 'Open';
$lang->api->aclList['private'] = 'Private';
$lang->api->aclList['custom'] = 'Custom';
$lang->api->aclList['open'] = "Public <span class='acl-tip'>(Users who can access doccan access it)</span>";
$lang->api->aclList['default'] = "Default <span class='acl-tip'>(Users who can access the selected %s or users in the whiltelist can access it)</span>";
$lang->api->aclList['private'] = "Private <span class='acl-tip'> (Only the one who created it or users in the whiltelist can access it)</span>";
$lang->api->group = 'Group';
$lang->api->user = 'User';
@@ -148,6 +148,10 @@ $lang->api->default = 'Default';
$lang->api->desc = 'Description';
$lang->api->customType = 'Custom Structure';
$lang->api->format = 'Format';
$lang->api->libType = 'Api Library Type';
$lang->api->product = $lang->productCommon;
$lang->api->project = $lang->projectCommon;
$lang->api->methodOptions = array(
'GET' => 'GET',
'POST' => 'POST',
@@ -169,6 +173,10 @@ $lang->api->requestTypeOptions['application/json'] = 'applicati
$lang->api->requestTypeOptions['application/x-www-form-urlencoded'] = 'application/x-www-form-urlencoded';
$lang->api->requestTypeOptions['multipart/form-data'] = 'multipart/form-data';
$lang->api->libTypeList = array();
$lang->api->libTypeList['product'] = $lang->productCommon . ' Api Library';
$lang->api->libTypeList['project'] = $lang->projectCommon . ' Api Library';
$lang->api->statusOptions = array(
'done' => 'Done',
'doing' => 'Doing',
+13 -5
View File
@@ -64,9 +64,9 @@ $lang->api->allLibs = "全部接口库";
/* Common access control lang. */
$lang->api->whiteList = '白名单';
$lang->api->aclList['open'] = '公开';
$lang->api->aclList['private'] = '私有';
$lang->api->aclList['custom'] = '自定义';
$lang->api->aclList['open'] = "公开 <span class='acl-tip'>(有文档视图权限即可访问)</span>";
$lang->api->aclList['default'] = "默认 <span class='acl-tip'>(有所选%s访问权限用户和白名单用户可以访问)</span>";
$lang->api->aclList['private'] = "私有 <span class='acl-tip'>(仅创建者和白名单用户可访问)</span>";
$lang->api->group = '分组';
$lang->api->user = '用户';
@@ -102,8 +102,8 @@ $lang->api->structType = '类型';
$lang->api->structAttr = '属性';
$lang->api->structAddedBy = '创建人';
$lang->api->structAddedDate = '创建时间';
$lang->api->name = '接口库名称';
$lang->api->baseUrl = '请求基路径';
$lang->api->name = '库名称';
$lang->api->baseUrl = '请求基础路径';
$lang->api->baseUrlDesc = '网址或者路径,比如 test.zentao.net 或者 /v1';
$lang->api->desc = '描述';
$lang->api->control = '访问控制';
@@ -148,6 +148,10 @@ $lang->api->default = '默认值';
$lang->api->desc = '描述';
$lang->api->customType = '自定义结构';
$lang->api->format = '格式化';
$lang->api->libType = '接口库类型';
$lang->api->product = '所属' . $lang->productCommon;
$lang->api->project = '所属' . $lang->projectCommon;
$lang->api->methodOptions = array(
'GET' => 'GET',
'POST' => 'POST',
@@ -169,6 +173,10 @@ $lang->api->requestTypeOptions['application/json'] = 'applicati
$lang->api->requestTypeOptions['application/x-www-form-urlencoded'] = 'application/x-www-form-urlencoded';
$lang->api->requestTypeOptions['multipart/form-data'] = 'multipart/form-data';
$lang->api->libTypeList = array();
$lang->api->libTypeList['product'] = $lang->productCommon . '接口库';
$lang->api->libTypeList['project'] = $lang->projectCommon . '接口库';
$lang->api->statusOptions = array(
'done' => '开发完成',
'doing' => '开发中',
+28 -28
View File
@@ -938,7 +938,7 @@ class apiModel extends model
*
* @param string $libID
* @param int $queryID
* @param int $objectType product|project
* @param string $objectType product|project
* @param array $libs
* @access public
* @return array
@@ -947,35 +947,35 @@ class apiModel extends model
{
$queryName = $objectType ? $objectType . 'apiDocQuery' : 'apiQuery';
$queryForm = $objectType ? $objectType . 'apiDocForm' : 'apiForm';
if($queryID)
{
$query = $this->loadModel('search')->getQuery($queryID);
if($query)
{
$this->session->set($queryName, $query->sql);
$this->session->set($queryForm, $query->form);
}
else
{
$this->session->set($queryName, ' 1 = 1');
}
}
else
{
if($this->session->$queryName == false) $this->session->set($queryName, ' 1 = 1');
}
if($queryID)
{
$query = $this->loadModel('search')->getQuery($queryID);
if($query)
{
$this->session->set($queryName, $query->sql);
$this->session->set($queryForm, $query->form);
}
else
{
$this->session->set($queryName, ' 1 = 1');
}
}
else
{
if($this->session->$queryName == false) $this->session->set($queryName, ' 1 = 1');
}
$apiQuery = $this->session->$queryName;
if(strpos($apiQuery, "`lib` = 'all'") === false and !$objectType) $apiQuery = "$apiQuery and lib = $libID";
if(strpos($apiQuery, "`lib` = 'all'") !== false) $apiQuery = str_replace("`lib` = 'all'", '1', $apiQuery);
$apiQuery = $this->session->$queryName;
if(strpos($apiQuery, "`lib` = 'all'") === false and !$objectType) $apiQuery = "$apiQuery and lib = $libID";
if(strpos($apiQuery, "`lib` = 'all'") !== false) $apiQuery = str_replace("`lib` = 'all'", '1', $apiQuery);
$list = $this->dao->select('*')
->from(TABLE_API)
->where('deleted')->eq(0)
->andWhere($apiQuery)
->beginIF(!empty($libs))->andWhere('`lib`')->in($libs)->fi()
->fetchAll();
$list = $this->dao->select('*')
->from(TABLE_API)
->where('deleted')->eq(0)
->andWhere($apiQuery)
->beginIF(!empty($libs))->andWhere('`lib`')->in($libs)->fi()
->fetchAll();
return $list;
return $list;
}
}
+2 -1
View File
@@ -1,4 +1,5 @@
<style>
.base-url {margin: 0; border-bottom: 1px solid #eee;}
.table-empty-tip > div {display: inline-block;}
.detail .list-group-item .heading.GET {
background-color: #e7f0f7;
@@ -80,7 +81,7 @@
<div class="detail">
<li class="detail-title"><?php echo intval($libID) > 0 ? $lang->api->apiList : $lang->api->pageTitle;?></li>
</div>
<div class="detail table-empty-tip">
<div class="table-empty-tip">
<div class="notice text-muted"><?php echo (empty($libs)) ? $lang->api->noLib : $lang->api->noApi;?></div>
<div class="no-content-button">
<?php
+29 -11
View File
@@ -18,29 +18,45 @@
<div id='mainContent' class='main-content'>
<div class='center-block'>
<div class='main-header'>
<h2><?php echo $type == 'normal' ? $lang->api->createLib : $lang->api->createDemo;?></h2>
<h2><?php echo $lang->api->createLib;?></h2>
</div>
<form class='load-indicator main-form' id="apiForm" method='post' enctype='multipart/form-data'>
<table class='table table-form'>
<tr>
<th><?php echo $lang->api->libType;?></th>
<td>
<span><?php echo html::radio('libType', $lang->api->libTypeList, $type, "onchange='toggleLibType(this.value)'")?></span>
</td>
</tr>
<tr id='productBox'>
<th><?php echo $lang->api->product;?></th>
<td class='required'>
<span><?php echo html::select('product', $products, 0, "class='form-control chosen'")?></span>
</td>
</tr>
<tr id='projectBox' class='hidden'>
<th><?php echo $lang->api->project;?></th>
<td class='required'>
<span><?php echo html::select('project', $projects, 0, "class='form-control chosen'")?></span>
</td>
</tr>
<tr>
<th><?php echo $lang->api->name?></th>
<td style="width: 80%"><?php echo html::input('name', $type == 'demo' ? $lang->api->zentaoAPI : '', "class='form-control'")?></td>
<td style="width: 80%"><?php echo html::input('name', '', "class='form-control'")?></td>
</tr>
<tr>
<th><?php echo $lang->api->baseUrl?></th>
<td style="width: 80%"><?php echo html::input('baseUrl', $type == 'demo' ? ('http://' . $_SERVER['HTTP_HOST'] . $this->app->config->webRoot . 'api.php/v1') : '', "class='form-control' placeholder='" . $lang->api->baseUrlDesc . "'");?></td>
<td style="width: 80%"><?php echo html::input('baseUrl', '', "class='form-control' placeholder='" . $lang->api->baseUrlDesc . "'");?></td>
</tr>
<tr>
<tr id='aclBox'>
<th><?php echo $lang->api->control;?></th>
<td>
<?php $isDisabled = $type == 'demo' ? 'disabled' : '';?>
<span><?php echo html::radio('acl', $lang->api->aclList, 'open', "onchange='toggleAcl(this.value, \"lib\")' $isDisabled")?></span>
<span class='text-info' id='noticeAcl'><?php echo $lang->api->noticeAcl['open'];?></span>
<td colspan='2'>
<span><?php echo html::radio('acl', $lang->api->aclList, 'open', "onchange='toggleAcl(this.value, \"lib\")'", 'block');?></span>
</td>
</tr>
<tr id='whiteListBox' class='hidden'>
<th><?php echo $lang->api->whiteList;?></th>
<td>
<td colspan='2'>
<div class='input-group'>
<span class='input-group-addon groups-addon'><?php echo $lang->api->group?></span>
<?php echo html::select('groups[]', $groups, '', "class='form-control chosen' multiple")?>
@@ -48,13 +64,14 @@
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->api->user?></span>
<?php echo html::select('users[]', $users, '', "class='form-control chosen' multiple")?>
<?php echo $this->fetch('my', 'buildContactLists', "dropdownName=users&attr=data-drop_direction='up'");?>
</div>
</td>
</tr>
<tr>
<th><?php echo $lang->api->desc;?></th>
<td colspan='2'>
<?php echo html::textarea('desc', '', "rows='8' class='form-control kindeditor' hidefocus='true' tabindex=''");?>
<?php echo html::textarea('desc', '', "rows='8' class='form-control kindeditor' hidefocus='true' tabindex=''");?>
</td>
</tr>
<tr>
@@ -66,5 +83,6 @@
</div>
</div>
</div>
<?php js::set('noticeAcl', $lang->api->noticeAcl);?>
<?php js::set('productLang', $lang->productCommon);?>
<?php js::set('projectLang', $lang->projectCommon);?>
<?php include '../../common/view/footer.lite.html.php';?>
+30 -28
View File
@@ -22,38 +22,56 @@
</div>
<form class='load-indicator main-form form-ajax' id="apiForm" method='post' enctype='multipart/form-data'>
<table class='table table-form'>
<tr>
<th><?php echo $lang->api->libType;?></th>
<td>
<span><?php echo html::radio('libType', $lang->api->libTypeList, $type, "onchange='toggleLibType(this.value)'")?></span>
</td>
</tr>
<tr id='productBox' class='<?php echo $type != 'product' ? 'hidden' : '';?>'>
<th><?php echo $lang->api->product;?></th>
<td>
<span><?php echo html::select('product', $products, $lib->product, "class='form-control chosen'")?></span>
</td>
</tr>
<tr id='projectBox' class='<?php echo $type != 'project' ? 'hidden' : '';?>'>
<th><?php echo $lang->api->project;?></th>
<td>
<span><?php echo html::select('project', $projects, $lib->project, "class='form-control chosen'")?></span>
</td>
</tr>
<tr>
<th><?php echo $lang->api->name?></th>
<td style="width: 80%"><?php echo html::input('name', $doc->name, "class='form-control'");?></td>
<td style="width: 80%"><?php echo html::input('name', $lib->name, "class='form-control'");?></td>
</tr>
<tr>
<th><?php echo $lang->api->baseUrl?></th>
<td style="width: 80%"><?php echo html::input('baseUrl', $doc->baseUrl, "class='form-control'");?></td>
<td style="width: 80%"><?php echo html::input('baseUrl', $lib->baseUrl, "class='form-control'");?></td>
</tr>
<tr>
<tr id='aclBox'>
<th><?php echo $lang->api->control;?></th>
<td>
<span><?php echo html::radio('acl', $lang->api->aclList, $doc->acl, "onchange='toggleAcl(this.value, \"lib\")'")?></span>
<span class='text-info' id='noticeAcl'><?php echo $lang->api->noticeAcl['open'];?></span>
<span><?php echo html::radio('acl', $lang->api->aclList, $lib->acl, "onchange='toggleAcl(this.value, \"lib\")'", 'block')?></span>
</td>
</tr>
<tr id='whiteListBox' class='<?php echo $doc->acl == 'custom' ? '' : 'hidden';?>'>
<tr id='whiteListBox' class='<?php echo $lib->acl != 'open' ? '' : 'hidden';?>'>
<th><?php echo $lang->api->whiteList;?></th>
<td>
<td colspan='2'>
<div class='input-group'>
<span class='input-group-addon groups-addon'><?php echo $lang->api->group?></span>
<?php echo html::select('groups[]', $groups, $doc->groups, "class='form-control chosen' multiple");?>
<?php echo html::select('groups[]', $groups, $lib->groups, "class='form-control chosen' multiple");?>
</div>
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->api->user?></span>
<?php echo html::select('users[]', $users, $doc->users, "class='form-control chosen' multiple");?>
<?php echo html::select('users[]', $users, $lib->users, "class='form-control chosen' multiple");?>
<?php echo $this->fetch('my', 'buildContactLists', "dropdownName=users&attr=data-drop_direction='up'");?>
</div>
</td>
</tr>
<tr>
<th><?php echo $lang->api->desc;?></th>
<td colspan='2'>
<?php echo html::textarea('desc', $doc->desc, "rows='8' class='form-control kindeditor' hidefocus='true' tabindex=''");?>
<?php echo html::textarea('desc', $lib->desc, "rows='8' class='form-control kindeditor' hidefocus='true' tabindex=''");?>
</td>
</tr>
<tr>
@@ -65,22 +83,6 @@
</div>
</div>
</div>
<div class='hidden'>
<table>
<tr id='aclBoxA'>
<th><?php echo $lang->api->control;?></th>
<td>
<?php echo html::radio('acl', $lang->api->aclListA, 'default', "onchange='toggleAcl(this.value, \"lib\")'");?>
</td>
</tr>
<tr id='aclBoxB'>
<th><?php echo $lang->api->control;?></th>
<td><?php echo html::radio('acl', $lang->api->aclListB, 'open', "onchange='toggleAcl(this.value, \"lib\")'");?></td>
</tr>
</table>
</div>
<?php js::set('noticeAcl', $lang->api->noticeAcl);?>
<script>
$(function(){toggleAcl($('form input[name="acl"]:checked').val(), 'lib');})
</script>
<?php js::set('productLang', $lang->productCommon);?>
<?php js::set('projectLang', $lang->projectCommon);?>
<?php include '../../common/view/footer.lite.html.php';?>
+11 -2
View File
@@ -17,9 +17,18 @@
<?php if($libID):?>
<?php $sideWidth = common::checkNotCN() ? '270' : '238';?>
<div class="side-col" style="width:<?php echo $sideWidth;?>px" data-min-width="<?php echo $sideWidth;?>">
<div class="cell" style="min-height: 286px">
<div class="cell" style="min-height: 286px; overflow: visible;">
<div id='title'>
<li class='menu-title'><?php echo $this->lang->api->module;?></li>
<li class='menu-title'>
<div class="title"><?php echo $this->lang->api->module;?></div>
<div class="dropdown vision-drop">
<button data-toggle="dropdown" class="btn btn-link">v-1.43</button>
<ul class="dropdown-menu">
<li><a>1.43</a></li>
<li><a>1.44</a></li>
</ul>
</div>
</li>
<?php
$canTreeBrowse = common::hasPriv('tree', 'browse');
$canViewReleases = common::hasPriv('api', 'releases');
+55 -49
View File
@@ -136,7 +136,7 @@ class commonModel extends model
*
* @param object $execution
* @access public
* @return object $parentExecution
* @return object|false $parentExecution
*/
public function syncExecutionByChild($execution)
{
@@ -1474,15 +1474,20 @@ class commonModel extends model
echo "<li class='dropdown-submenu' id='downloadMobile'><a href='javascript:;'>" . $lang->downloadMobile . "</a><ul class='dropdown-menu pull-left''>";
/* Intranet users use local pictures. */
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://www.zentao.net/page/appqrcode.json');
curl_setopt($curl, CURLOPT_TIMEOUT_MS, 200);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT_MS, 200);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
$connected = curl_exec($curl);
curl_close($curl);
$connected = false;
if(extension_loaded('curl'))
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://www.zentao.net/page/appqrcode.json');
curl_setopt($curl, CURLOPT_TIMEOUT_MS, 200);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT_MS, 200);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
$connected = curl_exec($curl);
curl_close($curl);
}
if($connected)
{
echo "<li><div class='mobile-qrcode'><iframe src='https://www.zentao.net/page/appqrcode.html?v={$config->version}' frameborder='0' scrolling='no' seamless></iframe></div></li>";
@@ -1557,7 +1562,7 @@ class commonModel extends model
}
else
{
$orderBy = "" . trim($fieldName, '`') . "" . '_' . 'asc';
$orderBy = trim($fieldName, '`') . '_' . 'asc';
$className = 'header';
}
@@ -1569,10 +1574,9 @@ class commonModel extends model
}
/**
* Print link to a module's method.
*
* Print link to an modules' methd.
*
* Before printing, check the privilege first. If no privilege, return fasle. Else, print the link, return true.
* Before printing, check the privilege first. If no privilege, return false. Else, print the link, return true.
*
* @param string $module the module name
* @param string $method the method
@@ -1629,7 +1633,7 @@ class commonModel extends model
if(!commonModel::hasPriv('action', 'comment', $object)) return false;
echo html::commonButton('<i class="icon icon-chat-line"></i> ' . $lang->action->create, '', 'btn btn-link pull-right btn-comment');
echo <<<EOD
echo <<<EOF
<div class="modal fade modal-comment">
<div class="modal-dialog">
<div class="modal-content">
@@ -1658,7 +1662,7 @@ $(function()
if(\$body.hasClass('hide-modal-close')) \$body.removeClass('hide-modal-close');
});
</script>
EOD;
EOF;
}
/**
@@ -2143,9 +2147,9 @@ EOD;
* Get the previous and next object.
*
* @param string $type story|task|bug|case
* @param string $objectID
* @param int $objectID
* @access public
* @return void
* @return object
*/
public function getPreAndNextObject($type, $objectID)
{
@@ -2267,6 +2271,7 @@ EOD;
*
* @param string $sql
* @param string $objectType story|task|bug|testcase
* @param bool $onlyCondition
* @access public
* @return void
*/
@@ -2836,7 +2841,7 @@ EOD;
/**
* Check whether view type is tutorial
* @access public
* @return boolean
* @return bool
*/
public static function isTutorialMode()
{
@@ -3095,23 +3100,23 @@ EOD;
/**
* Response.
*
* @param string $code
* @param string $reasonPhrase
* @access public
* @return void
*/
public function response($code)
public function response($reasonPhrase)
{
$response = new stdclass();
if(isset($this->config->entry->errcode))
{
$response->errcode = $this->config->entry->errcode[$code];
$response->errmsg = urlencode($this->lang->entry->errmsg[$code]);
$response->errcode = $this->config->entry->errcode[$reasonPhrase];
$response->errmsg = urlencode($this->lang->entry->errmsg[$reasonPhrase]);
die(urldecode(json_encode($response)));
}
else
{
$response->error = $code;
$response->error = $reasonPhrase;
die(urldecode(json_encode($response)));
}
}
@@ -3120,10 +3125,10 @@ EOD;
/**
* Http response with header.
*
* @param string $url
* @param string|array $data
* @param array $options This is option and value pair, like CURLOPT_HEADER => true. Use curl_setopt function to set options.
* @param array $headers Set request headers.
* @param string $url
* @param string|array|object $data
* @param array $options This is option and value pair, like CURLOPT_HEADER => true. Use curl_setopt function to set options.
* @param array $headers Set request headers.
* @static
* @access public
* @return string
@@ -3140,16 +3145,16 @@ EOD;
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($curl, CURLOPT_USERAGENT, 'Sae T OAuth2 v0.1');
curl_setopt($curl, CURLOPT_USERAGENT, 'ZenTao PMS ' . $app->config->version);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_ENCODING, "");
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_ENCODING, '');
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($curl, CURLINFO_HEADER_OUT, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_URL, $url);
@@ -3175,8 +3180,8 @@ EOD;
{
$field = explode(':', $item);
if(count($field) < 2) continue;
$headerkey = array_shift($field);
$newHeader[$headerkey] = join('', $field);
$headerKey = array_shift($field);
$newHeader[$headerKey] = join('', $field);
}
curl_close($curl);
@@ -3240,17 +3245,17 @@ EOD;
$curl = curl_init();
curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($curl, CURLOPT_USERAGENT, 'Sae T OAuth2 v0.1');
curl_setopt($curl, CURLOPT_USERAGENT, 'ZenTao PMS ' . $app->config->version);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_ENCODING, "");
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_setopt($curl, CURLOPT_HEADER, FALSE);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 2);
curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE);
curl_setopt($curl, CURLINFO_HEADER_OUT, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
curl_setopt($curl, CURLOPT_URL, $url);
@@ -3357,13 +3362,13 @@ EOD;
/**
* Get relations for two object.
*
* @param varchar $atype
* @param int $aid
* @param varchar $btype
* @param int $bid
* @param string $AType
* @param int $AID
* @param string $BType
* @param int $BID
*
* @access public
* @return string
* @return array
*/
public function getRelations($AType = '', $AID = 0, $BType = '', $BID = 0)
{
@@ -3386,7 +3391,7 @@ EOD;
* @param array $params
*
* @access public
* @return string
* @return void
*/
static public function setMenuVars($moduleName, $objectID, $params = array())
{
@@ -3463,8 +3468,9 @@ EOD;
}
}
/*
/**
* Replace the %s of one key of a menu by objectID or $params.
*
* @param object $menu
* @param int $objectID
* @param array $params
+2
View File
@@ -30,6 +30,8 @@ $lang->company->guest = 'Gast Login';
$lang->company->admins = 'Administratoren';
$lang->company->deleted = 'Deleted';
$lang->company->manageRole = 'Role setting';
$lang->company->product = $lang->productCommon;
$lang->company->project = $lang->projectCommon;
$lang->company->execution = 'Execution';
+2
View File
@@ -30,6 +30,8 @@ $lang->company->guest = 'Guest Login';
$lang->company->admins = 'Administrator';
$lang->company->deleted = 'Deleted';
$lang->company->manageRole = 'Role setting';
$lang->company->product = $lang->productCommon;
$lang->company->project = $lang->projectCommon;
$lang->company->execution = $lang->executionCommon;
+2
View File
@@ -30,6 +30,8 @@ $lang->company->guest = 'Connexion Invités';
$lang->company->admins = 'Administrateur';
$lang->company->deleted = 'Deleted';
$lang->company->manageRole = 'Role setting';
$lang->company->product = $lang->productCommon;
$lang->company->project = $lang->projectCommon;
$lang->company->execution = $lang->executionCommon;
+2
View File
@@ -30,6 +30,8 @@ $lang->company->guest = '匿名登录';
$lang->company->admins = '管理员';
$lang->company->deleted = '已删除';
$lang->company->manageRole = '维护职位';
$lang->company->product = $lang->productCommon;
$lang->company->project = $lang->projectCommon;
$lang->company->execution = $lang->executionCommon;
+3
View File
@@ -36,6 +36,9 @@ js::set('confirmDelete', $lang->user->confirmDelete);
echo html::a($link, "<i class='icon icon-plus'></i> {$lang->user->create}", '', "class='btn btn-primary create-user-btn'");
?>
<?php else:?>
<?php if(common::hasPriv('custom', 'set')):?>
<?php common::printLink('custom', 'set', "module=user&field=roleList", "<i class='icon icon-cog-outline'></i> " . $lang->company->manageRole, '', "class='btn btn-link'");?>
<?php endif;?>
<?php if(common::hasPriv('user', 'create') and common::hasPriv('user', 'batchCreate')):?>
<?php
$createUserLink = $this->createLink('user', 'create', "dept={$deptID}");
+101 -46
View File
@@ -40,9 +40,6 @@ class doc extends control
$this->app->loadClass('pager', $static = true);
$pager = new pager(0, 5, 1);
$actionURL = $this->createLink('doc', 'browse', "lib=0&browseType=bySearch&queryID=myQueryID");
$this->doc->buildSearchForm(0, array(), 0, $actionURL, 'index');
$this->view->title = $this->lang->doc->common . $this->lang->colon . $this->lang->doc->index;
$this->view->position[] = $this->lang->doc->index;
@@ -132,16 +129,15 @@ class doc extends control
$libID = $this->doc->createlib();
if(!dao::isError())
{
$objectType = $this->post->type;
if($objectType == 'project' and $this->post->project) $objectID = $this->post->project;
if($objectType == 'product' and $this->post->product) $objectID = $this->post->product;
if($objectType == 'execution' and $this->post->execution) $objectID = $this->post->execution;
if($objectType == 'custom' or $objectType == 'book') $objectID = 0;
if($type == 'project' and $this->post->project) $objectID = $this->post->project;
if($type == 'product' and $this->post->product) $objectID = $this->post->product;
if($type == 'execution' and $this->post->execution) $objectID = $this->post->execution;
if($type == 'custom') $objectID = 0;
$this->action->create('docLib', $libID, 'Created');
if($this->viewType == 'json') return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'id' => $libID));
return print(js::locate($this->createLink('doc', 'tableContents', "type=$objectType&objectID=$objectID&libID=$libID"), 'parent.parent'));
return print(js::locate($this->createLink('doc', 'tableContents', "type=$type&objectID=$objectID&libID=$libID"), 'parent.parent'));
}
else
{
@@ -149,55 +145,66 @@ class doc extends control
}
}
$products = $this->product->getPairs();
$projects = $this->project->getPairsByProgram('', 'all', true);
$executions = $this->execution->getList();
if(in_array($type, array('product', 'project'))) $this->app->loadLang('api');
/* Splice project name. */
foreach($executions as $executionID => $execution)
$objects = array();
$executionPairs = array(0 => '');
if($type == 'product') $objects = $this->product->getPairs();
if($type == 'project')
{
if($execution->multiple)
$objects = $this->project->getPairsByProgram();
if($this->app->tab == 'doc')
{
if($execution->type == 'stage' and $execution->grade > 1)
{
$parentExecutions = $this->dao->select('id,name')->from(TABLE_EXECUTION)->where('id')->in(trim($execution->path, ','))->andWhere('type')->in('stage,kanban,sprint')->orderBy('grade')->fetchPairs();
$execution->name = implode('/', $parentExecutions);
}
$executionPrefix = isset($projects[$execution->project]) ? $projects[$execution->project] . '/' : '';
$executions[$executionID] = $executionPrefix . $execution->name;
}
else
{
unset($executions[$executionID]);
$executions = $this->execution->getList($objectID);
$this->view->project = $this->project->getById($objectID);
}
}
if($type == 'execution')
{
$executions = $this->execution->getList();
$projects = $this->project->getPairsByProgram('', 'all', true);
}
/* Get the project that has permission to view. */
foreach($projects as $projectID => $project) if(!$this->app->user->admin and strpos(',' . $this->app->user->view->projects . ',', ',' . $projectID . ',') === false) unset($projects[$projectID]);
/* Splice project name. */
if(!empty($executions))
{
foreach($executions as $id => $execution)
{
if($execution->multiple)
{
if($execution->type == 'stage' and $execution->grade > 1)
{
$parentExecutions = $this->dao->select('id,name')->from(TABLE_EXECUTION)->where('id')->in(trim($execution->path, ','))->andWhere('type')->in('stage,kanban,sprint')->orderBy('grade')->fetchPairs();
$execution->name = implode('/', $parentExecutions);
}
$executionPrefix = isset($projects[$execution->project]) ? $projects[$execution->project] . '/' : '';
$executionPairs[$id] = $executionPrefix . $execution->name;
}
}
if($type == 'executions') $objects = $executionPairs;
}
if($type == 'execution')
{
$execution = $this->execution->getByID($objectID);
if($execution->type == 'stage') $this->lang->doc->execution = str_replace($this->lang->executionCommon, $this->lang->project->stage, $this->lang->doc->execution);
if($execution->type == 'stage') $this->lang->doc->libTypeList['execution'] = str_replace($this->lang->executionCommon, $this->lang->project->stage, $this->lang->doc->libTypeList['execution']);
}
$libTypeList = $this->lang->doc->libTypeList;
if(empty($products)) unset($libTypeList['product']);
if(empty($projects)) unset($libTypeList['project']);
if(empty($executions)) unset($libTypeList['execution']);
if($type == 'custom') unset($this->lang->doclib->aclList['default']);
if($type != 'custom')
{
$this->lang->doclib->aclList['default'] = sprintf($this->lang->doclib->aclList['default'], $this->lang->{$type}->common);
$this->lang->doclib->aclList['private'] = sprintf($this->lang->doclib->privateACL, $this->lang->{$type}->common);
unset($this->lang->doclib->aclList['open']);
}
$this->app->loadLang('api');
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->users = $this->user->getPairs('nocode|noclosed');
$this->view->products = $products;
$this->view->projects = $projects;
$this->view->executions = $executions;
$this->view->type = $type;
$this->view->libTypeList = $libTypeList;
$this->view->objectID = $objectID;
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->users = $this->user->getPairs('nocode|noclosed');
$this->view->objects = $objects;
$this->view->executionPairs = $executionPairs;
$this->view->type = $type;
$this->view->objectID = $objectID;
$this->display();
}
@@ -258,6 +265,15 @@ class doc extends control
$this->view->execution = $execution;
}
if($lib->type == 'custom') unset($this->lang->doclib->aclList['default']);
if($lib->type != 'custom')
{
$this->lang->doclib->aclList['default'] = sprintf($this->lang->doclib->aclList['default'], $this->lang->{$lib->type}->common);
$this->lang->doclib->aclList['private'] = sprintf($this->lang->doclib->privateACL, $this->lang->{$lib->type}->common);
unset($this->lang->doclib->aclList['open']);
}
$this->view->lib = $lib;
$this->view->groups = $this->loadModel('group')->getPairs();
$this->view->users = $this->user->getPairs('noletter|noclosed', $lib->users);
@@ -276,7 +292,7 @@ class doc extends control
* @access public
* @return void
*/
public function deleteLib($libID, $confirm = 'no', $type = 'lib', $from = 'objectLibs')
public function deleteLib($libID, $confirm = 'no', $type = 'lib', $from = 'tableContents')
{
if($libID == 'product' or $libID == 'execution') return;
if($confirm == 'no')
@@ -298,6 +314,11 @@ class doc extends control
$objectType = $lib->type;
$objectID = strpos(',product,project,execution,', ",$objectType,") !== false ? $lib->{$objectType} : 0;
if(in_array($this->app->tab, array('project', 'doc')) and $objectType == 'execution')
{
$objectType = 'project';
$objectID = $lib->project;
}
$browseLink = $this->createLink('doc', $from, "type=$objectType&objectID=$objectID");
return print(js::locate($browseLink, 'parent'));
@@ -359,7 +380,6 @@ class doc extends control
}
elseif($this->app->tab == 'project')
{
$linkType = 'project';
$this->project->setMenu($this->session->project);
}
elseif($this->app->tab == 'execution')
@@ -1267,7 +1287,9 @@ class doc extends control
* @param string $type
* @param int $objectID
* @param int $libID
* @param int $moduleID
* @param string $browseType
* @param string $orderBy
* @param int $param
* @param int $recTotal
* @param int $recPerPage
@@ -1427,4 +1449,37 @@ class doc extends control
$this->display();
}
/**
* Ajax Get the execution drop down by the projectID.
*
* @param int $projectID
* @access public
* @return void
*/
public function ajaxGetExecution($projectID)
{
$executions = $this->execution->getList($projectID);
$executionPairs = array(0 => '');
if(!empty($executions))
{
foreach($executions as $id => $execution)
{
if($execution->multiple)
{
if($execution->type == 'stage' and $execution->grade > 1)
{
$parentExecutions = $this->dao->select('id,name')->from(TABLE_EXECUTION)->where('id')->in(trim($execution->path, ','))->andWhere('type')->in('stage,kanban,sprint')->orderBy('grade')->fetchPairs();
$execution->name = implode('/', $parentExecutions);
}
$executionPairs[$id] = $execution->name;
}
}
}
$project = $this->project->getById($projectID);
$disabled = $project->multiple ? '' : 'disabled';
return print(html::select('execution', $executionPairs, 0, "class='form-control' data-placeholder='{$this->lang->doclib->tip->selectExecution}' $disabled"));
}
}
+2
View File
@@ -104,3 +104,5 @@ 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;}
#aclBox .acl-tip {color: #838a9d;}
+2 -4
View File
@@ -1,10 +1,8 @@
.modal-dialog {width: 75%;}
form {margin-bottom: 100px; padding-left: 65px;}
form {margin-bottom: 50px;}
table {width: 90% !important;}
#mainContent table th {width: 70px;}
#whiteListBox div.input-group {margin-bottom: 2px;}
#product_chosen {width: 50% !important;}
#execution_chosen {width: 50% !important;}
#groups_chosen.chosen-container .chosen-results, #users_chosen.chosen-container .chosen-results {max-height: 160px;}
+2
View File
@@ -9,6 +9,7 @@
.overflow-auto {overflow: auto;}
.overflow-visible {overflow: visible;}
.overflow-hidden {overflow: hidden;}
.img-lib {width: 14px; height: 14px; margin-bottom: 2px;}
#mainContent {padding-top: 0; padding-bottom: 0; height: calc(100vh - 125px);}
#mainContent #createDropdown {display: inline-block;}
#mainContent #createDropdown ul {position: absolute;}
@@ -62,6 +63,7 @@ li.drag-shadow ul {display: none!important;}
.file-tree a.show-icon {padding-right: 15px;}
.flex-between {display: flex; align-items: center; justify-content: space-between;}
.flex-center {display: flex; align-items: center; justify-content: center;}
.flex-start {display: flex; align-items: center;}
.tree li > .list-toggle {top: 4px;}
.input-tree {width: 120px;}
.tree-icon {position: absolute; right: 0;}
+1 -5
View File
@@ -58,11 +58,7 @@ function toggleAcl(acl, type)
if(type == 'lib')
{
var libType = $('input[name="type"]:checked').val();
var notice = typeof(noticeAcl[libType][acl]) != 'undefined' ? noticeAcl[libType][acl] : '';
$('#noticeAcl').html(notice);
if((libType == 'custom' || libType == 'api' || libType == 'book') && acl == 'private') $('#whiteListBox').addClass('hidden');
if((libType == 'api' || libType == 'book') && acl == 'private') $('#whiteListBox').addClass('hidden');
if(libType == 'project' && typeof(doclibID) != 'undefined')
{
+9 -140
View File
@@ -1,143 +1,12 @@
$(function()
$('#project').change(function()
{
$('input[name="type"]').change(function()
$.get(createLink('doc', 'ajaxGetExecution', 'projectID=' + $(this).val()), function(data)
{
var libType = $(this).val();
changeByLibType(libType);
})
changeByLibType($('input[name="type"]:checked').val());
toggleAcl($('form [name=acl]:checked').val(), 'lib');
if(data)
{
$('#execution').replaceWith(data);
$('#execution_chosen').remove();
$('#execution').chosen();
}
});
});
/**
* Change form by lib type.
*
* @param string libType
* @access public
* @return void
*/
function changeByLibType(libType)
{
if(libType == 'product')
{
$('table tr.product').removeClass('hidden');
$('#product').attr('disabled', false);
$('table tr.project').addClass('hidden');
$('#project').attr('disabled', true);
$('table tr.execution').addClass('hidden');
$('#execution').attr('disabled', true);
$('.normalLib').removeClass('hidden');
$('.normalLib input').attr('disabled', false);
$('table tr.apilib').addClass('hidden');
$('.apilib input, #desc, #baseUrl').attr('disabled', true);
$('form').removeAttr('action');
changeDoclibAcl(libType);
}
else if(libType == 'project')
{
$('table tr.project').removeClass('hidden');
$('#project').attr('disabled', false);
$('table tr.product').addClass('hidden');
$('#product').attr('disabled', true);
$('table tr.execution').addClass('hidden');
$('#execution').attr('disabled', true);
$('.normalLib').removeClass('hidden');
$('.normalLib input').attr('disabled', false);
$('table tr.apilib').addClass('hidden');
$('.apilib input, #desc, #baseUrl').attr('disabled', true);
$('form').removeAttr('action');
changeDoclibAcl(libType);
}
else if(libType == 'execution')
{
$('table tr.execution').removeClass('hidden');
$('#execution').attr('disabled', false);
$('table tr.product').addClass('hidden');
$('#product').attr('disabled', true);
$('table tr.project').addClass('hidden');
$('#project').attr('disabled', true);
$('.normalLib').removeClass('hidden');
$('.normalLib input').attr('disabled', false);
$('table tr.apilib').addClass('hidden');
$('.apilib input, #desc, #baseUrl').attr('disabled', true);
$('form').removeAttr('action');
changeDoclibAcl(libType);
}
else if(libType == 'api')
{
$('table tr.product').addClass('hidden');
$('#product').attr('disabled', true);
$('table tr.project').addClass('hidden');
$('#project').attr('disabled', true);
$('table tr.execution').addClass('hidden');
$('#execution').attr('disabled', true);
$('.normalLib').addClass('hidden');
$('.normalLib input').attr('disabled', true);
$('table tr.apilib').removeClass('hidden');
$('.apilib input, #desc, #baseUrl').attr('disabled', false);
$('form').attr('action', createLink('api', 'createLib'));
changeDoclibAcl(libType);
}
else
{
$('table tr.product').addClass('hidden');
$('#product').attr('disabled', true);
$('table tr.project').addClass('hidden');
$('#project').attr('disabled', true);
$('table tr.execution').addClass('hidden');
$('#execution').attr('disabled', true);
$('.normalLib').removeClass('hidden');
$('.normalLib input').attr('disabled', false);
$('table tr.apilib').addClass('hidden');
$('.apilib input, #desc, #baseUrl').attr('disabled', true);
$('form').removeAttr('action');
changeDoclibAcl(libType);
}
var acl = $('form [name=acl]').val();
var notice = typeof(noticeAcl[libType][acl]) != 'undefined' ? noticeAcl[libType][acl] : '';
$('#noticeAcl').html(notice);
$('#whiteListBox').addClass('hidden');
}
function changeDoclibAcl(libType)
{
if(libType == 'product' || libType == 'execution')
{
$('form input[name="acl"]').closest('td').find('span:first').html($('#aclBoxA td').html());
}
else
{
$('form input[name="acl"]').closest('td').find('span:first').html($('#aclBoxB td').html());
}
}
+22 -12
View File
@@ -17,18 +17,24 @@ $(function()
return dropdown;
}
var imgObj = {
'annex': 'annex',
'lib': 'wiki-file-lib',
'api': 'interface'
}
$('#fileTree').tree(
{
initialState: 'active',
data: treeData,
itemCreator: function($li, item)
{
var libClass = ['lib', 'annex', 'api', 'execution'].indexOf(item.type) !== -1 ? 'lib' : '';
var libClass = ['lib', 'annex', 'api'].indexOf(item.type) !== -1 ? 'lib' : '';
var hasChild = item.children ? !!item.children.length : false;
var $item = '<a href="###" style="position: relative" data-has-children="' + hasChild + '" title="' + item.name + '" data-id="' + item.id + '" class="' + libClass + '" data-type="' + item.type + '">';
$item += '<div class="text h-full w-full flex-between overflow-hidden">';
$item += '<span>';
if(libClass == 'lib') $item += '<i class="icon-file-excel"></i> ';
$item += '<div class="text h-full w-full flex-start overflow-hidden">';
if(libClass == 'lib') $item += '<div class="img-lib" style="background-image:url(static/svg/' + imgObj[item.type || 'lib'] + '.svg)"></div>';
$item += '<span style="padding-left: 5px;">';
$item += item.name
$item += '</span>';
$item += '<i class="icon icon-drop icon-ellipsis-v hidden tree-icon" data-isCatalogue="' + (item.type ? false : true) + '"></i>';
@@ -182,17 +188,19 @@ $(function()
{
var $input = $('[data-id=liTreeModal]').html();
var $rootDom = $('[data-id=' + item.libid + ']a + ul');
$rootDom.append($input);
}
else
{
var $input = $('[data-id=ulTreeModal]').html();
var $rootDom = $('[data-id=' + item.libid + ']a + ul');
var $rootDom = $('[data-id=' + item.libid + ']a');
var $li = $rootDom.parent();
moduleData.isUpdate = true;
$rootDom.addClass('open in has-list');
$rootDom.after($input);
$li.addClass('open in has-list');
}
$('#fileTree').data('zui.tree').expand($('li[data-id="' + item.libid + '"]'));
$rootDom.append($input);
$rootDom.find('input').focus();
$rootDom.parent().find('input').focus();
break;
case 'addCataBro' :
moduleData.createType = 'same';
@@ -224,10 +232,11 @@ $(function()
}
}).on('blur', '.file-tree input.input-tree', function()
{
var value = $(this).val();
var $input = $(this);
var value = $input.val();
if(!value)
{
$(this).closest('[data-id=insert]').remove();
$input.closest('[data-id=insert]').remove();
return;
}
@@ -251,8 +260,9 @@ $(function()
}
var module = result.module;
var resultDom = $('[data-id=aTreeModal]').html().replace(/%name%/g, module.name).replace(/%id%/g, module.id).replace('insert', module.id);
$(this).parent().append(resultDom);
$(this).remove();
$input.closest('ul').find('.has-input').css('padding-left', '15px');
$input.after(resultDom);
$input.remove();
if(moduleData.isUpdate)
{
$.getJSON(createLink('doc', 'tableContents', 'type=' + objectType + '&objectID=' + objectID , 'json'), function(data){
+12
View File
@@ -20,6 +20,13 @@ $lang->doclib->select = 'Auswahl';
$lang->doclib->execution = $lang->executionCommon . ' Bibliothek';
$lang->doclib->product = $lang->productCommon . ' Bibliothek';
$lang->doclib->apiLibName = 'Api Library Name';
$lang->doclib->privateACL = "Private <span class='acl-tip'>(Only creators and whitelisted users with %s permissions can access it)</span>";
$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['api'] = 'API';
$lang->doclib->aclListA = array();
$lang->doclib->aclListA['default'] = 'Default';
@@ -29,6 +36,11 @@ $lang->doclib->aclListB['open'] = 'Public';
$lang->doclib->aclListB['custom'] = 'Custom';
$lang->doclib->aclListB['private'] = 'Private';
$lang->doclib->aclList = array();
$lang->doclib->aclList['open'] = "Public <span class='acl-tip'>(Users who can access doccan access it)</span>";
$lang->doclib->aclList['default'] = "Default <span class='acl-tip'>(Users who can access the selected %s or users in the whiltelist can access it)</span>";
$lang->doclib->aclList['private'] = "Private <span class='acl-tip'>(Only the one who created it or users in the whiltelist can access it)</span>";
$lang->doclib->create['product'] = 'Create ' . $lang->productCommon . ' Library';
$lang->doclib->create['execution'] = 'Create ' . $lang->executionCommon . ' Library';
$lang->doclib->create['custom'] = 'Create Custom Library';
+12
View File
@@ -20,6 +20,13 @@ $lang->doclib->select = 'Select';
$lang->doclib->execution = $lang->executionCommon . ' Library';
$lang->doclib->product = $lang->productCommon . ' Library';
$lang->doclib->apiLibName = 'Api Library Name';
$lang->doclib->privateACL = "Private <span class='acl-tip'>(Only creators and whitelisted users with %s permissions can access it)</span>";
$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['api'] = 'API';
$lang->doclib->aclListA = array();
$lang->doclib->aclListA['default'] = 'Default';
@@ -29,6 +36,11 @@ $lang->doclib->aclListB['open'] = 'Public';
$lang->doclib->aclListB['custom'] = 'Custom';
$lang->doclib->aclListB['private'] = 'Private';
$lang->doclib->aclList = array();
$lang->doclib->aclList['open'] = "Public <span class='acl-tip'>(Users who can access doccan access it)</span>";
$lang->doclib->aclList['default'] = "Default <span class='acl-tip'>(Users who can access the selected %s or users in the whiltelist can access it)</span>";
$lang->doclib->aclList['private'] = "Private <span class='acl-tip'> (Only the one who created it or users in the whiltelist can access it)</span>";
$lang->doclib->create['product'] = 'Create ' . $lang->productCommon . ' Library';
$lang->doclib->create['execution'] = 'Create ' . $lang->executionCommon . ' Library';
$lang->doclib->create['custom'] = 'Create Custom Library';
+12
View File
@@ -20,6 +20,13 @@ $lang->doclib->select = 'Sélect.';
$lang->doclib->execution = 'Bibliothèque ' . $lang->executionCommon;
$lang->doclib->product = $lang->productCommon . ' Library';
$lang->doclib->apiLibName = 'Api Library Name';
$lang->doclib->privateACL = "Private <span class='acl-tip'>(Only creators and whitelisted users with %s permissions can access it)</span>";
$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['api'] = 'API';
$lang->doclib->aclListA = array();
$lang->doclib->aclListA['default'] = 'Défaut';
@@ -29,6 +36,11 @@ $lang->doclib->aclListB['open'] = 'Public';
$lang->doclib->aclListB['custom'] = 'Person.';
$lang->doclib->aclListB['private'] = 'Privée';
$lang->doclib->aclList = array();
$lang->doclib->aclList['open'] = "Public <span class='acl-tip'>(Users who can access doccan access it)</span>";
$lang->doclib->aclList['default'] = "Default <span class='acl-tip'>(Users who can access the selected %s or users in the whiltelist can access it)</span>";
$lang->doclib->aclList['private'] = "Private <span class='acl-tip'> (Only the one who created it or users in the whiltelist can access it)</span>";
$lang->doclib->create['product'] = 'Créer ' . $lang->productCommon . ' Library';
$lang->doclib->create['execution'] = 'Créer ' . 'Bibliothèque ' . $lang->executionCommon;
$lang->doclib->create['custom'] = 'Créer Bibliothèque Personnelle';
+15 -3
View File
@@ -10,7 +10,7 @@
* @link http://www.zentao.net
*/
$lang->doclib = new stdclass();
$lang->doclib->name = '文档库名称';
$lang->doclib->name = '库名称';
$lang->doclib->control = '访问控制';
$lang->doclib->group = '分组';
$lang->doclib->user = '用户';
@@ -20,6 +20,13 @@ $lang->doclib->select = '选择文档库';
$lang->doclib->execution = $lang->executionCommon . '库';
$lang->doclib->product = $lang->productCommon . '库';
$lang->doclib->apiLibName = '接口库名称';
$lang->doclib->privateACL = "私有 <span class='acl-tip'>(仅创建者和有%s权限的白名单用户可访问)</span>";
$lang->doclib->tip = new stdclass();
$lang->doclib->tip->selectExecution = "执行为空时,创建的库为{$lang->projectCommon}库";
$lang->doclib->type['wiki'] = 'WIKI文档库';
$lang->doclib->type['api'] = '接口库';
$lang->doclib->aclListA = array();
$lang->doclib->aclListA['default'] = '默认';
@@ -29,6 +36,11 @@ $lang->doclib->aclListB['open'] = '公开';
$lang->doclib->aclListB['custom'] = '自定义';
$lang->doclib->aclListB['private'] = '私有';
$lang->doclib->aclList = array();
$lang->doclib->aclList['open'] = "公开 <span class='acl-tip'>(有文档视图权限即可访问)</span>";
$lang->doclib->aclList['default'] = "默认 <span class='acl-tip'>(有所选%s访问权限用户可以访问)</span>";
$lang->doclib->aclList['private'] = "私有 <span class='acl-tip'>(仅创建者和白名单用户可访问)</span>";
$lang->doclib->create['product'] = '创建' . $lang->productCommon . '文档库';
$lang->doclib->create['execution'] = '创建' . $lang->executionCommon . '文档库';
$lang->doclib->create['custom'] = '创建自定义文档库';
@@ -142,8 +154,8 @@ $lang->doc->api = '接口';
$lang->doc->collectAction = '收藏文档';
$lang->doc->libName = '文档库名称';
$lang->doc->libType = '文档库类型';
$lang->doc->libName = '库名称';
$lang->doc->libType = '库类型';
$lang->doc->custom = '自定义文档库';
$lang->doc->customAB = '自定义库';
$lang->doc->createLib = '创建库';
+76 -79
View File
@@ -9,8 +9,6 @@
* @version $Id: model.php 881 2010-06-22 06:50:32Z chencongzhi520 $
* @link http://www.zentao.net
*/
?>
<?php
class docModel extends model
{
@@ -193,12 +191,17 @@ class docModel extends model
{
$lib = fixer::input('post')
->setForce('product', $this->post->type == 'product' ? $this->post->product : 0)
->setForce('execution', $this->post->type == 'execution' ? $this->post->execution : 0)
->setForce('project', $this->post->type == 'project' ? $this->post->project : 0)
->setForce('execution', $this->post->type == 'execution' || $this->post->execution ? $this->post->execution : 0)
->join('groups', ',')
->join('users', ',')
->add('addedBy', $this->app->user->account)
->add('addedDate', helper::now())
->remove('uid,contactListMenu,libType')
->get();
if($lib->type == 'execution' and $lib->execution)
if($lib->execution) $lib->type = 'execution';
if($lib->type == 'execution' and $lib->execution and !$lib->project)
{
$execution = $this->loadModel('execution')->getByID($lib->execution);
$lib->project = $execution->project;
@@ -226,17 +229,26 @@ class docModel extends model
*/
public function createApiLib()
{
/* Replace doc library name. */
$this->lang->doclib->name = $this->lang->doclib->apiLibName;
$data = fixer::input('post')
->trim('name')
->join('groups', ',')
->join('users', ',')
->setForce('product', $this->post->libType == 'product' ? $this->post->product : 0)
->setForce('project', $this->post->libType == 'project' ? $this->post->project : 0)
->add('addedBy', $this->app->user->account)
->add('addedDate', helper::now())
->remove('uid,contactListMenu,libType')
->get();
if($data->acl == 'private') $data->users = $this->app->user->account;
if($data->acl == 'custom' && strpos($data->users, $this->app->user->account) === false) $data->users .= ',' . $this->app->user->account;
$this->app->loadLang('api');
/* Replace doc library name. */
$this->lang->doclib->name = $this->lang->doclib->apiLibName;
$this->lang->doclib->baseUrl = $this->lang->api->baseUrl;
$this->lang->doclib->project = $this->lang->api->project;
$this->lang->doclib->product = $this->lang->api->product;
$this->config->api->createlib->requiredFields .= $this->post->libType == 'product' ? ',product' : ',project';
$data->type = static::DOC_TYPE_API;
$this->dao->insert(TABLE_DOCLIB)->data($data)->autoCheck()
@@ -250,16 +262,33 @@ class docModel extends model
/**
* Update api lib.
*
* @param int $id
* @param stdClass $oldDoc
* @param array $data
* @param int $id
* @access public
* @return array|int
*/
public function updateApiLib($id, $oldDoc, $data)
public function updateApiLib($id)
{
$oldLib = $this->getLibById($id);
$data = fixer::input('post')
->trim('name')
->join('groups', ',')
->join('users', ',')
->setForce('product', $this->post->libType == 'product' ? $this->post->product : 0)
->setForce('project', $this->post->libType == 'project' ? $this->post->project : 0)
->remove('uid,contactListMenu,libType')
->get();
$this->app->loadLang('api');
/* Replace doc library name. */
$this->lang->doclib->name = $this->lang->doclib->apiLibName;
$this->lang->doclib->name = $this->lang->doclib->apiLibName;
$this->lang->doclib->baseUrl = $this->lang->api->baseUrl;
$this->lang->doclib->project = $this->lang->api->project;
$this->lang->doclib->product = $this->lang->api->product;
$this->config->api->editlib->requiredFields .= $this->post->libType == 'product' ? ',product' : ',project';
$data->type = static::DOC_TYPE_API;
$this->dao->update(TABLE_DOCLIB)->data($data)->autoCheck()
@@ -294,21 +323,15 @@ class docModel extends model
->setDefault('groups', '')
->join('groups', ',')
->join('users', ',')
->remove('uid,contactListMenu')
->get();
if($oldLib->type == 'project' or $oldLib->type == 'custom')
if($oldLib->type == 'project')
{
$libCreatedBy = $this->dao->select('*')->from(TABLE_ACTION)->where('objectType')->eq('doclib')->andWhere('objectID')->eq($libID)->andWhere('action')->eq('created')->fetch('actor');
if($oldLib->type == 'custom')
{
if($lib->acl == 'private') $lib->users = $libCreatedBy ? $libCreatedBy : $this->app->user->account;
}
else
{
$openedBy = $this->dao->findById($oldLib->project)->from(TABLE_PROJECT)->fetch('openedBy');
if($lib->acl == 'private' and $lib->acl == 'custom') $lib->users .= ',' . $libCreatedBy ? $libCreatedBy : $openedBy;
}
$openedBy = $this->dao->findById($oldLib->project)->from(TABLE_PROJECT)->fetch('openedBy');
if($lib->acl == 'private' and $lib->acl == 'custom') $lib->users .= ',' . $libCreatedBy ? $libCreatedBy : $openedBy;
}
if($oldLib->acl != $lib->acl and $lib->acl == 'open') $lib->users = '';
@@ -797,7 +820,6 @@ class docModel extends model
return false;
}
$now = helper::now();
$doc = fixer::input('post')->setDefault('module', 0)
->callFunc('title', 'trim')
->stripTags($this->config->doc->editor->edit['id'], $this->config->allowedTags)
@@ -807,7 +829,7 @@ class docModel extends model
->setDefault('execution', 0)
->setDefault('mailto', '')
->add('editedBy', $this->app->user->account)
->add('editedDate', $now)
->add('editedDate', helper::now())
->cleanInt('module')
->join('groups', ',')
->join('users', ',')
@@ -938,7 +960,7 @@ class docModel extends model
$products = $this->product->getPairs();
$this->config->doc->search['params']['project']['values'] = array('' => '') + $this->loadModel('project')->getPairsByProgram() + array('all' => $this->lang->doc->allProjects);
$this->config->doc->search['params']['execution']['values'] = array('' => '') + $this->loadModel('execution')->getPairs() + array('all' => $this->lang->doc->allExecutions);
$this->config->doc->search['params']['execution']['values'] = array('' => '') + $this->loadModel('execution')->getPairs(0, 'all', 'multiple') + 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);
@@ -959,7 +981,7 @@ class docModel extends model
if($type == 'project')
{
$this->config->doc->search['params']['execution']['values'] = array('' => '') + $this->loadModel('execution')->getPairs($this->session->project, 'all', 'all') + array('all' => $this->lang->doc->allExecutions);
$this->config->doc->search['params']['execution']['values'] = array('' => '') + $this->loadModel('execution')->getPairs($this->session->project, 'all', 'multiple') + array('all' => $this->lang->doc->allExecutions);
}
else
{
@@ -975,7 +997,7 @@ class docModel extends model
else
{
$products = $this->product->getPairs('nocode', $this->session->project);
$this->config->doc->search['params']['execution']['values'] = array('' => '') + $this->loadModel('execution')->getPairs($this->session->project, 'all', 'noclosed') + array('all' => $this->lang->doc->allExecutions);
$this->config->doc->search['params']['execution']['values'] = array('' => '') + $this->loadModel('execution')->getPairs($this->session->project, 'all', 'multiple') + array('all' => $this->lang->doc->allExecutions);
$this->config->doc->search['params']['lib']['values'] = array('' => '', $libID => ($libID ? $libs[$libID] : 0), 'all' => $this->lang->doclib->all);
$this->config->doc->search['params']['product']['values'] = array('' => '') + $products + array('all' => $this->lang->doc->allProduct);
}
@@ -1099,7 +1121,16 @@ class docModel extends model
if(isset($object->addedBy) and $object->addedBy == $this->app->user->account) return true;
if(isset($object->users) and strpos(",{$object->users},", $account) !== false) return true;
if($object->project and $object->acl == 'private')
if(!empty($object->groups))
{
$userGroups = $this->app->user->groups;
foreach($userGroups as $groupID)
{
if(strpos(",$object->groups,", ",$groupID,") !== false) return true;
}
}
if($object->project and !$object->execution and $object->acl == 'default')
{
$stakeHolders = array();
$project = $this->loadModel('project')->getById($object->project);
@@ -1108,20 +1139,9 @@ class docModel extends model
$authorizedUsers = $this->user->getProjectAuthedUsers($project, $stakeHolders, $projectTeams, array_flip(explode(",", $project->whitelist)));
if(strpos(",{$object->users},", $account) !== false) return true;
if(array_key_exists($this->app->user->account, array_filter($authorizedUsers))) return true;
}
if($object->acl == 'custom')
{
$userGroups = $this->app->user->groups;
foreach($userGroups as $groupID)
{
if(strpos(",$object->groups,", ",$groupID,") !== false) return true;
}
if(strpos(",{$object->users},", $account) !== false) return true;
}
if(strpos($extra, 'notdoc') !== false)
{
static $extraDocLibs;
@@ -1129,7 +1149,7 @@ class docModel extends model
if(isset($extraDocLibs[$object->id])) return true;
}
if(!empty($object->product) or !empty($object->execution))
if($object->acl == 'default' and (in_array($object->type, array('product', 'execution'))))
{
$acls = $this->app->user->rights['acls'];
if(!empty($object->product) and !empty($acls['products']) and !in_array($object->product, $acls['products'])) return false;
@@ -1449,14 +1469,7 @@ class docModel extends model
else
{
$executionIDList = array();
if($type == 'project')
{
$executionIDList = $this->dao->select('id')->from(TABLE_EXECUTION)
->where('project')->eq($objectID)
->andWhere('multiple')->eq(1)
->andWhere('deleted')->eq(0)
->fetchPairs();
}
if($type == 'project') $executionIDList = $this->loadModel('execution')->getPairs($objectID, 'all', 'multiple');
$objectLibs = $this->dao->select('*')->from(TABLE_DOCLIB)
->where('deleted')->eq(0)
@@ -1470,7 +1483,7 @@ class docModel extends model
$objectLibs += $this->dao->select('*')->from(TABLE_DOCLIB)
->where('deleted')->eq(0)
->andWhere('vision')->eq($this->config->vision)
->andWhere('execution')->in($executionIDList)
->andWhere('execution')->in(array_keys($executionIDList))
->beginIF(!empty($appendLib))->orWhere('id')->eq($appendLib)->fi()
->orderBy('`order` asc, id_asc')
->fetchAll('id');
@@ -1488,24 +1501,10 @@ class docModel extends model
->fetchPairs('product', 'projectCount');
}
$docCountPairs = $this->dao->select('lib, count(id) as docCount')->from(TABLE_DOC)
->where('lib')->in(array_keys($objectLibs))
->andWhere('vision')->eq($this->config->vision)
->andWhere('type')->notin('chapter')
->andWhere('deleted')->eq(0)
->groupBy('lib')
->fetchPairs('lib');
$libs = array();
foreach($objectLibs as $lib)
{
if($this->checkPrivLib($lib))
{
$docCount = zget($docCountPairs, $lib->id, 0);
$lib->docCount = $docCount > 99 ? '99+' : $docCount;
$libs[$lib->id] = $lib;
}
if($this->checkPrivLib($lib)) $libs[$lib->id] = $lib;
}
$itemCounts = $this->statLibCounts(array_keys($libs));
@@ -2653,7 +2652,7 @@ class docModel extends model
$table = $this->config->objectTables[$type];
$libs = $this->getLibsByObject($type, $objectID, '', $appendLib);
if($libID == 0 and !empty($libs)) $libID = reset($libs)->id;
if(($libID == 0 or !isset($libs[$libID])) and !empty($libs)) $libID = reset($libs)->id;
if($this->app->tab == 'doc') $this->app->rawMethod = $type == 'execution' ? 'project' : $type;
$object = $this->dao->select('id,name,status')->from($table)->where('id')->eq($objectID)->fetch();
@@ -2712,7 +2711,6 @@ class docModel extends model
*/
public function getDocsBySearch($type, $objectID, $libID, $queryID, $orderBy = 'id_desc', $pager = null)
{
$lib = $this->getLibById($libID);
$queryName = $type . 'libDocQuery';
$queryForm = $type . 'libDocForm';
if($queryID)
@@ -2831,7 +2829,7 @@ class docModel extends model
foreach($libs as $lib)
{
if($lib->type != 'execution') continue;
$executionLibs[$lib->execution][$libID] = $lib;
$executionLibs[$lib->execution][$lib->id] = $lib;
}
$executionPairs = $this->dao->select('id,name')->from(TABLE_EXECUTION)
@@ -2862,24 +2860,23 @@ class docModel extends model
if(empty($libTree['execution'][$executionID]))
{
$execution = new stdclass();
$execution->id = $executionID;
$execution->name = zget($executionPairs, $executionID);
$execution->type = 'execution';
$execution->active = $item->active;
$execution->children = array();
$execution->id = $executionID;
$execution->name = zget($executionPairs, $executionID);
$execution->type = 'execution';
$execution->active = $item->active;
$execution->children = array();
if(count($executionLibs[$executionID]) == 1)
{
$execution->id = $item->id;
$execution->type = 'lib';
$execution->children = $item->children;
$execution->id = $item->id;
$execution->children = $item->children;
}
$libTree['execution'][$executionID] = $execution;
continue;
if(count($executionLibs[$executionID]) == 1) continue;
}
$libTree['execution'][$executionID]->active = $item->active ? 1 : $libTree['execution'][$executionID]->active;
$libTree['execution'][$executionID]->children[$lib->id] = $item;
$libTree['execution'][$executionID]->children[] = $item;
}
}
+28 -36
View File
@@ -12,6 +12,7 @@
?>
<?php include '../../common/view/header.lite.html.php';?>
<?php include '../../common/view/chosen.html.php';?>
<?php js::set('libType', $type);?>
<div id="main">
<div class="container">
<div id='mainContent' class='main-content'>
@@ -21,47 +22,39 @@
</div>
<form method='post' target='hiddenwin' class='no-stash'>
<table class='table table-form'>
<tr>
<th class='w-110px'><?php echo $lang->doc->libType?></th>
<?php if($this->app->tab != 'doc'):?>
<?php
foreach($libTypeList as $key => $libType)
{
if($this->app->tab != $key) unset($libTypeList[$key]);
}
?>
<?php endif;?>
<td><?php echo html::radio('type', $libTypeList, $type ? $type : key($libTypeList))?></td>
<?php if(in_array($type, array('product', 'project', 'execution'))):?>
<tr class='objectBox'>
<th><?php echo $lang->doc->{$type}?></th>
<td class='required'><?php echo html::select($type, $objects, $objectID, "class='form-control chosen' data-drop_direction='down'")?></td>
</tr>
<tr class='product'>
<th><?php echo $lang->doc->product?></th>
<td><?php echo html::select('product', $products, $type == 'product' ? $objectID : '', "class='form-control chosen' data-drop_direction='down'")?></td>
</tr>
<tr class='project hidden'>
<th><?php echo $lang->doc->project?></th>
<td><?php echo html::select('project', $projects, $type == 'project' ? $objectID : '', "class='form-control chosen' data-drop_direction='down'")?></td>
</tr>
<tr class='execution hidden'>
<?php if($app->tab == 'doc' and $type == 'project'):?>
<tr class='executionBox'>
<th><?php echo $lang->doc->execution?></th>
<td><?php echo html::select('execution', $executions, $type == 'execution' ? $objectID : '', "class='form-control chosen' data-drop_direction='down'")?></td>
<td>
<?php $disabled = $project->multiple ? '' : 'disabled';?>
<?php echo html::select('execution', $executionPairs, 0, "class='form-control chosen' data-drop_direction='down' data-placeholder='{$lang->doclib->tip->selectExecution}' $disabled")?>
</td>
</tr>
<?php endif;?>
<tr>
<th><?php echo $lang->doc->libType;?></th>
<td>
<span><?php echo html::radio('libType', $lang->doclib->type, 'wiki')?></span>
</td>
</tr>
<?php endif;?>
<tr class="normalLib">
<th><?php echo $lang->doclib->name?></th>
<td><?php echo html::input('name', '', "class='form-control'")?></td>
</tr>
<tr class='apilib hidden'>
<th><?php echo $lang->api->name?></th>
<td><?php echo html::input('name', '', "class='form-control'")?></td>
</tr>
<tr class="apilib hidden">
<th><?php echo $lang->api->baseUrl?></th>
<td><?php echo html::input('baseUrl', '', "class='form-control' placeholder='" . $lang->api->baseUrlDesc . "'");?></td>
</tr>
<tr>
<tr id="aclBox">
<th><?php echo $lang->doclib->control;?></th>
<td>
<span><?php echo html::radio('acl', $lang->doc->aclList, 'open', "onchange='toggleAcl(this.value, \"lib\")'")?></span>
<span class='text-info' id='noticeAcl'><?php echo $lang->doc->noticeAcl['lib']['product']['default'];?></span>
<?php echo html::radio('acl', $lang->doclib->aclList, $type == 'custom' ? 'open' : 'default', "onchange='toggleAcl(this.value, \"lib\")'", 'block')?>
</td>
</tr>
<tr id='whiteListBox' class='hidden'>
@@ -74,6 +67,7 @@
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->doclib->user?></span>
<?php echo html::select('users[]', $users, '', "class='form-control picker-select' multiple")?>
<?php echo $this->fetch('my', 'buildContactLists', "dropdownName=users&attr=data-drop_direction='up'");?>
</div>
</td>
</tr>
@@ -84,7 +78,10 @@
</td>
</tr>
<tr>
<td class='text-center form-actions' colspan='2'><?php echo html::submitButton();?></td>
<td class='text-center form-actions' colspan='2'>
<?php echo html::submitButton();?>
<?php echo html::hidden('type', $type);?>
</td>
</tr>
</table>
</form>
@@ -94,19 +91,14 @@
</div>
<div class='hidden'>
<table>
<tr id='aclBoxA'>
<tr id='aclAPIBox'>
<th><?php echo $lang->doclib->control;?></th>
<td>
<?php echo html::radio('acl', $lang->doclib->aclListA, 'default', "onchange='toggleAcl(this.value, \"lib\")'")?>
</td>
</tr>
<tr id='aclBoxB'>
<th><?php echo $lang->doclib->control;?></th>
<td>
<?php echo html::radio('acl', $lang->doclib->aclListB, 'open', "onchange='toggleAcl(this.value, \"lib\")'")?>
</td>
</tr>
</table>
</div>
<?php js::set('noticeAcl', $lang->doc->noticeAcl['lib']);?>
<?php js::set('libType', $type);?>
<?php include '../../common/view/footer.lite.html.php';?>
+8 -2
View File
@@ -15,6 +15,10 @@
#docListForm th.c-id {width: 72px;}
#docListForm th.c-user {width: 80px;}
#docListForm th.c-actions {width: 84px; padding-left: 15px;}
#docListForm .checkbox-primary {line-height: 16px;}
#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;}
</style>
<?php if(common::checkNotCN()):?>
<style>
@@ -75,13 +79,15 @@
</td>
<td class="c-name" title='<?php echo $doc->title;?>'>
<?php
$docType = $doc->type == 'text' ? 'wiki-file' : $doc->type;
$icon = html::image("static/svg/{$docType}.svg");
if(common::hasPriv('doc', 'objectLibs'))
{
echo html::a($this->createLink('doc', 'objectLibs', "type=$type&objectID=$objectID&libID=$doc->lib&docID=$doc->id"), "<i class='icon icon-file-text text-muted'></i> &nbsp;" . $doc->title, '', "title='{$doc->title}' data-app='{$this->app->tab}'");
echo html::a($this->createLink('doc', 'objectLibs', "type=$type&objectID=$objectID&libID=$doc->lib&docID=$doc->id"), $icon . $doc->title, '', "title='{$doc->title}' data-app='{$this->app->tab}'");
}
else
{
echo "<i class='icon icon-file-text text-muted'></i> {$doc->title}";
echo "$icon {$doc->title}";
}
?>
<?php if(common::canBeChanged('doc', $doc) and common::hasPriv('doc', 'collect') and $libType and $libType != 'api'):?>
+3 -10
View File
@@ -47,19 +47,11 @@
<span class='hidden'><?php echo html::radio('type', $lang->doc->libTypeList, $lib->type);?></span>
</td>
</tr>
<tr>
<tr id="aclBox">
<th><?php echo $lang->doclib->control;?></th>
<?php if($lib->type == 'product' or $lib->type == 'execution'):?>
<td>
<?php echo html::radio('acl', $lang->doclib->aclListA, $lib->acl, "onchange='toggleAcl(this.value, \"lib\")'")?>
<span class='text-info' id='noticeAcl'><?php echo $lang->doc->noticeAcl['lib'][$lib->type][$lib->acl];?></span>
<?php echo html::radio('acl', $lang->doclib->aclList, $lib->acl, "onchange='toggleAcl(this.value, \"lib\")'", 'block')?>
</td>
<?php else:?>
<td>
<?php echo html::radio('acl', $lang->doclib->aclListB, $lib->acl, "onchange='toggleAcl(this.value, \"lib\")'")?>
<span class='text-info' id='noticeAcl'><?php echo $lang->doc->noticeAcl['lib'][$lib->type][$lib->acl];?></span>
</td>
<?php endif;?>
</tr>
<tr id='whiteListBox' class='hidden'>
<th><?php echo $lang->doc->whiteList?></th>
@@ -71,6 +63,7 @@
<div class='input-group'>
<span class='input-group-addon'><?php echo $lang->doclib->user?></span>
<?php echo html::select('users[]', $users, $lib->users, "class='form-control picker-select' multiple")?>
<?php echo $this->fetch('my', 'buildContactLists', "dropdownName=users&attr=data-drop_direction='up'");?>
</div>
</td>
</tr>
+3 -3
View File
@@ -32,7 +32,7 @@
if(common::hasPriv('doc', 'createLib'))
{
echo html::a(helper::createLink('doc', 'createLib', "type=$type&objectID=$objectID"), '<i class="icon icon-plus"></i> ' . $this->lang->doc->createLib, '', 'class="btn btn-secondary iframe"');
echo html::a(helper::createLink('doc', 'createLib', "type=$type&objectID=$objectID"), '<i class="icon icon-plus"></i> ' . $this->lang->doc->createLib, '', 'class="btn btn-secondary iframe" data-width="800px"');
}
if($libID and (common::hasPriv('doc', 'create') or (common::hasPriv('api', 'create') and !$apiLibID)))
@@ -109,8 +109,8 @@
</div>
<div class="hidden" data-id="aTreeModal">
<a href="###" data-has-children="false" title="%name%" data-id="%id%">
<div class="text h-full w-full overflow-hidden" style="position: relative;">
%name%
<div class="text h-full w-full flex-between overflow-hidden" style="position: relative;">
<span>%name%</span>
<i class="icon icon-drop icon-ellipsis-v hidden file-drop-icon" data-iscatalogue="true"></i>
</div>
</a>
+1
View File
@@ -1374,6 +1374,7 @@ class kanban extends control
$this->loadModel('project');
$this->loadModel('execution');
$this->loadModel('programplan');
/* Load pager. */
$this->app->loadClass('pager', $static = true);
+1 -1
View File
@@ -370,7 +370,7 @@ function renderKanbanItem(item, $item)
$item.data('card', item);
$info.children('.estimate').text(item.estimate + kanbancardLang.lblHour);
if(item.estimate == 0) $info.children('.estimate').hide();
item.estimate > 0 ? $info.children('.estimate').show() : $info.children('.estimate').hide();
$info.children('.pri')
.attr('class', 'pri' + (item.pri ? ' label-pri label-pri-' + item.pri : ''))
+1 -1
View File
@@ -3119,8 +3119,8 @@ class kanbanModel extends model
->add('lastEditedBy', $this->app->user->account)
->add('lastEditedDate', $now)
->trim('name')
->setDefault('estimate', $oldCard->estimate)
->setIF(!empty($this->post->assignedTo) and $oldCard->assignedTo != $this->post->assignedTo, 'assignedDate', $now)
->setIF(!isset($_POST['estimate']), 'estimate', $oldCard->estimate)
->setIF(is_numeric($this->post->estimate), 'estimate', (float)$this->post->estimate)
->stripTags($this->config->kanban->editor->editcard['id'], $this->config->allowedTags)
->join('assignedTo', ',')
@@ -62,8 +62,16 @@
<?php printf('%03d', $execution->id);?>
</td>
<?php if(common::hasPriv('execution', 'view')):?>
<?php
$isClickable = true;
if($execution->type == 'stage') $isClickable = $this->programplan->checkLeafStage($execution->id) ? true : false;
?>
<td title='<?php echo $execution->title;?>'>
<?php if($isClickable):?>
<a href='javascript:void(0);' onclick="locateView('execution', <?php echo $execution->id;?>)"><?php echo $execution->name;?></a>
<?php else:?>
<?php echo $execution->name;?>
<?php endif;?>
</td>
<?php else:?>
<td title='<?php echo $execution->title;?>'><?php echo $execution->name;?></td>
+1
View File
@@ -77,6 +77,7 @@ class personnel extends control
public function invest($programID = 0)
{
$this->loadModel('program')->setMenu($programID);
$this->app->loadLang('user');
$this->view->title = $this->lang->personnel->invest;
$this->view->position[] = $this->lang->personnel->invest;
+23 -39
View File
@@ -376,15 +376,7 @@ class personnelModel extends model
}
/* The number of hours per person. */
$userHours = array();
if($this->config->edition != 'open')
{
$userHours = $this->getUserEffortHours($userTasks);
}
else
{
$userHours = $this->getUserHours($userTasks);
}
$userHours = $this->getUserHours($userTasks);
foreach($userHours as $account => $hours)
{
@@ -395,33 +387,6 @@ class personnelModel extends model
return $invest;
}
/**
* Get user hours.
*
* @param object $userTasks
* @access public
* @return object
*/
public function getUserEffortHours($userTasks)
{
$accounts = array();
$taskIDList = array();
foreach($userTasks as $account => $taskID)
{
$accounts[] = $account;
$taskIDList = array_merge($taskIDList, $taskID);
}
$userHours = $this->dao->select('account, sum(`left`) as `left`, sum(consumed) as consumed')->from(TABLE_EFFORT)
->where('account')->in($accounts)
->andWhere('deleted')->eq(0)
->andWhere('objectType')->eq('task')
->andWhere('objectID')->in($taskIDList)
->groupBy('account')
->fetchAll('account');
return $userHours;
}
/**
* Get user hours.
*
@@ -439,12 +404,31 @@ class personnelModel extends model
$taskIDList = array_merge($taskIDList, $taskID);
}
$userHours = $this->dao->select('account, sum(`left`) as `left`, sum(consumed) as consumed')->from(TABLE_EFFORT)
$effortList = $this->dao->select('id, account, objectID , `left`, consumed')->from(TABLE_EFFORT)
->where('account')->in($accounts)
->andWhere('deleted')->eq(0)
->andWhere('objectID')->in($taskIDList)
->andWhere('objectType')->eq('task')
->groupBy('account')
->fetchAll('account');
->orderBy('id_asc')
->fetchGroup('account', 'id');
$userHours = array();
foreach($effortList as $account => $efforts)
{
$latestLeft = array();
$userHours[$account] = new stdclass();
$userHours[$account]->left = 0;
$userHours[$account]->consumed = 0;
foreach($efforts as $effort)
{
$latestLeft[$effort->objectID] = $effort->left;
$userHours[$account]->consumed += $effort->consumed;
}
$userHours[$account]->left = array_sum($latestLeft);
}
return $userHours;
}
+1 -1
View File
@@ -1871,7 +1871,7 @@ class repoModel extends model
$_POST['objectType'][1] = 'task';
$_POST['objectID'][1] = $taskID;
$_POST['work'][1] = str_replace('<br />', "\n", $action->comment);
if(is_dir($this->app->getModuleRoot() . 'effort'))
if($this->config->edition != 'open')
{
$this->loadModel('effort')->batchCreate();
}
+1
View File
@@ -148,6 +148,7 @@ class reportModel extends model
->leftJoin(TABLE_PROGRAM)->alias('t2')->on('t1.program = t2.id')
->where('t1.deleted')->eq(0)
->andWhere('t1.shadow')->eq(0)
->andWhere('t1.vision')->eq('rnd')
->beginIF(strpos($conditions, 'closedProduct') === false)->andWhere('t1.status')->ne('closed')->fi()
->beginIF(!$permission)->andWhere('t1.id')->in($this->app->user->view->products)->fi()
->orderBy('t2.order_asc, t1.line_desc, t1.order_asc')
+4 -2
View File
@@ -5,7 +5,7 @@
.row a:hover {color: #3c4353;}
.screen {border-radius: 4px; border: solid 1px #ddd; margin-bottom: 20px; position: relative;}
.screen {border-radius: 4px; border: solid 1px #ddd; position: relative;}
.screen .top {text-align: center; min-height:182px; position:relative;}
.screen .top.img {height: 182px; text-align: center;}
.screen .top.img img {height:100%; overflow: hidden; object-fit: cover; object-position: top;}
@@ -28,4 +28,6 @@
.bg6 {background:#0abbad;}
.main-col {background-color: white;}
.main-col .row {margin:10px 0px;}
.main-col .row {margin:10px 0px; padding: 12px;}
.main-col .row .col-md-3 {padding: 8px;}
.main-col .row .col-md-3 a {min-width: 297px;}
+6 -5
View File
@@ -1,11 +1,12 @@
.header {display:flex; justify-content:center; }
.img-header {width:1300px; height:120px; background-image:url("static/images/screen_header.png"); background-repeat:no-repeat;}
.title {padding-top:39px; padding-left:525px; white-space:nowrap; color:#B2D5E5; font-family: "Helvetica Neue",Helvetica,Tahoma,Arial,'PingFang SC','Source Han Sans CN','Source Han Sans','Source Han Serif','Hiragino Sans GB','WenQuanYi Micro Hei','Microsoft YaHei',sans-serif; letter-spacing:5px;}
.img-header {width:1342px; height: 129px; background-image:url("static/images/screen_header.png"); background-repeat:no-repeat;}
.title {padding-top:39px; padding-left: 615px; white-space:nowrap; color:#B2D5E5; font-family: "Helvetica Neue",Helvetica,Tahoma,Arial,'PingFang SC','Source Han Sans CN','Source Han Sans','Source Han Serif','Hiragino Sans GB','WenQuanYi Micro Hei','Microsoft YaHei',sans-serif; letter-spacing:5px;}
.time {position:absolute; right:10px; top:30px; color:#eee}
body {background:rgb(0,16,40);}
.content {display:flex; justify-content:center; margin-top: 20px;}
.burn {width: 1300px; display: flex; flex-wrap: wrap; justify-content: space-around; padding: 10px 0;}
.burn > .container {flex: 0 0 33%; margin-top: 40px; height: 370px; width: 370px; background-image:url("static/images/burn_bg.png"); background-repeat:no-repeat; background-size: 100% 100%}
.content {display: flex; justify-content: center;}
.burn {width: 1300px; display: flex; flex-wrap: wrap; justify-content: space-around; padding: 20px 0;}
.burn > .container {flex: 0 0 33%; margin-top: 20px; height: 370px; width: 370px; background-image:url("static/images/burn_bg.png"); background-repeat:no-repeat; background-size: calc(100% - 14px) calc(100%); left: 7px;}
.burn > .container canvas{max-width: calc(100% - 15px); max-height: calc(100% - 15px);}
.content .table-empty-tip {background: transparent; padding-right: 75px;}
+2 -2
View File
@@ -841,8 +841,8 @@ class screenModel extends model
$deadline = $execution->status == 'closed' ? substr($execution->closedDate, 0, 10) : $execution->suspendedDate;
$deadline = strpos('closed,suspended', $execution->status) === false ? helper::today() : $deadline;
$endDate = strpos($type, 'withdelay') !== false ? $deadline : $execution->end;
list($dateList, $interval) = $this->execution->getDateList($execution->begin, $endDate, $type, 0, 'Y-m-d', $execution->end);
$endDate = (strpos($type, 'withdelay') !== false and $deadline > $execution->end) ? $deadline : $execution->end;
list($dateList, $interval) = $this->execution->getDateList($execution->begin, $endDate, $type, 0, 'Y-m-d', $deadline);
$executionEnd = strpos($type, 'withdelay') !== false ? $execution->end : '';
$chartData = $this->execution->buildBurnData($executionID, $dateList, $type, 'left', $executionEnd);
+23 -2
View File
@@ -1,10 +1,15 @@
<?php include $app->getModuleRoot() . 'common/view/header.lite.html.php';?>
<?php include $app->getModuleRoot() . 'common/view/chart.html.php';?>
<?php js::import($jsRoot . 'echarts/echarts.common.min.js');?>
<?php js::import($jsRoot . 'echarts/timeline.min.js');?>
<?php js::set('executions', $executions);?>
<?php js::set('burnXUnit', $lang->execution->burnXUnit);?>
<?php js::set('burnYUnit', $lang->execution->burnYUnit);?>
<?php js::set('workHour', $lang->execution->workHour);?>
<?php js::set('workHourUnit', $lang->execution->workHourUnit);?>
<div class='header'>
<div class='img-header'>
<h2 class='title'>迭代燃尽图大屏</h2>
<h2 class='title'><?php echo $screen->name;?></h2>
<span class='time'><?php echo '更新时间:' . $date;?></span>
</div>
</div>
@@ -34,13 +39,15 @@ function initBurnChar()
var option = {
title: {
text: execution.name,
top: 10,
textStyle: {
color: '#a1c4e9',
fontSize: 15
}
},
tooltip: {
trigger: 'axis'
trigger: 'axis',
valueFormatter: (value) => (value == undefined ? 0 : value) + ' ' + workHour + '/' + workHourUnit
},
legend: {
data: ["<?php echo $lang->execution->charts->burn->graph->actuality;?>","<?php echo $lang->execution->charts->burn->graph->reference;?>"],
@@ -48,12 +55,14 @@ function initBurnChar()
color: '#dee0e4',
fontSize: 14
},
top: 10,
right: 0
},
color: ['#42526a', '#2567cf', 'red'],
grid: {
left: '3%',
right: '4%',
top: 65,
bottom: '3%',
containLabel: true
},
@@ -64,6 +73,11 @@ function initBurnChar()
},
xAxis: {
type: 'category',
name: burnXUnit,
nameTextStyle:{
padding: [20, 0, 0, -40],
verticalAlign: "top"
},
boundaryGap: false,
axisLabel: {
show: true,
@@ -75,12 +89,19 @@ function initBurnChar()
},
yAxis: {
type: 'value',
name: burnYUnit,
nameTextStyle:{
padding: [0, 0, -40, -45]
},
axisLabel: {
show: true,
textStyle: {
color: '#dee0e4'
}
},
axisLine: {
show: true
},
splitLine: {
show: true,
lineStyle:{
+3 -4
View File
@@ -1552,7 +1552,7 @@ class story extends control
if($story->parent > 0)
{
$this->story->updateParentStatus($story->id);
$this->loadModel('action')->create('story', $task->parent, 'deleteChildrenStory', '', $storyID);
$this->action->create('story', $story->parent, 'deleteChildrenStory', '', $storyID);
}
$this->executeHooks($storyID);
@@ -2200,8 +2200,8 @@ class story extends control
*/
public function batchChangeBranch($branchID, $confirm = '', $storyIdList = '', $storyType = 'story')
{
if(empty($_POST['storyIdList'])) return print(js::locate($this->session->storyList, 'parent'));
$storyIdList = $this->post->storyIdList;
if(empty($storyIdList) and empty($_POST['storyIdList'])) return print(js::locate($this->session->storyList, 'parent'));
if(!empty($_POST['storyIdList'])) $storyIdList = $this->post->storyIdList;
$plans = $this->loadModel('productplan')->getPlansByStories($storyIdList);
if(empty($confirm))
{
@@ -2466,7 +2466,6 @@ class story extends control
/* Get story, product, products, and queryID. */
$story = $this->story->getById($storyID);
$products = $this->product->getPairs('', 0, '', 'all');
$queryID = 0;
$product = $this->product->getByID($story->product);
/* Change for requirement story title. */
-1
View File
@@ -237,7 +237,6 @@ class storyModel extends model
->setIF(!in_array($this->post->source, $this->config->story->feedbackSource), 'notifyEmail', '')
->setIF($executionID > 0, 'stage', 'projected')
->setIF($bugID > 0, 'fromBug', $bugID)
->setIF($this->post->assignedTo, 'assignedDate', helper::now())
->join('assignedTo', '')
->join('mailto', ',')
->stripTags($this->config->story->editor->create['id'], $this->config->allowedTags)
+4 -2
View File
@@ -59,7 +59,7 @@ foreach(explode(',', $config->story->create->requiredFields) as $field)
<?php if($branches and $type != 'story') echo html::select('branch', $branches, $branch, "onchange='loadBranch();' class='form-control chosen control-branch'");?>
</div>
</td>
<?php if(!((!$branches and $type == 'story') or $type == 'requirement')):?>
<?php if($branches and $type == 'story'):?>
<td colspan='2' id='assignedToBox' class="switchBranch">
<div class='input-group'>
<div class="input-group-addon assignedTo"><?php echo $lang->story->assignedTo;?></div>
@@ -128,7 +128,8 @@ foreach(explode(',', $config->story->create->requiredFields) as $field)
<i class="icon-exclamation-sign"></i> <?php echo $lang->story->notice->branch;?>
</td>
</tr>
<tr class='<?php if($branches) echo "hidden"; ?> switchBranch'>
<?php if(!$branches):?>
<tr class='switchBranch'>
<?php if(!$hiddenPlan):?>
<th class='planTh'><?php echo $lang->story->planAB;?></th>
<td colspan="2">
@@ -159,6 +160,7 @@ foreach(explode(',', $config->story->create->requiredFields) as $field)
</div>
</td>
</tr>
<?php endif;?>
<tr class='sourceBox <?php echo $hiddenSource;?>'>
<th><?php echo $lang->story->source;?></th>
<td colspan='2'>
+3 -5
View File
@@ -9,8 +9,6 @@
* @version $Id: model.php 5149 2013-07-16 01:47:01Z zhujinyonging@gmail.com $
* @link http://www.zentao.net
*/
?>
<?php
class treeModel extends model
{
/**
@@ -204,7 +202,7 @@ class treeModel extends model
}
ksort($treeMenu);
$topMenu = @array_shift($treeMenu);
$topMenu = array_shift($treeMenu);
$topMenu = explode("\n", trim((string)$topMenu));
$lastMenu[] = '/';
foreach($topMenu as $menu)
@@ -348,7 +346,7 @@ class treeModel extends model
}
ksort($treeMenu);
$topMenu = @array_shift($treeMenu);
$topMenu = array_shift($treeMenu);
$topMenu = explode("\n", trim((string)$topMenu));
foreach($topMenu as $menu)
{
@@ -2367,7 +2365,7 @@ class treeModel extends model
if($data->createType == 'same')
{
$this->dao->update(TABLE_MODULE)
->set('`order`')->eq('`order` + 10')
->set('`order` = `order` + 10')
->where('deleted')->eq(0)
->andWhere('`root`')->eq($module->root)
->andWhere('`parent`')->eq($module->parent)
+19 -7
View File
@@ -109,13 +109,14 @@ class personnelTest
}
/**
* getUserEffortHoursTest
* GetUserHoursTest
*
* @param mixed $projectID
* @param mixed $projectID
* @param array $accounts
* @access public
* @return void
*/
public function getUserEffortHoursTest($projectID)
public function getUserHoursTest($projectID, $accounts)
{
global $tester;
$projects = $tester->dao->select('id')->from(TABLE_PROJECT)->where('id')->in($projectID)->fetchall('id');
@@ -124,6 +125,17 @@ class personnelTest
->andWhere('deleted')->eq('0')
->fetchAll('id');
/* Initialize personnel related tasks. */
$invest = array();
foreach($accounts as $account)
{
$invest[$account]['createdTask'] = 0;
$invest[$account]['finishedTask'] = 0;
$invest[$account]['pendingTask'] = 0;
$invest[$account]['consumedTask'] = 0;
$invest[$account]['leftTask'] = 0;
}
$userTasks = array();
foreach($tasks as $task)
@@ -131,23 +143,23 @@ class personnelTest
if($task->openedBy && isset($invest[$task->openedBy]))
{
$invest[$task->openedBy]['createdTask'] += 1;
$userTasks[$task->openedBy][$task->id] = $task->id;
$userTasks[$task->openedBy][$task->id] = $task->id;
}
if($task->finishedBy && isset($invest[$task->finishedBy]))
{
$invest[$task->finishedBy]['finishedTask'] += 1;
$userTasks[$task->finishedBy][$task->id] = $task->id;
$userTasks[$task->finishedBy][$task->id] = $task->id;
}
if($task->assignedTo && $task->status == 'wait' && isset($invest[$task->assignedTo]))
{
$invest[$task->assignedTo]['pendingTask'] += 1;
$userTasks[$task->assignedTo][$task->id] = $task->id;
$userTasks[$task->assignedTo][$task->id] = $task->id;
}
}
$objects = $this->objectModel->getUserEffortHours($userTasks);
$objects = $this->objectModel->getUserHours($userTasks);
if(dao::isError()) return dao::getError();
@@ -1,28 +0,0 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/personnel.class.php';
su('admin');
/**
title=测试 personnelModel->getUserEffortHours();
cid=1
pid=1
正常传入的情况 >> 0
传入不存在的情况 >> 0
*/
$personnel = new personnelTest('admin');
$projectID = array();
$projectID[0] = 11;
$projectID[1] = 11111;
$result1 = $personnel->getUserEffortHoursTest($projectID[0]);
$result2 = $personnel->getUserEffortHoursTest($projectID[1]);
r($result1) && p() && e('0'); //正常传入的情况
r($result2) && p() && e('0'); //传入不存在的情况
+56
View File
@@ -0,0 +1,56 @@
#!/usr/bin/env php
<?php
include dirname(dirname(dirname(__FILE__))) . '/lib/init.php';
include dirname(dirname(dirname(__FILE__))) . '/class/personnel.class.php';
su('admin');
$project = zdTable('project');
$project->id->range('1-10');
$project->project->range('0,0,2{8}');
$project->type->range('program,project,sprint{8}');
$project->status->range('doing{3},wait{7}');
$project->vision->range('rnd');
$project->name->range('1-10')->prefix('Object');
$project->multiple->range('1');
$project->deleted->range('`0`');
$project->gen(10);
$task = zdTable('task');
$task->id->range('1');
$task->name->range('task1');
$task->project->range('2');
$task->type->range('dev');
$task->left->range('1');
$task->openedBy->range('admin');
$task->consumed->range('5');
$task->deleted->range('`0`');
$task->gen(1);
$effort = zdTable('effort');
$effort->id->range('1-2');
$effort->objectType->range('task');
$effort->objectID->range('1');
$effort->account->range('admin');
$effort->left->range('7,1');
$effort->consumed->range('2,3');
$effort->deleted->range('`0`');
$effort->gen(2);
/**
title=测试 personnelModel->getUserHours();
cid=1
pid=1
正常传入的情况 >> 1
传入不存在的情况 >> 0
*/
$personnel = new personnelTest('admin');
$result1 = $personnel->getUserHoursTest('2', array('admin'));
$result2 = $personnel->getUserHoursTest('100', array('admin'));
r($result1['admin']->left) && p() && e('1'); //正常传入的情况
r($result2) && p() && e('0'); //传入不存在的情况
Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

+6
View File
@@ -0,0 +1,6 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.6494 3.36914L-0.00015831 3.36914L2.53372 0.00097272L11.1098 0.000973661L13.6494 3.36914Z" fill="#FFE2E0"/>
<path d="M0.000976562 3.37109H13.6505V11.6519C13.6505 12.7564 12.7551 13.6519 11.6505 13.6519H2.00098C0.896408 13.6519 0.000976562 12.7564 0.000976562 11.6519V3.37109Z" fill="#FC918A"/>
<rect x="6.60254" y="0.580078" width="0.584982" height="2.00158" rx="0.292491" fill="white"/>
<path d="M5.45182 9.64949C5.37048 9.56815 5.38404 9.44615 5.45182 9.36481L6.8074 8.00924C6.90229 7.91435 6.91584 7.75168 6.8074 7.62967C6.69895 7.50767 6.50917 7.52123 6.40072 7.62967L4.76047 9.29704C4.39446 9.66304 4.39446 10.2731 4.76047 10.6391L4.77403 10.6526C5.14003 11.0186 5.75004 11.0186 6.11605 10.6526L9.05766 7.71101C9.42366 7.345 9.42366 6.73499 9.05766 6.36899L9.0441 6.35543C8.67809 5.98942 8.06808 5.98942 7.70208 6.35543L7.68852 6.36899C7.62074 6.43676 7.52585 6.45032 7.44452 6.3961C7.2954 6.31476 7.13273 6.24698 6.97006 6.20632C6.86162 6.17921 6.83451 6.0572 6.90229 5.97587C7.01073 5.86742 7.11918 5.77253 7.11918 5.77253C7.81052 5.08119 8.93565 5.08119 9.627 5.77253L9.627 5.79964C10.3183 6.49099 10.3183 7.61612 9.627 8.30746L6.69895 11.2491C6.0076 11.9404 4.88247 11.9404 4.19113 11.2491L4.16402 11.222C3.47267 10.5306 3.47267 9.41904 4.16402 8.72769L5.83138 7.04678C6.26516 6.61299 6.97006 6.62655 7.40385 7.07389C7.82408 7.50767 7.79697 8.21257 7.36318 8.6328L6.03472 9.96127C5.95338 10.0426 5.81782 10.0426 5.73649 9.96127L5.45182 9.64949Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

+7
View File
@@ -0,0 +1,7 @@
<svg width="17" height="17" viewBox="0 0 17 17" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.42969 1.40625C3.42969 0.853965 3.8774 0.40625 4.42969 0.40625H15.4297C15.982 0.40625 16.4297 0.853965 16.4297 1.40625V11.4062C16.4297 11.9585 15.982 12.4062 15.4297 12.4062H4.42969C3.8774 12.4062 3.42969 11.9585 3.42969 11.4062V1.40625Z" fill="#FFE2E0"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.42969 5.30261H14.2868V4.07812H7.42969V5.30261ZM7.42969 8.36316H14.2868V7.13867H7.42969V8.36316Z" fill="white"/>
<path d="M0.429688 4.28711C0.429688 3.73482 0.877403 3.28711 1.42969 3.28711H8.57254C9.12483 3.28711 9.57254 3.73482 9.57254 4.28711V14.8585C9.57254 15.4108 9.12483 15.8585 8.57254 15.8585H0.429688V4.28711Z" fill="#FC918A"/>
<path d="M6.14453 3.28711H9.5731V6.71568L7.85882 5.00139L6.14453 3.28711Z" fill="#E6716A"/>
<path d="M6.82969 0.8125C5.5042 0.8125 4.42969 1.88702 4.42969 3.2125V10.4125C4.42969 10.9841 4.73465 11.5123 5.22969 11.7981C5.72473 12.084 6.33465 12.084 6.82969 11.7981C7.32473 11.5123 7.62969 10.9841 7.62969 10.4125V6.14583C7.62969 5.95529 7.52803 5.77922 7.36302 5.68395C7.19801 5.58868 6.9947 5.58868 6.82969 5.68395C6.66467 5.77922 6.56302 5.95529 6.56302 6.14583V10.4125C6.56302 10.603 6.46137 10.7791 6.29635 10.8744C6.13134 10.9697 5.92803 10.9697 5.76302 10.8744C5.59801 10.7791 5.49635 10.603 5.49635 10.4125V3.2125C5.49635 2.47612 6.09331 1.87917 6.82969 1.87917C7.56607 1.87917 8.16302 2.47612 8.16302 3.2125V3.32089H9.22969V3.2125C9.22969 1.88702 8.15517 0.8125 6.82969 0.8125Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

+7
View File
@@ -0,0 +1,7 @@
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.35742 0.999999C4.35742 0.723857 4.58128 0.5 4.85742 0.5H15.4289C15.705 0.5 15.9289 0.723857 15.9289 1V13.8571C15.9289 14.1333 15.705 14.3571 15.4288 14.3571H4.85742C4.58128 14.3571 4.35742 14.1333 4.35742 13.8571V0.999999Z" stroke="#B1ECD6"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.9997 4.89636H6.14258V3.67188H12.9997V4.89636ZM12.9997 7.95678H6.14258V6.73229H12.9997V7.95678ZM6.14258 11.0193H12.9997V9.79479H6.14258V11.0193Z" fill="#D0F6E8"/>
<path d="M0.429688 3.28516C0.429688 2.73287 0.877403 2.28516 1.42969 2.28516H8.57254C9.12483 2.28516 9.57254 2.73287 9.57254 3.28516V13.8566C9.57254 14.4089 9.12483 14.8566 8.57254 14.8566H0.429688V3.28516Z" fill="#7ADFBA"/>
<path d="M8.21237 3.64589L7.35164 2.78516H9.0731V4.50662L8.21237 3.64589Z" fill="#FDFDFD" stroke="#22C98D"/>
<path d="M4.25952 9.26697L2.90045 11.4291H1.57227L3.57999 8.46388L1.69582 5.71484H3.20933L4.38308 7.66079L5.6186 5.71484H6.91589L5.03172 8.46388L7.03945 11.4291H5.52593L4.25952 9.26697Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

+10
View File
@@ -0,0 +1,10 @@
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.42969 1C3.42969 0.447715 3.8774 0 4.42969 0H15.4297C15.982 0 16.4297 0.447715 16.4297 1V11C16.4297 11.5523 15.982 12 15.4297 12H4.42969C3.8774 12 3.42969 11.5523 3.42969 11V1Z" fill="#D0F2FA"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.42969 4.89636H14.2868V3.67188H7.42969V4.89636ZM7.42969 7.95691H14.2868V6.73242H7.42969V7.95691Z" fill="white"/>
<path d="M0.429688 3.88086C0.429688 3.32857 0.877403 2.88086 1.42969 2.88086H8.57254C9.12483 2.88086 9.57254 3.32857 9.57254 3.88086V14.4523C9.57254 15.0046 9.12483 15.4523 8.57254 15.4523H0.429688V3.88086Z" fill="#64D7F0"/>
<path d="M6.14453 2.88086H9.5731V6.30943L7.85882 4.59514L6.14453 2.88086Z" fill="#4DBDD6"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.37694 8.0572L6.62306 8.0572L6.62306 8.40996C6.62306 9.08028 6.03413 9.62369 5.30766 9.62369L4.69234 9.62369C3.96587 9.62369 3.37694 9.08028 3.37694 8.40996L3.37694 8.0572ZM7.5 7.24805L7.5 8.40996C7.5 9.52717 6.51845 10.4328 5.30766 10.4328L4.69234 10.4328C3.48155 10.4328 2.5 9.52717 2.5 8.40996L2.5 7.24805L7.5 7.24805Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.35449 6.42196L4.35449 7.45312L3.41736 7.45312L3.41736 6.42196L4.35449 6.42196Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.58203 6.42196L6.58203 7.45312L5.6449 7.45312L5.6449 6.42196L6.58203 6.42196Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.53161 12.1973L4.53161 10.2453L5.46875 10.2453L5.46875 12.1973L4.53161 12.1973Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

+9
View File
@@ -0,0 +1,9 @@
<svg width="14" height="15" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.6494 3.81836L-0.00015831 3.81836L2.53372 0.450191L11.1098 0.450192L13.6494 3.81836Z" fill="#D0F2FA"/>
<path d="M0.000976562 3.82031H13.6505V12.1011C13.6505 13.2057 12.7551 14.1011 11.6505 14.1011H2.00098C0.896408 14.1011 0.000976562 13.2057 0.000976562 12.1011V3.82031Z" fill="#64D7F0"/>
<rect x="6.3252" y="1.0293" width="1" height="2.00158" rx="0.5" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.09352 7.72671L8.5574 7.72671L8.5574 8.10314C8.5574 8.81843 7.92897 9.39829 7.15375 9.39829L6.49717 9.39829C5.72195 9.39829 5.09352 8.81843 5.09352 8.10314L5.09352 7.72671ZM9.49316 6.86328L9.49316 8.10314C9.49316 9.29529 8.44577 10.2617 7.15375 10.2617L6.49717 10.2617C5.20515 10.2617 4.15776 9.29529 4.15776 8.10314L4.15776 6.86328L9.49316 6.86328Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.13672 5.98365L6.13672 7.08398L5.13672 7.08398L5.13672 5.98365L6.13672 5.98365Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.51367 5.98365L8.51367 7.08398L7.51367 7.08398L7.51367 5.98365L8.51367 5.98365Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.3252 12.1465L6.3252 10.0636L7.3252 10.0636L7.3252 12.1465L6.3252 12.1465Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

+7
View File
@@ -0,0 +1,7 @@
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.35742 0.999999C4.35742 0.723857 4.58128 0.5 4.85742 0.5H15.4289C15.705 0.5 15.9289 0.723857 15.9289 1V13.8571C15.9289 14.1333 15.705 14.3571 15.4288 14.3571H4.85742C4.58128 14.3571 4.35742 14.1333 4.35742 13.8571V0.999999Z" stroke="#FFD2A9"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.9997 4.89636H6.14258V3.67188H12.9997V4.89636ZM12.9997 7.95678H6.14258V6.73229H12.9997V7.95678ZM6.14258 11.0193H12.9997V9.79479H6.14258V11.0193Z" fill="#FFECDB"/>
<path d="M0.429688 3.28516C0.429688 2.73287 0.877403 2.28516 1.42969 2.28516H8.57254C9.12483 2.28516 9.57254 2.73287 9.57254 3.28516V13.8566C9.57254 14.4089 9.12483 14.8566 8.57254 14.8566H0.429688V3.28516Z" fill="#FFBC7E"/>
<path d="M8.21237 3.64589L7.35164 2.78516H9.0731V4.50662L8.21237 3.64589Z" fill="#FDFDFD" stroke="#FF9F46"/>
<path d="M4.16741 11.4291H2.96289V5.71537H4.72335C6.26761 5.69478 7.03974 6.2816 7.03974 7.47582C6.99856 8.58769 6.33967 9.17451 5.06308 9.23628H4.16741V11.4291ZM4.16741 6.67281V8.27884C4.22918 8.27884 4.35272 8.28913 4.53804 8.30972C5.36164 8.39208 5.76315 8.11412 5.74256 7.47582C5.74256 6.91989 5.34105 6.65222 4.53804 6.67281C4.35272 6.6934 4.22918 6.6934 4.16741 6.67281Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

+6
View File
@@ -0,0 +1,6 @@
<svg width="14" height="15" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.6494 3.80273L-0.00015831 3.80273L2.53372 0.434566L11.1098 0.434567L13.6494 3.80273Z" fill="#E5E5FF"/>
<path d="M0.000976562 3.80469H13.6505V12.0855C13.6505 13.19 12.7551 14.0855 11.6505 14.0855H2.00098C0.896408 14.0855 0.000976562 13.19 0.000976562 12.0855V3.80469Z" fill="#9394F9"/>
<rect x="6.3252" y="1.01367" width="1" height="2.00158" rx="0.5" fill="white"/>
<path d="M5.4238 11.4652H4.38867L6.21376 6.42578H7.49404L9.26465 11.4652H8.17504L7.79368 10.4028H5.80516L5.4238 11.4652ZM6.07756 9.55839H7.52128L6.84028 7.40642H6.81304L6.07756 9.55839Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 682 B

+7
View File
@@ -0,0 +1,7 @@
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.42969 1C3.42969 0.447715 3.8774 0 4.42969 0H15.4297C15.982 0 16.4297 0.447715 16.4297 1V11C16.4297 11.5523 15.982 12 15.4297 12H4.42969C3.8774 12 3.42969 11.5523 3.42969 11V1Z" fill="#E6E6FF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.42969 4.89636H14.2868V3.67188H7.42969V4.89636ZM7.42969 7.95691H14.2868V6.73242H7.42969V7.95691Z" fill="white"/>
<path d="M0.429688 3.88086C0.429688 3.32857 0.877403 2.88086 1.42969 2.88086H8.57254C9.12483 2.88086 9.57254 3.32857 9.57254 3.88086V14.4523C9.57254 15.0046 9.12483 15.4523 8.57254 15.4523H0.429688V3.88086Z" fill="#9394F9"/>
<path d="M3.46481 12.0394H2.42969L4.25477 7H5.53506L7.30566 12.0394H6.21606L5.8347 10.9771H3.84617L3.46481 12.0394ZM4.11857 10.1326H5.5623L4.8813 7.98064H4.85406L4.11857 10.1326Z" fill="white"/>
<path d="M6.14453 2.88086H9.5731V6.30943L7.85882 4.59514L6.14453 2.88086Z" fill="#7475EE"/>
</svg>

After

Width:  |  Height:  |  Size: 985 B

+7
View File
@@ -0,0 +1,7 @@
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M4.35742 1.5957C4.35742 1.31956 4.58128 1.0957 4.85742 1.0957H15.4289C15.705 1.0957 15.9289 1.31956 15.9289 1.5957V14.4528C15.9289 14.729 15.705 14.9528 15.4288 14.9528H4.85742C4.58128 14.9528 4.35742 14.729 4.35742 14.4528V1.5957Z" stroke="#A4C7FF"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.9997 5.49207H6.14258V4.26758H12.9997V5.49207ZM12.9997 8.55248H6.14258V7.32799H12.9997V8.55248ZM6.14258 11.615H12.9997V10.3905H6.14258V11.615Z" fill="#E6F0FF"/>
<path d="M0.429688 3.88086C0.429688 3.32857 0.877403 2.88086 1.42969 2.88086H8.57254C9.12483 2.88086 9.57254 3.32857 9.57254 3.88086V14.4523C9.57254 15.0046 9.12483 15.4523 8.57254 15.4523H0.429688V3.88086Z" fill="#66A2FF"/>
<path d="M3.72167 10.365L4.54453 6.78711H5.5731L6.30453 10.365H6.32739L7.0131 6.78711H7.85882L6.78453 11.549H5.77882L5.02453 7.91967L4.20167 11.549H3.1731L2.14453 6.78711H3.08167L3.72167 10.365Z" fill="#FDFDFD"/>
<path d="M8.21237 4.24159L7.35164 3.38086H9.0731V5.10232L8.21237 4.24159Z" fill="#66A2FF" stroke="#3785FF"/>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because one or more lines are too long
Binary file not shown.
+1
View File
@@ -259,6 +259,7 @@
<glyph unicode="&#xe9ec;" glyph-name="design" d="M1022.95 548.083l-255.488 255.488-255.486-255.488-255.489 255.488-255.488-255.488 255.488-255.489-255.488-255.486v-255.488h255.488l255.489 255.488 255.486-255.488 255.488 255.488-255.488 255.486 255.488 255.489zM262.888 375.603l108.544 108.608-44.672 44.736-108.609-108.608-38.336 38.336 115.009 114.881-51.136 44.799-108.545-115.007-44.8 44.672 166.144 166.079 210.689-210.688-166.016-166.080-38.272 38.272zM64.872-154.507v127.744l127.743-127.744h-127.743zM256.488-128.971l-166.080 166.080 677.119 677.119 166.016-166.144-677.055-677.055zM933.606 37.109l-166.144-166.080-44.672 44.736 114.944 114.944-44.736 44.736-114.944-115.008-38.334 38.336 115.006 114.944-51.136 44.8-114.942-115.008-38.401 38.272 166.143 166.078 217.216-210.75z" />
<glyph unicode="&#xe9ed;" glyph-name="waterfallplus" horiz-adv-x="956" d="M477.827 706.371c226.214 0 409.599-183.384 409.599-409.6h68.267c0 263.919-213.948 477.867-477.865 477.867h-68.267v-136.534h68.267v68.267zM477.827-181.097c-240.74 0-439.902 178.019-473.027 409.601h69.090c32.5-193.722 200.98-341.335 403.937-341.335v68.267h68.267v-136.533h-68.267zM136.533 467.437h341.333v-68.267h-341.333v68.267zM546.133 399.171v136.533h-477.867v-204.8h409.6v-68.267h-68.267v-204.801h477.867v204.801h-341.333v136.533zM477.867 194.371h341.333v-68.267h-341.333v68.267z" />
<glyph unicode="&#xe9ee;" glyph-name="agileplus" horiz-adv-x="956" d="M887.467 296.771c0 226.216-183.385 409.6-409.6 409.6v-68.267h-68.267v136.534h68.267c263.919 0 477.867-213.948 477.867-477.867h-68.267zM0 296.771c0-263.92 213.948-477.868 477.867-477.868h68.267v136.533h-68.267v-68.267c-226.216 0-409.6 183.385-409.6 409.601h-68.267zM204.8 91.969v68.268h273.067c75.405 0 136.533 61.128 136.533 136.533s-61.128 136.533-136.533 136.533c-75.405 0-136.533-61.128-136.533-136.533h-68.267c0 113.108 91.692 204.8 204.8 204.8s204.8-91.692 204.8-204.8c0-52.453-19.719-100.3-52.148-136.533h120.415v-68.268h-546.133z" />
<glyph unicode="&#xe9ef;" glyph-name="icon-add-directory" d="M768 658.285v-182.857h182.857v-73.143h-182.857v-182.857h-73.143v182.857h-182.857v73.143h182.857v182.857h73.143zM73.143 0v-73.143h877.714v73.143h-877.714zM438.857 256h-365.714v73.143h365.714v-73.143zM73.143 585.142h365.714v73.143h-365.714v-73.143z" />
<glyph unicode="&#xf016;" glyph-name="file, file-empty" horiz-adv-x="878" d="M838.857 587.428c21.143-21.143 38.857-63.429 38.857-93.714v-658.286c0-30.286-24.571-54.857-54.857-54.857h-768c-30.286 0-54.857 24.571-54.857 54.857v914.286c0 30.286 24.571 54.857 54.857 54.857h512c30.286 0 72.571-17.714 93.714-38.857zM585.143 726.857v-214.857h214.857c-3.429 9.714-8.571 19.429-12.571 23.429l-178.857 178.857c-4 4-13.714 9.143-23.429 12.571zM804.571-146.286v585.143h-237.714c-30.286 0-54.857 24.571-54.857 54.857v237.714h-438.857v-877.714h731.429z" />
<glyph unicode="&#xf02d;" glyph-name="book" d="M948.764 510.653c13.529-19.482 17.318-44.918 9.741-69.81l-148.822-490.3c-13.529-45.999-61.152-81.716-107.693-81.716h-499.501c-55.199 0-114.186 43.835-134.21 100.116-8.658 24.352-8.658 48.165-1.083 68.728 1.083 10.823 3.248 21.647 3.789 34.635 0.541 8.658-4.329 15.694-3.248 22.188 2.165 12.988 13.529 22.188 22.188 36.799 16.235 27.058 34.635 70.893 40.587 99.033 2.706 10.281-2.706 22.188 0 31.388 2.706 10.281 12.988 17.859 18.401 27.6 14.612 24.894 33.554 73.058 36.259 98.493 1.083 11.364-4.329 23.811-1.083 32.471 3.789 12.447 15.694 17.859 23.811 28.682 12.988 17.859 34.635 69.269 37.881 97.952 1.083 9.199-4.329 18.401-2.706 28.14 2.165 10.281 15.153 21.106 23.811 33.554 22.728 33.554 27.058 107.693 95.787 88.211l-0.541-1.623c9.199 2.165 18.401 4.871 27.6 4.871h411.831c25.434 0 48.165-11.364 61.694-30.306 14.070-19.482 17.318-44.918 9.741-70.352l-148.281-490.3c-25.434-83.34-39.505-101.74-108.235-101.74h-470.277c-7.035 0-15.694-1.623-20.565-8.117-4.329-6.495-4.871-11.364-0.541-23.269 10.823-31.388 48.165-37.881 77.93-37.881h499.501c20.024 0 43.293 11.364 49.247 30.846l162.352 534.135c3.248 10.281 3.248 21.106 2.706 30.846 12.447-4.871 23.811-12.447 31.929-23.269zM372.959 509.57c-3.248-9.741 2.165-17.318 11.905-17.318h329.032c9.199 0 19.482 7.576 22.728 17.318l11.364 34.635c3.248 9.741-2.165 17.318-11.905 17.318h-329.032c-9.199 0-19.482-7.576-22.728-17.318zM328.043 371.031c-3.248-9.741 2.165-17.318 11.905-17.318h329.032c9.199 0 19.482 7.576 22.728 17.318l11.364 34.635c3.248 9.741-2.165 17.318-11.905 17.318h-329.032c-9.199 0-19.482-7.576-22.728-17.318z" />
<glyph unicode="&#xf064;" glyph-name="share" d="M960.285 412.526c0-8.506-3.502-16.511-9.505-22.514l-256.163-256.163c-6.003-6.003-14.008-9.505-22.514-9.505-17.512 0-32.020 14.509-32.020 32.020v128.082h-112.072c-215.638 0-357.227-41.527-357.227-280.178 0-20.513 1.001-41.025 2.501-61.54 0.5-8.005 2.501-17.011 2.501-25.015 0-9.505-6.003-17.512-16.010-17.512-7.004 0-10.506 3.502-14.008 8.506-7.505 10.506-13.009 26.518-18.511 38.025-28.517 64.041-63.54 155.598-63.54 225.643 0 56.036 5.504 113.572 26.518 166.606 69.545 172.609 273.673 201.628 437.778 201.628h112.072v128.082c0 17.512 14.509 32.020 32.020 32.020 8.506 0 16.511-3.502 22.514-9.505l256.163-256.163c6.003-6.003 9.505-14.008 9.505-22.514z" />

Before

Width:  |  Height:  |  Size: 268 KiB

After

Width:  |  Height:  |  Size: 268 KiB

Binary file not shown.
Binary file not shown.