diff --git a/module/kanban/config.php b/module/kanban/config.php index 3b3fe9a058..ce494e00eb 100644 --- a/module/kanban/config.php +++ b/module/kanban/config.php @@ -8,16 +8,22 @@ $config->kanban->require->createregion = 'name'; $config->kanban->setwip = new stdclass(); $config->kanban->setlane = new stdclass(); $config->kanban->setlaneColumn = new stdclass(); +$config->kanban->create = new stdclass(); +$config->kanban->edit = new stdclass(); $config->kanban->createspace = new stdclass(); $config->kanban->editspace = new stdclass(); $config->kanban->setwip->requiredFields = 'limit'; $config->kanban->setlane->requiredFields = 'name,type'; $config->kanban->setlaneColumn->requiredFields = 'name'; +$config->kanban->create->requiredFields = 'space,name'; +$config->kanban->edit->requiredFields = 'space,name'; $config->kanban->createspace->requiredFields = 'name,owner'; $config->kanban->editspace->requiredFields = 'name,owner'; $config->kanban->editor = new stdclass(); +$config->kanban->editor->create = array('id' => 'desc', 'tools' => 'simpleTools'); +$config->kanban->editor->edit = array('id' => 'desc', 'tools' => 'simpleTools'); $config->kanban->editor->createspace = array('id' => 'desc', 'tools' => 'simpleTools'); $config->kanban->editor->editspace = array('id' => 'desc', 'tools' => 'simpleTools'); diff --git a/module/kanban/control.php b/module/kanban/control.php index d2a25e2f5f..9eac56f876 100644 --- a/module/kanban/control.php +++ b/module/kanban/control.php @@ -23,11 +23,16 @@ class kanban extends control */ public function space($browseType = 'my', $recTotal = 0, $recPerPage = 15, $pageID = 1) { + $spaces = $this->kanban->getSpaces($browseType); + /* Load pager. */ $this->app->loadClass('pager', $static = true); - $pager = new pager($recTotal, $recPerPage, $pageID); + $recTotal = count($spaces); + $pager = new pager($recTotal, $recPerPage, $pageID); + $spaces = array_chunk($spaces, $pager->recPerPage); - $this->view->title = $this->lang->kanban->common; + $this->view->title = $this->lang->kanbanspace->common; + $this->view->spaces = empty($spaces) ? $spaces : $spaces[$pageID - 1]; $this->view->browseType = $browseType; $this->view->pager = $pager; @@ -84,6 +89,32 @@ class kanban extends control $this->display(); } + /** + * Create a kanban. + * + * @param int $spaceID + * @access public + * @return void + */ + public function create($spaceID = 0) + { + if(!empty($_POST)) + { + $kanbanID = $this->kanban->create(); + + if(dao::isError()) die(js::error(dao::getError())); + + $this->loadModel('action')->create('kanban', $kanbanID, 'created'); + die(js::reload('parent.parent')); + } + + $this->view->users = $this->loadModel('user')->getPairs('noletter|noclosed'); + $this->view->spaceID = $spaceID; + $this->view->spacePairs = array('' => '') + $this->kanban->getSpacePairs(); + + $this->display(); + } + /** * Set WIP. * diff --git a/module/kanban/css/space.css b/module/kanban/css/space.css new file mode 100644 index 0000000000..be6d44e1d8 --- /dev/null +++ b/module/kanban/css/space.css @@ -0,0 +1,5 @@ +#spaces {margin: 0 0; margin-bottom: 15px;} +#spaces .spaceTitle {margin-bottom: 15px;} +#spaces .spaceActions {margin-top: 10px;} +#spaces .spaceActions > a{margin-left: 10px;} +.table-footer .pager>li.disabled>a.pager-item {bottom: -3px;} diff --git a/module/kanban/lang/en.php b/module/kanban/lang/en.php index 650576ed2d..6b3a230436 100644 --- a/module/kanban/lang/en.php +++ b/module/kanban/lang/en.php @@ -1,6 +1,5 @@ kanban->space = 'Kanban Space'; $lang->kanban->create = 'Create Kanban'; $lang->kanban->createSpace = 'Create Space'; $lang->kanban->editSpace = 'Edit Space'; @@ -26,6 +25,18 @@ $lang->kanban->createCard = 'Create Card'; $lang->kanban->editCard = 'Edit Card'; $lang->kanban->viewCard = 'View Card'; $lang->kanban->sortCard = 'Sort Card'; +$lang->kanban->setting = 'Setting'; + +/* Fields. */ +$lang->kanban->space = 'Space'; +$lang->kanban->name = 'Name'; +$lang->kanban->owner = 'Owner'; +$lang->kanban->team = 'Team'; +$lang->kanban->desc = 'Description'; +$lang->kanban->acl = 'ACL'; + +$lang->kanban->aclList['open'] = '继承空间访问权限(能访问当前空间,即可访问)'; +$lang->kanban->aclList['private'] = '私有(看板团队成员、可访问)'; $lang->kanban->type = array(); $lang->kanban->type['all'] = "All KanBan"; @@ -87,6 +98,8 @@ $lang->kanban->error->mustBeInt = 'The WIPs must be positive integer.'; $lang->kanban->error->parentLimitNote = 'The WIPs in the parent column cannot be < the sum of the WIPs in the child column.'; $lang->kanban->error->childLimitNote = 'The sum of products in the child column cannot be > the number of products in the parent column.'; +$lang->kanban->defaultColumn = array('wait', 'doing', 'done', 'close'); + $this->lang->kanban->laneTypeList = array(); $this->lang->kanban->laneTypeList['story'] = $lang->SRCommon; $this->lang->kanban->laneTypeList['bug'] = 'Bug'; @@ -126,14 +139,17 @@ $lang->kanban->taskColumn['canceled'] = 'Canceled'; $lang->kanban->taskColumn['closed'] = 'Closed'; $lang->kanbanspace = new stdclass(); -$lang->kanbanspace->name = 'Name'; -$lang->kanbanspace->owner = 'Owner'; -$lang->kanbanspace->team = 'Team'; -$lang->kanbanspace->desc = 'Description'; -$lang->kanbanspace->acl = 'ACL'; +$lang->kanbanspace->common = 'Kanban Space'; +$lang->kanbanspace->name = 'Name'; +$lang->kanbanspace->owner = 'Owner'; +$lang->kanbanspace->team = 'Team'; +$lang->kanbanspace->desc = 'Description'; +$lang->kanbanspace->acl = 'ACL'; + +$lang->kanbanspace->empty = 'No Space'; $lang->kanbanspace->aclList['open'] = 'Open (Accessible with kanban view permissions)'; -$lang->kanbanspace->aclList['private'] = 'Private (For the kanban owner and team members only)'; +$lang->kanbanspace->aclList['private'] = 'Private (For the kanban owner team and whitelist members only)'; $lang->kanbanspace->featureBar['all'] = 'All'; $lang->kanbanspace->featureBar['my'] = 'My'; @@ -145,4 +161,9 @@ $lang->kanbancolumn->name = $lang->kanban->columnName; $lang->kanbancolumn->limit = $lang->kanban->WIPCount; $lang->kanbanlane = new stdclass(); -$lang->kanbanlane->name = $lang->kanban->laneName; +$lang->kanbanlane->name = $lang->kanban->laneName; +$lang->kanbanlane->default = 'Default Lane'; + +$lang->kanbanregion = new stdclass(); +$lang->kanbanregion->name = 'Kanban Region'; +$lang->kanbanregion->default = 'Default Region'; diff --git a/module/kanban/lang/zh-cn.php b/module/kanban/lang/zh-cn.php index fe7d2ccb40..3f42e34dec 100644 --- a/module/kanban/lang/zh-cn.php +++ b/module/kanban/lang/zh-cn.php @@ -1,6 +1,5 @@ kanban->space = '看板空间'; $lang->kanban->create = '创建看板'; $lang->kanban->createSpace = '创建空间'; $lang->kanban->editSpace = '设置空间'; @@ -26,6 +25,18 @@ $lang->kanban->createCard = '创建卡片'; $lang->kanban->editCard = '编辑卡片'; $lang->kanban->viewCard = '查看卡片'; $lang->kanban->sortCard = '卡片排序'; +$lang->kanban->setting = '设置'; + +/* Fields. */ +$lang->kanban->space = '所属空间'; +$lang->kanban->name = '看板名称'; +$lang->kanban->owner = '负责人'; +$lang->kanban->team = '团队'; +$lang->kanban->desc = '空间描述'; +$lang->kanban->acl = '访问控制'; + +$lang->kanban->aclList['open'] = '继承空间访问权限(能访问当前空间,即可访问)'; +$lang->kanban->aclList['private'] = '私有(看板团队成员、空间负责人、白名单可访问)'; $lang->kanban->type = array(); $lang->kanban->type['all'] = "综合看板"; @@ -87,6 +98,8 @@ $lang->kanban->error->mustBeInt = '在制品数量必须是正整数。'; $lang->kanban->error->parentLimitNote = '父列的在制品数量不能小于子列在制品数量之和'; $lang->kanban->error->childLimitNote = '子列在制品数量之和不能大于父列的在制品数量'; +$lang->kanban->defaultColumn = array('未开始', '进行中', '已完成', '已关闭'); + $this->lang->kanban->laneTypeList = array(); $this->lang->kanban->laneTypeList['story'] = $lang->SRCommon; $this->lang->kanban->laneTypeList['bug'] = 'Bug'; @@ -126,22 +139,23 @@ $lang->kanban->taskColumn['canceled'] = '已取消'; $lang->kanban->taskColumn['closed'] = '已关闭'; $lang->kanbanspace = new stdclass(); -$lang->kanbanspace->name = '空间名称'; -$lang->kanbanspace->owner = '负责人'; -$lang->kanbanspace->team = '团队'; -$lang->kanbanspace->desc = '空间描述'; -$lang->kanbanspace->acl = '访问控制'; +$lang->kanbanspace->common = '看板空间'; +$lang->kanbanspace->name = '空间名称'; +$lang->kanbanspace->owner = '负责人'; +$lang->kanbanspace->team = '团队'; +$lang->kanbanspace->desc = '空间描述'; +$lang->kanbanspace->acl = '访问控制'; + +$lang->kanbanspace->empty = '暂时没有空间'; $lang->kanbanspace->aclList['open'] = '公开(有看板空间视图权限即可访问)'; -$lang->kanbanspace->aclList['private'] = '私有(只有看板空间负责人、团队成员可访问)'; +$lang->kanbanspace->aclList['private'] = '私有(只有看板空间负责人、团队成员、白名单可访问)'; $lang->kanbanspace->featureBar['all'] = '所有'; $lang->kanbanspace->featureBar['my'] = '我的空间'; $lang->kanbanspace->featureBar['other'] = '其他空间'; $lang->kanbanspace->featureBar['closed'] = '已关闭'; -$lang->kanban->defaultColumn = array('未开始', '进行中', '已完成', '已关闭'); - $lang->kanbancolumn = new stdclass(); $lang->kanbancolumn->name = $lang->kanban->columnName; $lang->kanbancolumn->limit = $lang->kanban->WIPCount; diff --git a/module/kanban/model.php b/module/kanban/model.php index eaf58d6c35..b784619a47 100644 --- a/module/kanban/model.php +++ b/module/kanban/model.php @@ -340,32 +340,114 @@ class kanbanModel extends model } /** - * Create a space. + * Get spaces. + * + * @param string $browseType all|my|other|closed + * @access public + * @return array + */ + public function getSpaces($browseType) + { + $account = $this->app->user->account; + $spaces = $this->dao->select('*')->from(TABLE_KANBANSPACE) + ->where('deleted')->eq(0) + ->beginIF($browseType == 'my')->andWhere('owner')->eq($account)->fi() + ->beginIF($browseType == 'other')->andWhere('owner')->ne($account)->fi() + ->beginIF($browseType == 'closed')->andWhere('status')->eq('closed')->fi() + ->orderBy('id_desc') + ->fetchAll('id'); + + $spaces = $this->getCanViewObjects('space', $spaces); + + return $spaces; + } + + /** + * Get space pairs. + * + * @param string $browseType all|my|other|closed + * @access public + * @return array + */ + public function getSpacePairs($browseType = 'all') + { + $spaces = $this->getSpaces($browseType); + $spacePairs = $this->getCanViewObjects('space', $spaces, 'pairs'); + + return $spacePairs; + } + + /** + * Get can view objects. + * + * @param string $objectType space|kanban + * @param array $objects + * @param string $returnType object|pairs + * @access public + * @return array + */ + public function getCanViewObjects($objectType, $objects, $returnType = 'object') + { + if($this->app->user->admin and $returnType == 'object') return $objects; + + $account = $this->app->user->account; + $objectPairs = array(); + foreach($objects as $objectID => $object) + { + if(($this->app->user->admin or $object->acl == 'open') and $returnType == 'pairs') + { + $objectPairs[$objectID] = $object->name; + } + elseif($object->acl == 'private') + { + $aclUsers = $object->owner . $object->team . $object->whitelist; + if(strpos(",$aclUsers,", ",$account,") === false) + { + unset($objects[$objectID]); + } + elseif($returnType == 'pairs') + { + $objectPairs[$objectID] = $object->name; + } + } + } + + if($returnType == 'pairs') return $objectPairs; + return $objects; + } + + /** + * Create a kanban. * * @access public * @return int */ - public function createSpace() + public function create() { - $space = fixer::input('post') - ->setDefault('createdBy', $this->app->user->account) + $account = $this->app->user->account; + $kanban = fixer::input('post') + ->setDefault('createdBy', $account) ->setDefault('createdDate', helper::now()) ->join('whitelist', ',') ->join('team', ',') ->remove('uid,contactListMenu') ->get(); - $this->dao->insert(TABLE_KANBANSPACE)->data($space) + if(strpos(",{$kanban->team},", ",$account,") === false and $kanban->owner != $account) $kanban->team .= ",$account"; + + $this->dao->insert(TABLE_KANBAN)->data($kanban) ->autoCheck() - ->batchCheck($this->config->kanban->createspace->requiredFields, 'notempty') + ->batchCheck($this->config->kanban->create->requiredFields, 'notempty') ->exec(); if(!dao::isError()) { - $spaceID = $this->dao->lastInsertID(); - $this->saveOrder(0, '', $spaceID, 'space', '', $spaceID); + $kanbanID = $this->dao->lastInsertID(); - return $spaceID; + $this->saveOrder(0, '', $kanbanID, 'kanban', '', $kanbanID); + $this->initKanban($kanbanID); + + return $kanbanID; } } @@ -397,6 +479,39 @@ class kanbanModel extends model if(!dao::isError()) return common::createChanges($oldSpace, $space); } + /** + * Create a space. + * + * @access public + * @return int + */ + public function createSpace() + { + $account = $this->app->user->account; + $space = fixer::input('post') + ->setDefault('createdBy', $this->app->user->account) + ->setDefault('createdDate', helper::now()) + ->join('whitelist', ',') + ->join('team', ',') + ->remove('uid,contactListMenu') + ->get(); + + if(strpos(",{$space->team},", ",$account,") === false and $space->owner != $account) $space->team .= ",$account"; + + $this->dao->insert(TABLE_KANBANSPACE)->data($space) + ->autoCheck() + ->batchCheck($this->config->kanban->createspace->requiredFields, 'notempty') + ->exec(); + + if(!dao::isError()) + { + $spaceID = $this->dao->lastInsertID(); + $this->saveOrder(0, '', $spaceID, 'space', '', $spaceID); + + return $spaceID; + } + } + /** * Add execution Kanban lanes and columns. * diff --git a/module/kanban/view/create.html.php b/module/kanban/view/create.html.php new file mode 100644 index 0000000000..39942dc539 --- /dev/null +++ b/module/kanban/view/create.html.php @@ -0,0 +1,64 @@ + + * @package kanban + * @version $Id: create.html.php 935 2021-12-09 13:48:24Z $ + * @link https://www.zentao.net + */ +?> + + +
kanbanspace->empty;?>
+