This commit is contained in:
wangyidong
2022-07-19 13:10:42 +08:00
16 changed files with 161 additions and 30 deletions
+26
View File
@@ -5,4 +5,30 @@ $(function()
var checked = $(this).prop('checked');
$(this).parents('tr').find('input[type=checkbox]').prop('checked', checked);
});
$('#other,#group,#outside').selectable(
{
selector: 'input',
listenClick: false,
select: function(e)
{
$('[data-id=' + e.id + ']').prop('checked', true);
var checked = true;
var memberNum = $('[data-id=' + e.id + ']').closest('td').find('input').length;
var checkedMemberNum = $('[data-id=' + e.id + ']').closest('td').find('input:checked').length;
if(memberNum > checkedMemberNum) checked = false;
$('[data-id=' + e.id + ']').closest('tr').find('.check-all input').prop('checked', checked);
},
unselect: function(e)
{
$('[data-id=' + e.id + ']').prop('checked', false);
var checked = true;
var memberNum = $('[data-id=' + e.id + ']').closest('td').find('input').length;
var checkedMemberNum = $('[data-id=' + e.id + ']').closest('td').find('input:checked').length;
if(memberNum > checkedMemberNum) checked = false;
$('[data-id=' + e.id + ']').closest('tr').find('.check-all input').prop('checked', checked);
}
});
});
+14 -15
View File
@@ -236,11 +236,11 @@ class kanban extends control
$space = $this->kanban->getSpaceById($spaceID);
$spaceUsers = $spaceID == 0 ? ',' : trim($space->owner) . ',' . trim($space->team);
$spacePairs = array(0 => '') + $this->kanban->getSpacePairs($type);
$users = isset($spacePairs[$spaceID]) ? $this->loadModel('user')->getPairs('noclosed|nodeleted', '', 0, $spaceUsers) : array();
$whitelist = (isset($space->whitelist) and !empty($space->whitelist)) ? $space->whitelist : ',';
$users = $this->loadModel('user')->getPairs('noclosed|nodeleted');
$ownerPairs = (isset($spacePairs[$spaceID])) ? $this->user->getPairs('noclosed|nodeleted', '', 0, $spaceUsers) : $users;
$this->view->users = $users;
$this->view->whitelist = isset($spacePairs[$spaceID]) ? $this->user->getPairs('noclosed|nodeleted', '', 0, $whitelist) : array();
$this->view->ownerPairs = $ownerPairs;
$this->view->spaceID = $spaceID;
$this->view->spacePairs = $spacePairs;
$this->view->type = $type;
@@ -282,11 +282,11 @@ class kanban extends control
$space = $this->kanban->getSpaceById($kanban->space);
$spaceUsers = trim($space->owner) . ',' . trim($space->team);
$users = $this->loadModel('user')->getPairs('noclosed|nodeleted', '', 0, $spaceUsers);
$whitelist = (isset($space->whitelist) and !empty($space->whitelist)) ? $space->whitelist : ',';
$users = $this->loadModel('user')->getPairs('noclosed|nodeleted');
$ownerPairs = $this->user->getPairs('noclosed|nodeleted', '', 0, $spaceUsers);
$this->view->users = $users;
$this->view->whitelist = $this->user->getPairs('noclosed|nodeleted', '', 0, $whitelist);
$this->view->ownerPairs = $ownerPairs;
$this->view->spacePairs = array(0 => '') + array($kanban->space => $space->name) + $this->kanban->getSpacePairs($space->type);
$this->view->kanban = $kanban;
$this->view->type = $space->type;
@@ -1844,20 +1844,21 @@ class kanban extends control
/**
* Ajax get contact users.
*
* @param string $field
* @param int $contactListID
* @access public
* @return string
*/
public function ajaxGetContactUsers($contactListID)
public function ajaxGetContactUsers($field, $contactListID)
{
$this->loadModel('user');
$list = $contactListID ? $this->user->getContactListByID($contactListID) : '';
$users = $this->user->getPairs('devfirst|nodeleted|noclosed', $list ? $list->userList : '', $this->config->maxCount);
if(!$contactListID) return print(html::select('team[]', $users, '', "class='form-control chosen' multiple"));
if(!$contactListID) return print(html::select($field . '[]', $users, '', "class='form-control picker-select' multiple"));
return print(html::select('team[]', $users, $list->userList, "class='form-control chosen' multiple"));
return print(html::select($field . '[]', $users, $list->userList, "class='form-control picker-select' multiple"));
}
/**
@@ -1913,18 +1914,16 @@ class kanban extends control
* @param int $spaceID
* @param string $field team|whitelist|owner
* @param string $selectedUser
* @param string $space all|space
* @access public
* @return string
*/
public function ajaxLoadSpaceUsers($spaceID, $field = '', $selectedUser = '')
public function ajaxLoadUsers($spaceID, $field = '', $selectedUser = '', $type = 'space')
{
$space = $this->kanban->getSpaceById($spaceID);
$accounts = '';
if(!empty($space))
{
if($space->type == 'private' and !empty($space->whitelist)) $accounts = $space->whitelist;
if($space->type != 'private') $accounts = trim($space->owner) . ',' . trim($space->team);
}
if(!empty($space) and $field == 'owner' and $type != 'all') $accounts = trim($space->owner) . ',' . trim($space->team);
$users = $this->loadModel('user')->getPairs('noclosed|nodeleted', '', 0, $accounts);
$multiple = in_array($field, array('team', 'whitelist')) ? 'multiple' : '';
+2
View File
@@ -23,3 +23,5 @@
#copyKanbanModal .copyContentBox > .checkbox-primary {display: inline-block; margin-left: 10px; margin-top: -1px;}
#copyKanbanModal .copyContentBox > .checkbox-primary:first-child {margin-left: 20px;}
#copyContentbasicInfo {cursor: not-allowed;}
#team ~ #contactListMenu_chosen, #whitelist ~ #contactListMenu_chosen {vertical-align: top;}
#team ~ #contactListMenu_chosen > .chosen-drop, #whitelist ~ #contactListMenu_chosen > .chosen-drop {top: 32px;}
+2
View File
@@ -10,3 +10,5 @@
#mainContent .objectBox .checkbox-primary>label:after {width: 14px; height: 14px;}
[lang^='en'] .columnWidth {width: 120px;}
[lang^='zh-cn'] .columnWidth {width: 80px;}
#team ~ #contactListMenu_chosen, #whitelist ~ #contactListMenu_chosen {vertical-align: top;}
#team ~ #contactListMenu_chosen > .chosen-drop, #whitelist ~ #contactListMenu_chosen > .chosen-drop {top: 32px;}
+24 -5
View File
@@ -8,13 +8,13 @@
*/
function setMailto(field, value)
{
var link = createLink('kanban', 'ajaxGetContactUsers', "listID=" + value);
var link = createLink('kanban', 'ajaxGetContactUsers', 'field=' + field + '&listID=' + value);
$.post(link, function(data)
{
$('#team').replaceWith(data);
$('#team_chosen').remove();
$('#team').chosen();
$('.picker.picker-multi').remove();
$('#' + field).replaceWith(data);
$('#' + field + '_chosen').remove();
$('#' + field).siblings('.picker').remove();
$('#' + field).picker();
})
}
@@ -109,3 +109,22 @@ function changeType(type)
$('#whitelistBox').addClass('hidden');
}
}
/**
* Load all users.
*
* @access public
* @return void
*/
function loadAllUsers()
{
var link = createLink('kanban', 'ajaxLoadUsers', 'spaceID=0&field=owner&selectedUser=' + $('#owner').val() + "&type=all");
$.get(link, function(data)
{
$('#owner').replaceWith(data);
$('#owner' + "_chosen").remove();
$('#owner').next('.picker').remove();
$('#owner').chosen();
});
}
+2 -2
View File
@@ -82,7 +82,7 @@ function changeValue(spaceID, type)
function loadUsers(spaceID)
{
var field = spaceType == 'private' ? 'whitelist' : 'team';
var link = createLink('kanban', 'ajaxLoadSpaceUsers', 'spaceID='+ spaceID + '&field=' + field + '&selectedUser=' + $('#' + field).val());
var link = createLink('kanban', 'ajaxLoadUsers', 'spaceID='+ spaceID + '&field=' + field + '&selectedUser=' + $('#' + field).val());
$.get(link, function(data)
{
$('#' + field).replaceWith(data);
@@ -102,7 +102,7 @@ function loadUsers(spaceID)
*/
function loadOwners(spaceID)
{
var link = createLink('kanban', 'ajaxLoadSpaceUsers', 'spaceID='+ spaceID + '&field=owner&selectedUser=' + $('#owner').val());
var link = createLink('kanban', 'ajaxLoadUsers', 'spaceID='+ spaceID + '&field=owner&selectedUser=' + $('#owner').val());
$.get(link, function(data)
{
+1
View File
@@ -87,6 +87,7 @@ $lang->kanban->allProjects = 'All ' . ($this->config->systemMode == 'cla
$lang->kanban->allProducts = 'All Products';
$lang->kanban->mine = 'Mine';
$lang->kanban->alignment = 'Alignment';
$lang->kanban->allUsers = 'Alle Benutzer laden';
/* Fields. */
$lang->kanban->space = 'Space';
+1
View File
@@ -87,6 +87,7 @@ $lang->kanban->allProjects = 'All ' . ($this->config->systemMode == 'cla
$lang->kanban->allProducts = 'All Products';
$lang->kanban->mine = 'Mine';
$lang->kanban->alignment = 'Alignment';
$lang->kanban->allUsers = 'Load All Users';
/* Fields. */
$lang->kanban->space = 'Space';
+1
View File
@@ -87,6 +87,7 @@ $lang->kanban->allProjects = 'All ' . ($this->config->systemMode == 'cla
$lang->kanban->allProducts = 'All Products';
$lang->kanban->mine = 'Mine';
$lang->kanban->alignment = 'Alignment';
$lang->kanban->allUsers = 'Charger Tous';
/* Fields. */
$lang->kanban->space = 'Space';
+1
View File
@@ -87,6 +87,7 @@ $lang->kanban->allProjects = '所有' . ($this->config->systemMode == 'c
$lang->kanban->allProducts = '所有产品';
$lang->kanban->mine = '我负责';
$lang->kanban->alignment = '对齐方式';
$lang->kanban->allUsers = '加载所有用户';
/* Fields. */
$lang->kanban->space = '所属空间';
+40
View File
@@ -2235,6 +2235,13 @@ class kanbanModel extends model
$this->loadModel('file')->saveUpload('kanban', $kanbanID);
$this->file->updateObjectID($this->post->uid, $kanbanID, 'kanban');
if(isset($_POST['team']) or isset($_POST['whitelist']))
{
$type = isset($_POST['team']) ? 'team' : 'whitelist';
$kanbanMembers = empty($kanban->{$type}) ? array() : explode(',', $kanban->{$type});
$this->addSpaceMembers($kanban->space, $type, $kanbanMembers);
}
return $kanbanID;
}
}
@@ -2283,6 +2290,13 @@ class kanbanModel extends model
$this->loadModel('file')->saveUpload('kanban', $kanbanID);
$this->file->updateObjectID($this->post->uid, $kanbanID, 'kanban');
if(isset($_POST['team']) or isset($_POST['whitelist']))
{
$type = isset($_POST['team']) ? 'team' : 'whitelist';
$kanbanMembers = empty($kanban->{$type}) ? array() : explode(',', $kanban->{$type});
$this->addSpaceMembers($kanban->space, $type, $kanbanMembers);
}
return common::createChanges($oldKanban, $kanban);
}
}
@@ -2559,6 +2573,32 @@ class kanbanModel extends model
}
}
/**
* Add space members.
*
* @param int $spaceID
* @param array $type team|whitelist
* @param array $kanbanMembers
* @access public
* @return void
*/
public function addSpaceMembers($spaceID, $type, $kanbanMembers = array())
{
$space = $this->getSpaceById($spaceID);
if(empty($space)) return;
$spaceMembers = empty($space->{$type}) ? array() : explode(',', $space->{$type});
$members = $space->{$type};
$addMembers = array_diff($kanbanMembers, $spaceMembers);
if(!empty($addMembers))
{
$addMembers = implode(',', $addMembers);
$members .= ',' . trim($addMembers, ',');
$this->dao->update(TABLE_KANBANSPACE)->set($type)->eq($members)->where('id')->eq($spaceID)->exec();
}
}
/**
* Remove kanban cell.
*
+13 -2
View File
@@ -47,13 +47,19 @@
<?php if($type != 'private'):?>
<tr>
<th><?php echo $lang->kanban->owner;?></th>
<td><?php echo html::select('owner', $users, isset($copyKanban->owner) ? $copyKanban->owner : '', "class='form-control chosen' data-drop_direction='down'");?></td>
<td>
<div class='input-group'>
<?php echo html::select('owner', $ownerPairs, isset($copyKanban->owner) ? $copyKanban->owner : '', "class='form-control chosen' data-drop_direction='down'");?>
<span class='input-group-btn'><?php echo html::commonButton($lang->kanban->allUsers, "class='btn btn-default' onclick='loadAllUsers()' data-toggle='tooltip'");?></span>
</div>
</td>
</tr>
<tr>
<th><?php echo $lang->kanban->team;?></th>
<td colspan='2'>
<div class="input-group">
<?php echo html::select('team[]', $users, isset($copyKanban->team) ? $copyKanban->team : '', "class='form-control picker-select' multiple data-dropDirection='bottom'");?>
<?php echo $this->fetch('my', 'buildContactLists', 'dropdownName=team');?>
</div>
</td>
</tr>
@@ -91,7 +97,12 @@
<?php if($type == 'private'):?>
<tr id="whitelistBox">
<th><?php echo $lang->whitelist;?></th>
<td><?php echo html::select('whitelist[]', $whitelist, isset($copyKanban->whitelist) ? $copyKanban->whitelist : '', 'class="form-control picker-select" multiple');?></td>
<td colspan='2'>
<div class="input-group">
<?php echo html::select('whitelist[]', $users, isset($copyKanban->whitelist) ? $copyKanban->whitelist : '', 'class="form-control picker-select" multiple');?>
<?php echo $this->fetch('my', 'buildContactLists', 'dropdownName=whitelist');?>
</div>
</td>
</tr>
<?php endif;?>
<tr>
+13 -2
View File
@@ -36,13 +36,19 @@
<?php if($type != 'private'):?>
<tr>
<th><?php echo $lang->kanban->owner;?></th>
<td><?php echo html::select('owner', $users, $kanban->owner, "class='form-control chosen' data-drop_direction='down'");?></td>
<td>
<div class='input-group'>
<?php echo html::select('owner', $ownerPairs, $kanban->owner, "class='form-control chosen' data-drop_direction='down'");?>
<span class='input-group-btn'><?php echo html::commonButton($lang->kanban->allUsers, "class='btn btn-default' onclick='loadAllUsers()' data-toggle='tooltip'");?></span>
</div>
</td>
</tr>
<tr>
<th><?php echo $lang->kanban->team;?></th>
<td colspan='2'>
<div class="input-group">
<?php echo html::select('team[]', $users, $kanban->team, "class='form-control picker-select' multiple data-dropDirection='bottom'");?>
<?php echo $this->fetch('my', 'buildContactLists', 'dropdownName=team');?>
</div>
</td>
</tr>
@@ -90,7 +96,12 @@
<?php if($type == 'private'):?>
<tr id="whitelistBox">
<th><?php echo $lang->whitelist;?></th>
<td><?php echo html::select('whitelist[]', $whitelist, $kanban->whitelist, 'class="form-control picker-select" multiple');?></td>
<td colspan='2'>
<div class="input-group">
<?php echo html::select('whitelist[]', $users, $kanban->whitelist, 'class="form-control picker-select" multiple');?>
<?php echo $this->fetch('my', 'buildContactLists', 'dropdownName=whitelist');?>
</div>
</td>
</tr>
<?php endif;?>
<tr>
+16 -2
View File
@@ -393,8 +393,22 @@ class productplan extends control
return print(js::error($this->lang->notFound) . js::locate($this->createLink('product', 'index')));
}
$this->session->set('storyList', $this->createLink('productplan', 'view', "planID=$planID&type=story"), 'product');
$this->session->set('bugList', $this->createLink('productplan', 'view', "planID=$planID&type=bug"), 'qa');
if($type == 'story' and ($orderBy != 'order_desc' or $pageID != 1 or $recPerPage != 100))
{
$this->session->set('storyList', $this->app->getURI(true), 'product');
}
else
{
$this->session->set('storyList', $this->createLink('productplan', 'view', "planID=$planID&type=story"), 'product');
}
if($type == 'bug' and ($orderBy != 'order_desc' or $pageID != 1 or $recPerPage != 100))
{
$this->session->set('bugList', $this->app->getURI(true), 'qa');
}
else
{
$this->session->set('bugList', $this->createLink('productplan', 'view', "planID=$planID&type=bug"), 'qa');
}
/* Determines whether an object is editable. */
$canBeChanged = common::canBeChanged('plan', $plan);
+4 -1
View File
@@ -1474,15 +1474,18 @@ class story extends control
* Recall the story review.
*
* @param int $storyID
* @param string $from
* @access public
* @return void
*/
public function recall($storyID)
public function recall($storyID, $from = 'list')
{
$story = $this->story->getById($storyID);
$this->story->recall($storyID);
$this->loadModel('action')->create('story', $storyID, 'Recalled');
if($from == 'view') return print(js::locate($this->createLink('story', 'view', "storyID={$storyID}&from=view")));
$locateLink = $this->session->storyList ? $this->session->storyList : $this->createLink('product', 'browse', "productID={$story->product}");
echo js::locate($locateLink, 'parent');
}
+1 -1
View File
@@ -3945,7 +3945,7 @@ class storyModel extends model
if($type == 'view')
{
$menu .= $this->buildMenu('story', 'change', $params, $story, $type, 'alter', '', 'showinonlybody');
$menu .= $this->buildMenu('story', 'recall', $params, $story, $type, 'undo', '', 'showinonlybody');
$menu .= $this->buildMenu('story', 'recall', $params . '&from=view', $story, $type, 'undo', '', 'showinonlybody');
$menu .= $this->buildMenu('story', 'review', $params, $story, $type, 'search', '', 'showinonlybody');
if(!isonlybody()) $menu .= $this->buildMenu('story', 'batchCreate', "productID=$story->product&branch=$story->branch&moduleID=$story->module&$params", $story, $type, 'split', '', 'divideStory', true, "data-toggle='modal' data-type='iframe' data-width='95%'", $this->lang->story->subdivide);