This commit is contained in:
Catouse
2016-11-09 10:26:49 +08:00
23 changed files with 71 additions and 41 deletions
+9 -9
View File
@@ -7,7 +7,7 @@ ZenTao is practical and prgagmatic. It has full functions and a beautiful interf
ZenTao focuses on R & D project management!
2. Why are we called ZenTao?
2. Why called ZenTao?
============================
Zen(禅) and Tao(道) are the two Chinese words that have rich meanings in both religion and culture. ZenTao Project Management Software take the cutural meaning of Zen and Tao, and is expected to convey our understanding and thinking on management. Inspired by The Tao of Programming and The Zen of Programming, we named our software ZenTao.
@@ -15,14 +15,14 @@ Zen(禅) and Tao(道) are the two Chinese words that have rich meanings in both
3. Design philosophy of ZenTao Project Management Software
==========================================================
The main management philosophy of ZenTao Project Management Software is based on Scrum, an internationally popular agile management methodology. Scrum is very pragmatic and easy to operate, so it fits in the fast iterative software development projects. However, Scrum only defines the core management framework. There are still many details and processes that need to be extended and developed. Based on the philosophy of Scrum and the observation of the current R&D situation in China, ZenTao integrates bug management, test case management, release management and document management, and it covers the entire life cycle of software R&D. In ZenTao, the concept of product, project and test is clearly defined. Product team, development team and testing team coordinate and check with each other while they function differently. The three teams interact with each other through working on requirements, tasks and bugs, and eventually deliver the product with quality.
The main management philosophy of ZenTao Project Management Software is based on Scrum, an internationally popular agile management methodology. Scrum is very pragmatic and easy to operate, so it fits in the fast iterative software development projects. However, Scrum only defines the core management framework. There are still many details and processes that need to be extended and developed. Based on the philosophy of Scrum and the observation of the current R&D situation in China, ZenTao integrates bug management, test case management, release management and document management, and it covers the entire life cycle of software R&D. In ZenTao, the concept of product, project and test is clearly defined. Product team, development team and testing team coordinate and check with each other while they function differently. The three teams interact with each other through working on stories, tasks and bugs, and eventually deliver the product with quality.
4. Why choose ZenTao Project Management Software
4. Why choose ZenTao Project Management Software?
===============================================
* ZenTao is a professional R&D project management software and canot be replaced by simple project management software.
* ZenTao has precise and pragmatic management philosphy, which will accelerate agile development.
* ZenTao has full functions as a project man: you don’t need to integrate several systems together, like mantisbt + trac + testlink.
* ZenTao has full features as a project management software: you don’t need to integrate several systems together, like mantisbt + trac + testlink.
* Open source codes and flexible extension mechanism, convenient for uses and secondary development of companies.
* Underlying framework and front-end UI framework developed independently; robust and stable with beautiful interface and friendly interaction.
* Perfect community mechanism; you can get technical support and help in time.
@@ -30,18 +30,18 @@ The main management philosophy of ZenTao Project Management Software is based on
* Support various deployments, either private deployment or cloud services.
5. Function lists of ZenTao Project Management Software
5. Features of ZenTao Project Management Software
======================================================
* Product management: including products, requirements, plans, releases and roadmaps;
* Product management: including products, stories, plans, releases and roadmaps;
* Project management: including projects, tasks, teams, versions and burn-down charts;
* Quality management: including bus, test cases, test tasks and test results;
* Document management: including product document library, project document library and user-defined document library;
* Affair management: including to-do management and personal affairs management like my tasks, my bugs, my requirement and my projects;
* Document management: including product document library, project document library and customized document library;
* Affair management: including to-do management and personal management, such as my tasks, my bugs, my story and my projects;
* Organization management: including department, users, groups and authorities;
* Statistics function: various statistical reports;
* Search function: powerful search functions to help you find the data you need.
* Extension mechanism:extensible nearly anywhere in ZenTao;
* Extension mechanism:extensible almost anywhere in ZenTao;
* API mechanism, visible API: convenient for integration with other systems.
6. Website
+1 -1
View File
@@ -32,7 +32,7 @@ class model extends baseModel
public function delete($table, $id)
{
$this->dao->update($table)->set('deleted')->eq(1)->where('id')->eq($id)->exec();
$object = ltrim(strstr(trim($table, '`'), '_'), '_');
$object = preg_replace('/^' . preg_quote($this->config->db->prefix) . '/', '', trim($table, '`'));
$this->loadModel('action')->create($object, $id, 'deleted', '', $extra = ACTIONMODEL::CAN_UNDELETED);
}
}
+29 -4
View File
@@ -128,6 +128,7 @@ class doc extends control
$pager = new pager($recTotal, $recPerPage, $pageID);
/* Append id for secend sort. */
if($browseType == 'bymenu' and strtolower($orderBy) != 'editeddate_desc' and strtolower($orderBy) != 'addeddate_desc') $orderBy = 'title_asc';
$sort = $this->loadModel('common')->appendOrder($orderBy);
/* Get docs by browse type. */
@@ -145,7 +146,7 @@ class doc extends control
if($this->cookie->browseType == 'bymenu')
{
$this->view->modules = $this->doc->getDocMenu($libID, $moduleID);
$this->view->modules = $this->doc->getDocMenu($libID, $moduleID, $orderBy == 'title_asc' ? 'name_asc' : 'id_desc');
$this->view->parents = $this->loadModel('tree')->getParents($moduleID);
}
elseif($this->cookie->browseType == 'bytree')
@@ -704,23 +705,47 @@ class doc extends control
* @access public
* @return void
*/
public function showFiles($type, $objectID)
public function showFiles($type, $objectID, $recTotal = 0, $recPerPage = 20, $pageID = 1)
{
$uri = $this->app->getURI(true);
$this->app->session->set('taskList', $uri);
$this->app->session->set('storyList', $uri);
$this->app->session->set('docList', $uri);
/* According the from, set menus. */
if($this->from == 'product')
{
$this->lang->doc->menu = $this->lang->product->menu;
$this->lang->doc->menuOrder = $this->lang->product->menuOrder;
$this->product->setMenu($this->product->getPairs(), $objectID);
$this->lang->set('menugroup.doc', 'product');
}
elseif($this->from == 'project')
{
$this->lang->doc->menu = $this->lang->project->menu;
$this->lang->doc->menuOrder = $this->lang->project->menuOrder;
$this->project->setMenu($this->project->getPairs('nocode'), $objectID);
$this->lang->set('menugroup.doc', 'project');
}
else
{
$this->doc->setMenu(array($this->lang->doclib->files), 0, $type);
}
/* Load pager. */
$this->app->loadClass('pager', $static = true);
$pager = new pager($recTotal, $recPerPage, $pageID);
$table = $type == 'product' ? TABLE_PRODUCT : TABLE_PROJECT;
$object = $this->dao->select('id,name')->from($table)->where('id')->eq($objectID)->fetch();
$this->doc->setMenu(array($this->lang->doclib->files), 0, $type);
$this->view->title = $object->name;
$this->view->position[] = $object->name;
$this->view->type = $type;
$this->view->object = $object;
$this->view->files = $this->doc->getLibFiles($type, $objectID);
$this->view->files = $this->doc->getLibFiles($type, $objectID, $pager);
$this->view->pager = $pager;
$this->display();
}
+2 -2
View File
@@ -2,9 +2,9 @@
.lib-more a.more{font-weight:bold; display:block;}
#libs .libs-group-heading{border:1px solid #ddd;}
#libs .libs-group{border:1px solid #ddd; border-top:0px; margin-bottom:20px;}
#libs .libs-group.lib-more{border:0px; text-align:center; height:128px; line-height:110px;}
#libs .libs-group.lib-more{border:0px; text-align:center; height:120px; line-height:110px;}
#libs .libs-group.lib-more:hover{background-color: #EBF2F9}
#libs .libs-custom-heading{text-align:left; height:128px;}
#libs .libs-custom-heading{text-align:center; height:120px; line-height:110px;}
#libs .libs-custom-heading:hover{background-color: #EBF2F9}
#libs .libs-custom-heading a{display:block;height:100%;}
#libs hr {margin-top:0px;}
+3
View File
@@ -115,3 +115,6 @@ $lang->doclib->user = 'User';
$lang->doclib->files = 'Files';
$lang->doclib->all = 'All Libraries';
$lang->doclib->select = 'Select Library';
$lang->doclib->main['product'] = $lang->productCommon . ' Library';
$lang->doclib->main['project'] = $lang->projectCommon . ' Library';
+3
View File
@@ -115,3 +115,6 @@ $lang->doclib->user = '用户';
$lang->doclib->files = '附件库';
$lang->doclib->all = '所有文档库';
$lang->doclib->select = '选择文档库';
$lang->doclib->main['product'] = $lang->productCommon . '库';
$lang->doclib->main['project'] = $lang->projectCommon . '库';
+3 -2
View File
@@ -531,13 +531,14 @@ class docModel extends model
* @param int $libID
* @param int $parent
* @access public
* @return void
* @return array
*/
public function getDocMenu($libID, $parent)
public function getDocMenu($libID, $parent, $orderBy = 'name_asc')
{
return $this->dao->select('*')->from(TABLE_MODULE)->where('root')->eq($libID)
->andWhere('type')->eq('doc')
->andWhere('parent')->eq($parent)
->orderBy($orderBy)
->fetchAll('id');
}
+1 -2
View File
@@ -63,8 +63,7 @@
</div>
<?php endif; ?>
</div>
<div class='clearfix pager-wrapper'><?php $pager->show('left');?></div>
<?php js::set('type', $type);?>
<div class='clearfix pager-wrapper'><?php $pager->show();?></div>
<script>
$(function()
{
+1 -1
View File
@@ -47,7 +47,7 @@ var browseType = '<?php echo $browseType;?>';
<ul class="dropdown-menu" role="menu">
<li><?php echo html::a('javascript:setBrowseType("bylist")', "<i class='icon icon-list'></i> {$lang->doc->browseTypeList['list']}");?></li>
<li><?php echo html::a('javascript:setBrowseType("bymenu")', "<i class='icon icon-th'></i> {$lang->doc->browseTypeList['menu']}");?></li>
<li><?php echo html::a('javascript:setBrowseType("bytree")', "<i class='icon icon-tags'></i> {$lang->doc->browseTypeList['tree']}");?></li>
<li><?php echo html::a('javascript:setBrowseType("bytree")', "<i class='icon icon-branch'></i> {$lang->doc->browseTypeList['tree']}");?></li>
</ul>
</div>
<?php common::printIcon('doc', 'create', "libID=$libID&moduleID=$moduleID");?>
+1 -1
View File
@@ -53,7 +53,7 @@
<ul class="dropdown-menu" role="menu">
<li><?php echo html::a('javascript:setBrowseType("bylist")', "<i class='icon icon-list'></i> {$lang->doc->browseTypeList['list']}");?></li>
<li><?php echo html::a('javascript:setBrowseType("bymenu")', "<i class='icon icon-th'></i> {$lang->doc->browseTypeList['menu']}");?></li>
<li><?php echo html::a('javascript:setBrowseType("bytree")', "<i class='icon icon-tags'></i> {$lang->doc->browseTypeList['tree']}");?></li>
<li><?php echo html::a('javascript:setBrowseType("bytree")', "<i class='icon icon-branch'></i> {$lang->doc->browseTypeList['tree']}");?></li>
</ul>
</div>
<?php common::printIcon('doc', 'create', "libID=$libID&moduleID=$moduleID");?>
+2 -2
View File
@@ -45,11 +45,11 @@
</ul>
</div>
<div class="btn-group">
<button type="button" class="btn dropdown-toggle" data-toggle="dropdown"><i class='icon icon-tags'></i> <?php echo $lang->doc->browseTypeList['tree']?> <span class="caret"></span></button>
<button type="button" class="btn dropdown-toggle" data-toggle="dropdown"><i class='icon icon-branch'></i> <?php echo $lang->doc->browseTypeList['tree']?> <span class="caret"></span></button>
<ul class="dropdown-menu" role="menu">
<li><?php echo html::a('javascript:setBrowseType("bylist")', "<i class='icon icon-list'></i> {$lang->doc->browseTypeList['list']}");?></li>
<li><?php echo html::a('javascript:setBrowseType("bymenu")', "<i class='icon icon-th'></i> {$lang->doc->browseTypeList['menu']}");?></li>
<li><?php echo html::a('javascript:setBrowseType("bytree")', "<i class='icon icon-tags'></i> {$lang->doc->browseTypeList['tree']}");?></li>
<li><?php echo html::a('javascript:setBrowseType("bytree")', "<i class='icon icon-branch'></i> {$lang->doc->browseTypeList['tree']}");?></li>
</ul>
</div>
<?php common::printIcon('doc', 'create', "libID=$libID&moduleID=$moduleID");?>
-1
View File
@@ -90,5 +90,4 @@
<?php endforeach;?>
</table>
</div>
<?php js::set('type', 'doc')?>
<?php include '../../common/view/footer.html.php';?>
-1
View File
@@ -13,7 +13,6 @@
<?php include '../../common/view/header.html.php';?>
<?php if($doc->contentType == 'html') include '../../common/view/ueditor.html.php';?>
<?php if($doc->contentType == 'markdown') include '../../common/view/markdown.html.php';?>
<?php js::set('type', 'doc')?>
<div class='container mw-1400px'>
<div id='titlebar'>
<div class='heading'>
+1 -1
View File
@@ -5,7 +5,7 @@
<script>
$(function()
{
$('#featurebar .heading').prepend("<i class='icon icon-tags'></i> " + <?php echo json_encode($crumbs)?> + <?php echo json_encode($lang->arrow)?>);
$('#featurebar .heading').prepend(<?php echo json_encode($crumbs)?> + <?php echo json_encode($lang->arrow)?>);
})
</script>
<?php include '../../common/view/footer.html.php';?>
+3 -4
View File
@@ -11,7 +11,6 @@
*/
?>
<?php include '../../common/view/header.html.php';?>
<div id='featurebar'><strong><?php echo $lang->doclib->all?></strong></div>
<div id='libs'>
<?php
$libs = array();
@@ -30,7 +29,7 @@
<?php if($objectCount > 8 and $objectNum == 8):?>
<div class='col-md-3'>
<div class='libs-group clearfix lib-more'>
<?php echo html::a(inlink('allLibs', "type=$libsName"), "{$lang->more}<i class='icon icon-double-angle-right'></i>", '', "title='$lang->more' class='more'")?>
<?php echo html::a(inlink('allLibs', "type=$libsName"), "{$lang->more}{$lang->doc->libTypeList['product']}<i class='icon icon-double-angle-right'></i>", '', "title='$lang->more' class='more'")?>
</div>
</div>
<?php break;?>
@@ -84,7 +83,7 @@
<?php if($objectCount > 8 and $objectNum == 8):?>
<div class='col-md-3'>
<div class='libs-group clearfix lib-more'>
<?php echo html::a(inlink('allLibs', "type=$libsName"), $lang->more . "<i class='icon icon-double-angle-right'></i>", '', "title='$lang->more' class='more'")?>
<?php echo html::a(inlink('allLibs', "type=$libsName"), "{$lang->more}{$lang->doc->libTypeList['project']}<i class='icon icon-double-angle-right'></i>", '', "title='$lang->more' class='more'")?>
</div>
</div>
<?php break;?>
@@ -137,7 +136,7 @@
<?php if($objectCount > 8 and $objectNum == 8):?>
<div class='col-md-3'>
<div class='libs-group clearfix lib-more'>
<?php echo html::a(inlink('allLibs', "type=$libsName"), $lang->more . "<i class='icon icon-double-angle-right'></i>", '', "title='$lang->more' class='more'")?>
<?php echo html::a(inlink('allLibs', "type=$libsName"), "{$lang->more}{$lang->doc->libTypeList['custom']}<i class='icon icon-double-angle-right'></i>", '', "title='$lang->more' class='more'")?>
</div>
</div>
<?php break;?>
-1
View File
@@ -32,5 +32,4 @@
<?php endforeach; ?>
</div>
</div>
<?php js::set('type', 'doc')?>
<?php include '../../common/view/footer.html.php';?>
+2 -2
View File
@@ -12,7 +12,7 @@
?>
<?php include '../../common/view/header.html.php';?>
<div id='featurebar'>
<strong><?php echo html::a(inlink('objectLibs', "type=$type&objectID={$object->id}&from={$this->from}"), $object->name) . $lang->arrow . $lang->doclib->files?></strong>
<strong><?php echo $lang->doclib->files?></strong>
<div class='actions'><?php echo html::backButton();?></div>
</div>
<div class='lib-files cards'>
@@ -46,12 +46,12 @@
</a>
<div class='card-heading'>
<a href='<?php echo $this->createLink($file->objectType, 'view', "objectID=$file->objectID"); ?>'><?php echo $lang->doc->fileObject . ' ' . strtoupper($file->objectType) . ' #' . $file->objectID ?></a>
<i class='icon icon-chevron-right pull-right'></i>
<a href='<?php echo $this->createLink('file', 'delete', "fileID=$file->id"); ?>' target='hiddenwin' title='<?php echo $lang->delete?>' class='delete pull-right'><i class='icon icon-remove'></i></a>
</div>
</div>
</div>
<?php endforeach;?>
</div>
<div class='clearfix pager-wrapper'><?php $pager->show();?></div>
<?php js::set('type', 'doc');?>
<?php include '../../common/view/footer.html.php';?>
-1
View File
@@ -165,6 +165,5 @@
</div>
</div>
</div>
<?php js::set('type', 'doc')?>
<?php include '../../common/view/syntaxhighlighter.html.php';?>
<?php include '../../common/view/footer.html.php';?>
+2 -1
View File
@@ -257,9 +257,10 @@ class productModel extends model
$this->dao->update(TABLE_PRODUCT)->set('`order`')->eq($productID * 5)->where('id')->eq($productID)->exec();
/* Create doc lib. */
$this->app->loadLang('doc');
$lib = new stdclass();
$lib->product = $productID;
$lib->name = $product->name;
$lib->name = $this->lang->doclib->main['product'];
$lib->main = '1';
$lib->acl = $product->acl == 'open' ? 'open' : 'custom';
$lib->users = $this->app->user->account;
+1 -1
View File
@@ -271,7 +271,7 @@ class projectModel extends model
/* Create doc lib. */
$lib = new stdclass();
$lib->project = $projectID;
$lib->name = $project->name;
$lib->name = $this->lang->doclib->main['project'];
$lib->main = '1';
$lib->acl = $project->acl == 'open' ? 'open' : 'custom';
+2 -1
View File
@@ -94,7 +94,8 @@
<td></td>
<td colspan='2'>
<?php
echo html::submitButton() . html::backButton();
echo html::submitButton();
echo $this->session->{$viewType .'List'} ? html::linkButton($this->lang->goback, $this->session->{$viewType .'List'}) : html::backButton();
echo html::hidden('parentModuleID', $currentModuleID);
echo html::hidden('maxOrder', $maxOrder);
?>
+2 -1
View File
@@ -80,7 +80,8 @@
<td></td>
<td colspan='2'>
<?php
echo html::submitButton() . html::backButton();
echo html::submitButton();
echo $this->session->taskList ? html::linkButton($this->lang->goback, $this->session->taskList) : html::backButton();
echo html::hidden('parentModuleID', $currentModuleID);
echo html::hidden('maxOrder', $maxOrder);
?>
+3 -2
View File
@@ -1163,6 +1163,7 @@ class upgradeModel extends model
*/
public function adjustDocModule()
{
$this->app->loadLang('doc');
$productDocModules = $this->dao->select('*')->from(TABLE_MODULE)->where('type')->eq('productdoc')->orderBy('grade,id')->fetchAll('id');
$allProductIdList = $this->dao->select('id,name,acl,whitelist,createdBy')->from(TABLE_PRODUCT)->where('deleted')->eq('0')->fetchAll('id');
foreach($allProductIdList as $productID => $product)
@@ -1171,7 +1172,7 @@ class upgradeModel extends model
$lib = new stdclass();
$lib->product = $productID;
$lib->name = $product->name;
$lib->name = $this->lang->doclib->main['product'];
$lib->main = 1;
$lib->acl = $product->acl == 'open' ? 'open' : 'custom';
$lib->users = $product->createdBy;
@@ -1213,7 +1214,7 @@ class upgradeModel extends model
$lib = new stdclass();
$lib->project = $projectID;
$lib->name = $project->name;
$lib->name = $this->lang->doclib->main['project'];
$lib->main = 1;
$lib->acl = $project->acl == 'open' ? 'open' : 'custom';