diff --git a/db/update16.4.sql b/db/update16.4.sql
index d87b04cf5d..db16f5094b 100644
--- a/db/update16.4.sql
+++ b/db/update16.4.sql
@@ -22,6 +22,8 @@ ALTER TABLE `zt_story` ADD `vision` varchar(10) NOT NULL DEFAULT 'rnd' AFTER `id
ALTER TABLE `zt_story` ADD `activatedDate` datetime NOT NULL AFTER `closedReason`;
ALTER TABLE `zt_task` MODIFY `activatedDate` datetime NOT NULL AFTER `lastEditedDate`;
+ALTER TABLE `zt_kanbancard` ADD `progress` float unsigned NOT NULL DEFAULT '0' AFTER `estimate`;
+
ALTER TABLE `zt_user` ADD `visions` varchar(20) NOT NULL AFTER `visits`;
UPDATE `zt_user` SET `visions`='rnd,lite';
diff --git a/db/zentao.sql b/db/zentao.sql
index ef4fea5d45..fec9d80de7 100644
--- a/db/zentao.sql
+++ b/db/zentao.sql
@@ -731,6 +731,7 @@ CREATE TABLE `zt_kanbancard` (
`begin` date NOT NULL,
`end` date NOT NULL,
`estimate` float unsigned NOT NULL,
+ `progress` float unsigned NOT NULL DEFAULT '0',
`color` char(7) NOT NULL,
`acl` char(30) NOT NULL DEFAULT 'open',
`whitelist` text NOT NULL,
@@ -8584,8 +8585,8 @@ REPLACE INTO `zt_grouppriv` (`group`, `module`, `method`) VALUES
-- DROP TABLE IF EXISTS `zt_workflow`;
CREATE TABLE IF NOT EXISTS `zt_workflow` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
- `parent` varchar(30) NOT NULL,
- `child` varchar(30) NOT NULL,
+ `parent` varchar(30) NOT NULL,
+ `child` varchar(30) NOT NULL,
`type` varchar(10) NOT NULL DEFAULT 'flow',
`app` varchar(20) NOT NULL,
`position` varchar(30) NOT NULL,
@@ -8659,7 +8660,7 @@ CREATE TABLE IF NOT EXISTS `zt_workflowdatasource` (
`type` enum('system', 'sql', 'func', 'option', 'lang', 'category') NOT NULL DEFAULT 'option',
`name` varchar(30) NOT NULL,
`code` varchar(30) NOT NULL,
- `datasource` text NOT NULL,
+ `datasource` text NOT NULL,
`view` varchar(20) NOT NULL,
`keyField` varchar(50) NOT NULL,
`valueField` varchar(50) NOT NULL,
@@ -8687,7 +8688,7 @@ CREATE TABLE IF NOT EXISTS `zt_workflowfield` (
`rules` varchar(255) NOT NULL,
`placeholder` varchar(100) NOT NULL,
`order` smallint(5) unsigned NOT NULL,
- `searchOrder` smallint(5) unsigned NOT NULL DEFAULT '0',
+ `searchOrder` smallint(5) unsigned NOT NULL DEFAULT '0',
`exportOrder` smallint(5) unsigned NOT NULL DEFAULT '0',
`canExport` enum('0', '1') NOT NULL DEFAULT '0',
`canSearch` enum('0', '1') NOT NULL DEFAULT '0',
@@ -8760,7 +8761,7 @@ CREATE TABLE IF NOT EXISTS `zt_workflowlinkdata` (
-- DROP TABLE IF EXISTS `zt_workflowrelation`;
CREATE TABLE IF NOT EXISTS `zt_workflowrelation` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
- `prev` varchar(30) NOT NULL,
+ `prev` varchar(30) NOT NULL,
`next` varchar(30) NOT NULL,
`field` varchar(50) NOT NULL,
`actions` varchar(20) NOT NULL,
@@ -8792,7 +8793,7 @@ CREATE TABLE IF NOT EXISTS `zt_workflowrule` (
`id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
`type` enum('system', 'regex', 'func') NOT NULL DEFAULT 'regex',
`name` varchar(30) NOT NULL,
- `rule` text NOT NULL,
+ `rule` text NOT NULL,
`createdBy` char(30) NOT NULL,
`createdDate` datetime NOT NULL,
`editedBy` char(30) NOT NULL,
diff --git a/module/kanban/config.php b/module/kanban/config.php
index d45192d2b1..70f04a7a32 100644
--- a/module/kanban/config.php
+++ b/module/kanban/config.php
@@ -34,15 +34,16 @@ $config->kanban->editregion->requiredFields = 'name';
$config->kanban->splitcolumn->requiredFields = 'name,limit';
$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');
-$config->kanban->editor->closespace = array('id' => 'comment', 'tools' => 'simpleTools');
-$config->kanban->editor->createcard = array('id' => 'desc', 'tools' => 'simpleTools');
-$config->kanban->editor->close = array('id' => 'comment', 'tools' => 'simpleTools');
-$config->kanban->editor->editcard = array('id' => 'desc', 'tools' => 'simpleTools');
-$config->kanban->editor->viewcard = array('id' => 'comment', 'tools' => 'simpleTools');
+$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');
+$config->kanban->editor->closespace = array('id' => 'comment', 'tools' => 'simpleTools');
+$config->kanban->editor->createcard = array('id' => 'desc', 'tools' => 'simpleTools');
+$config->kanban->editor->close = array('id' => 'comment', 'tools' => 'simpleTools');
+$config->kanban->editor->editcard = array('id' => 'desc', 'tools' => 'simpleTools');
+$config->kanban->editor->viewcard = array('id' => 'comment', 'tools' => 'simpleTools');
+$config->kanban->editor->activatecard = array('id' => 'comment', 'tools' => 'simpleTools');
$config->kanban->fromType = array('execution', 'productplan', 'release', 'build');
$config->kanban->executionField = array('name', 'status', 'end', 'PM', 'type', 'deleted');
diff --git a/module/kanban/control.php b/module/kanban/control.php
index b5b36d6dff..efd33584af 100644
--- a/module/kanban/control.php
+++ b/module/kanban/control.php
@@ -888,7 +888,7 @@ class kanban extends control
$this->loadModel('action');
$oldCard = $this->kanban->getCardByID($cardID);
- $this->dao->update(TABLE_KANBANCARD)->set('status')->eq('done')->where('id')->eq($cardID)->exec();
+ $this->dao->update(TABLE_KANBANCARD)->set('progress')->eq(100)->set('status')->eq('done')->where('id')->eq($cardID)->exec();
$card = $this->kanban->getCardByID($cardID);
$changes = common::createChanges($oldCard, $card);
@@ -915,22 +915,26 @@ class kanban extends control
public function activateCard($cardID, $kanbanID)
{
$this->loadModel('action');
+ if(!empty($_POST))
+ {
+ $oldCard = $this->kanban->getCardByID($cardID);
+ $this->kanban->activateCard($cardID);
+ $card = $this->kanban->getCardByID($cardID);
- $oldCard = $this->kanban->getCardByID($cardID);
- $this->dao->update(TABLE_KANBANCARD)->set('status')->eq('doing')->where('id')->eq($cardID)->exec();
- $card = $this->kanban->getCardByID($cardID);
+ $changes = common::createChanges($oldCard, $card);
+ if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
- $changes = common::createChanges($oldCard, $card);
+ $actionID = $this->action->create('kanbanCard', $cardID, 'activated');
+ $this->action->logHistory($actionID, $changes);
- if(dao::isError()) return $this->send(array('result' => 'fail', 'message' => dao::getError()));
+ return $this->send(array('result' => 'success', 'message' => $this->lang->saveSuccess, 'locate' => 'parent'));
+ }
- $actionID = $this->action->create('kanbanCard', $cardID, 'activated');
- $this->action->logHistory($actionID, $changes);
+ $this->view->card = $this->kanban->getCardByID($cardID);
+ $this->view->actions = $this->action->getList('kanbancard', $cardID);
+ $this->view->users = $this->loadModel('user')->getPairs('noclosed|nodeleted');
- if(isonlybody()) return print(js::reload('parent.parent'));
-
- $kanbanGroup = $this->kanban->getKanbanData($kanbanID);
- return print(json_encode($kanbanGroup));
+ $this->display();
}
/**
diff --git a/module/kanban/css/performable.css b/module/kanban/css/performable.css
index bef5675724..9680e099f3 100644
--- a/module/kanban/css/performable.css
+++ b/module/kanban/css/performable.css
@@ -1 +1 @@
-#c-done {width: 110px;}
+#c-title {width: 130px;}
diff --git a/module/kanban/css/view.css b/module/kanban/css/view.css
index 7c24d71151..8296944382 100644
--- a/module/kanban/css/view.css
+++ b/module/kanban/css/view.css
@@ -118,6 +118,10 @@
.kanban-card .label-finish {margin-right: 7px; margin-top: -1px; padding: 3px 5px; float: left; background-color:#2a5f29;}
.kanban-card .releaseTitle, .kanban-card .productplanTitle {width: 100%; float: left;}
+.progress-box {display: flex; flex-direction: row; margin-top: 10px;}
+.progress {flex: auto; margin: 5px auto 5px;}
+.progress-number {padding-left: 5px;}
+
@-moz-document url-prefix(){ .region .kanban-lane-items{scrollbar-width:thin; padding:5px 0px 5px 5px !important;} .region .kanban-card .info .user{right: -6px !important;}}
#archivedCards .table-empty-tip {border-style: hidden;}
#archivedColumns .table-empty-tip {border-style: hidden;}
diff --git a/module/kanban/js/view.js b/module/kanban/js/view.js
index 42c5a8a36a..13c12f3aac 100644
--- a/module/kanban/js/view.js
+++ b/module/kanban/js/view.js
@@ -357,6 +357,11 @@ function renderKanbanItem(item, $item)
'
',
''
].join('')).appendTo($item);
+ if(kanban.performable == 1)
+ {
+ var $progress = $item.children('.progress-box');
+ if(!$progress.length) $progress = $('').appendTo($item);
+ }
$item.data('card', item);
@@ -366,6 +371,11 @@ function renderKanbanItem(item, $item)
$info.children('.pri')
.attr('class', 'pri label-pri label-pri-' + item.pri)
.text(item.pri);
+ if(kanban.performable == 1)
+ {
+ $progress.find('.progress-bar').css('width', item.progress + '%');
+ $progress.find('.progress-number').html(item.progress + '%');
+ }
$item.css('background-color', item.color);
$item.toggleClass('has-color', item.color != '#fff' && item.color != '');
@@ -808,31 +818,6 @@ function finishCard(cardID, kanbanID, regionID)
});
}
-/**
- * Activate a card.
- *
- * @param int $cardID
- * @param int $kanbanID
- * @param int $regionID
- * @access public
- * @return void
- */
-function activateCard(cardID, kanbanID, regionID)
-{
- if(!cardID) return false;
- var url = createLink('kanban', 'activateCard', 'cardID=' + cardID + '&kanbanID=' + kanbanID);
- return $.ajax(
- {
- method: 'post',
- dataType: 'json',
- url: url,
- success: function(data)
- {
- updateRegion(regionID, data[regionID]);
- }
- });
-}
-
/**
* Update a region.
*
@@ -1091,7 +1076,7 @@ function createCardMenu(options)
{
if(card.status == 'done')
{
- items.push({label: kanbanLang.activateCard, icon: 'magic', onClick: function(){activateCard(card.id, card.kanban, card.region);}});
+ items.push({label: kanbanLang.activateCard, icon: 'magic', url: createLink('kanban', 'activateCard', 'cardID=' + card.id + '&kanbanID=' + card.kanban, '', 'true'), className: 'iframe', attrs: {'data-toggle': 'modal', 'data-width': '80%'}});
}
else
{
diff --git a/module/kanban/lang/en.php b/module/kanban/lang/en.php
index 3f78e41151..481ef5e140 100644
--- a/module/kanban/lang/en.php
+++ b/module/kanban/lang/en.php
@@ -44,8 +44,8 @@ $lang->kanban->assigntoCard = 'Assign';
$lang->kanban->setting = 'Setting';
$lang->kanban->enableArchived = 'Enable Archived';
$lang->kanban->archive = 'Archive';
-$lang->kanban->performable = 'Set done function';
-$lang->kanban->doneFunction = 'Done function';
+$lang->kanban->performable = 'Set progress management';
+$lang->kanban->manageProgress = 'Manage Progress';
$lang->kanban->splitColumn = 'Split Column';
$lang->kanban->createColumnOnLeft = 'Create Column On Left';
$lang->kanban->createColumnOnRight = 'Create Column On Right';
@@ -120,8 +120,8 @@ $lang->kanban->aclList['private'] = 'Private (For the kanban team, whitelist mem
$lang->kanban->archiveList['0'] = 'Disable';
$lang->kanban->archiveList['1'] = 'Enable';
-$lang->kanban->enableFinished['0'] = 'Disable';
-$lang->kanban->enableFinished['1'] = 'Enable';
+$lang->kanban->enableList['0'] = 'Disable';
+$lang->kanban->enableList['1'] = 'Enable';
$lang->kanban->type = array();
$lang->kanban->type['all'] = "All KanBan";
@@ -184,9 +184,9 @@ $lang->kanban->my = 'My';
$lang->kanban->other = 'Other';
$lang->kanban->error = new stdclass();
-$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->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->error->importObjNotEmpty = 'Please select at least one import object.';
$lang->kanban->importList = array();
@@ -340,6 +340,7 @@ $lang->kanbancard->beginAndEnd = 'Begin & End';
$lang->kanbancard->begin = 'Begin';
$lang->kanbancard->end = 'End';
$lang->kanbancard->pri = 'Priority';
+$lang->kanbancard->progress = 'Progress';
$lang->kanbancard->desc = 'Description';
$lang->kanbancard->estimate = 'Estimate';
$lang->kanbancard->createdBy = 'Created By';
@@ -373,5 +374,6 @@ $lang->kanbancard->colorList['#cfa227'] = 'Warning';
$lang->kanbancard->colorList['#2a5f29'] = 'Urgent';
$lang->kanbancard->error = new stdClass();
-$lang->kanbancard->error->recordMinus = 'Estimate cannot be negative!';
-$lang->kanbancard->error->endSmall = '"End Date" cannot be less than "Begin Date"';
+$lang->kanbancard->error->recordMinus = 'Estimate cannot be negative!';
+$lang->kanbancard->error->endSmall = '"End Date" cannot be less than "Begin Date"';
+$lang->kanbancard->error->progressIllegal = 'Please input correct progress.';
diff --git a/module/kanban/lang/zh-cn.php b/module/kanban/lang/zh-cn.php
index 188ac3d69e..f5c05a67d9 100644
--- a/module/kanban/lang/zh-cn.php
+++ b/module/kanban/lang/zh-cn.php
@@ -44,8 +44,8 @@ $lang->kanban->assigntoCard = '指派';
$lang->kanban->setting = '设置';
$lang->kanban->enableArchived = '设置归档功能';
$lang->kanban->archive = '归档功能';
-$lang->kanban->performable = '设置完成功能';
-$lang->kanban->doneFunction = '完成功能';
+$lang->kanban->performable = '设置进度管理';
+$lang->kanban->manageProgress = '进度管理';
$lang->kanban->splitColumn = '新增子看板列';
$lang->kanban->createColumnOnLeft = '左侧新增看板列';
$lang->kanban->createColumnOnRight = '右侧新增看板列';
@@ -120,8 +120,8 @@ $lang->kanban->aclList['private'] = '私有(看板团队成员、白名单、
$lang->kanban->archiveList['0'] = '不启用';
$lang->kanban->archiveList['1'] = '启用';
-$lang->kanban->enableFinished['0'] = '不启用';
-$lang->kanban->enableFinished['1'] = '启用';
+$lang->kanban->enableList['0'] = '不启用';
+$lang->kanban->enableList['1'] = '启用';
$lang->kanban->type = array();
$lang->kanban->type['all'] = "综合看板";
@@ -340,6 +340,7 @@ $lang->kanbancard->beginAndEnd = '起止日期';
$lang->kanbancard->begin = '预计开始';
$lang->kanbancard->end = '截止日期';
$lang->kanbancard->pri = '优先级';
+$lang->kanbancard->progress = '进度';
$lang->kanbancard->desc = '描述';
$lang->kanbancard->estimate = '预计';
$lang->kanbancard->createdBy = '由谁创建';
@@ -373,5 +374,6 @@ $lang->kanbancard->colorList['#cfa227'] = '警告';
$lang->kanbancard->colorList['#2a5f29'] = '加急';
$lang->kanbancard->error = new stdClass();
-$lang->kanbancard->error->recordMinus = '预计不能为负数!';
-$lang->kanbancard->error->endSmall = '"截止日期"不能小于"预计开始"!';
+$lang->kanbancard->error->recordMinus = '预计不能为负数!';
+$lang->kanbancard->error->endSmall = '"截止日期"不能小于"预计开始"!';
+$lang->kanbancard->error->progressIllegal = '请输入正确的进度';
diff --git a/module/kanban/model.php b/module/kanban/model.php
index 0dc172b298..cdb2d9103a 100644
--- a/module/kanban/model.php
+++ b/module/kanban/model.php
@@ -2661,6 +2661,22 @@ class kanbanModel extends model
->andWhere('groupby')->eq('')
->exec();
}
+ /**
+ * Activate a card.
+ *
+ * @param int $cardID
+ * @access public
+ * @return array
+ */
+ public function activateCard($cardID)
+ {
+ if($this->post->progress > 100 or $this->post->progress < 0)
+ {
+ dao::$errors[] = $this->lang->kanbancard->error->progressIllegal;
+ return false;
+ }
+ $this->dao->update(TABLE_KANBANCARD)->set('progress')->eq($this->post->progress)->set('status')->eq('doing')->where('id')->eq($cardID)->exec();
+ }
/**
* Update a card.
@@ -2683,6 +2699,12 @@ class kanbanModel extends model
return false;
}
+ if($this->post->progress > 100 or $this->post->progress < 0)
+ {
+ dao::$errors[] = $this->lang->kanbancard->error->progressIllegal;
+ return false;
+ }
+
$cardID = (int)$cardID;
$oldCard = $this->getCardByID($cardID);
@@ -2902,7 +2924,7 @@ class kanbanModel extends model
}
if(common::hasPriv('kanban', 'setColumnWidth')) $actions .= '' . html::a(helper::createLink('kanban', 'setColumnWidth', "kanbanID=$kanban->id", '', true), '' . $this->lang->kanban->columnWidth, '', "class='iframe btn btn-link' data-width=30%") . '';
- if(common::hasPriv('kanban', 'performable')) $actions .= '' . html::a(helper::createLink('kanban', 'performable', "kanbanID=$kanban->id", '', true), '' . $this->lang->kanban->doneFunction, '', "class='iframe btn btn-link' data-width=30%") . '';
+ if(common::hasPriv('kanban', 'performable')) $actions .= '' . html::a(helper::createLink('kanban', 'performable', "kanbanID=$kanban->id", '', true), '' . $this->lang->kanban->manageProgress, '', "class='iframe btn btn-link' data-width=40%") . '';
$kanbanActions = '';
$attr = $kanban->status == 'closed' ? "disabled='disabled'" : '';
diff --git a/module/kanban/view/activatecard.html.php b/module/kanban/view/activatecard.html.php
new file mode 100644
index 0000000000..7b61fe028d
--- /dev/null
+++ b/module/kanban/view/activatecard.html.php
@@ -0,0 +1,49 @@
+
+ * @package kanban
+ * @version $Id: close.html.php 935 2021-12-09 10:49:24Z $
+ * @link https://www.zentao.net
+ */
+?>
+
+
+
+
+
+
+ id;?>
+ name'>" . $card->name . '';?>
+
+
+
+
+
+
+
+
diff --git a/module/kanban/view/editcard.html.php b/module/kanban/view/editcard.html.php
index 99b99ac3ad..26f9bd2d4c 100644
--- a/module/kanban/view/editcard.html.php
+++ b/module/kanban/view/editcard.html.php
@@ -58,14 +58,28 @@
kanbancard->end;?> |
end) ? '' : $card->end, "class='form-control form-date'");?> |
-
- | kanbancard->estimate;?> |
- estimate, "class='form-control' placeholder='{$lang->kanbancard->lblHour}'");?> |
-
| kanbancard->pri;?> |
kanbancard->priList, $card->pri, "class='form-control'");?> |
+
+ | kanbancard->estimate;?> |
+
+
+ estimate, "class='form-control'");?>
+ h
+
+ |
+
+
+ | kanbancard->progress;?> |
+
+
+ progress, "class='form-control'");?>
+ %
+
+ |
+
diff --git a/module/kanban/view/performable.html.php b/module/kanban/view/performable.html.php
index 7a44e84fa0..455bfd7935 100644
--- a/module/kanban/view/performable.html.php
+++ b/module/kanban/view/performable.html.php
@@ -19,8 +19,8 @@