* [task#137010,done,3h] Add product release block.
This commit is contained in:
@@ -141,7 +141,7 @@ $config->doc->zentaoList['bug']['subMenu'][] = array('key' => 'productBug', 'nam
|
||||
$config->doc->zentaoList['bug']['subMenu'][] = array('key' => 'planBug', 'name' => $lang->doc->zentaoList['planBug'] . $lang->doc->list, 'icon' => 'productplan', 'module' => 'productplan', 'method' => 'bug', 'params' => 'productID=0&planID=0&blockID=0', 'priv' => 'productplanView');
|
||||
|
||||
$config->doc->zentaoList['more']['subMenu'][] = array('key' => 'productPlan', 'name' => $lang->doc->zentaoList['productPlan'] . $lang->doc->list, 'icon' => 'productplan', 'module' => 'productplan', 'method' => 'browse', 'params' => 'productID=0&branch=&browseType=undone&queryID=0&orderBy=begin_desc&recTotal=0&recPerPage=20&pageID=1&from=doc', 'priv' => 'productplanBrowse');
|
||||
//$config->doc->zentaoList['more']['subMenu'][] = array('key' => 'productRelease', 'name' => $lang->doc->zentaoList['productRelease'] . $lang->doc->list, 'icon' => 'send', 'module' => 'product', 'method' => 'browse', 'params' => '', 'priv' => 'releaseBrowse');
|
||||
$config->doc->zentaoList['more']['subMenu'][] = array('key' => 'productRelease', 'name' => $lang->doc->zentaoList['productRelease'] . $lang->doc->list, 'icon' => 'send', 'module' => 'release', 'method' => 'browse', 'params' => 'productID=0&branch=all&type=all&orderBy=¶m=0&recTotal=0&recPerPage=20&pageID=1&from=doc', 'priv' => 'releaseBrowse');
|
||||
$config->doc->zentaoList['more']['subMenu'][] = array('key' => 'ER', 'name' => $lang->doc->zentaoList['ER'] . $lang->doc->list, 'icon' => 'lightbulb-alt', 'module' => 'product', 'method' => 'browse', 'params' => 'productID=0&branch=all&browseType=¶m=0&storyType=epic&orderBy=&recTotal=0&recPerPage=20&pageID=1&projectID=0&from=doc', 'priv' => 'epicBrowse');
|
||||
$config->doc->zentaoList['more']['subMenu'][] = array('key' => 'UR', 'name' => $lang->doc->zentaoList['UR'] . $lang->doc->list, 'icon' => 'customer', 'module' => 'product', 'method' => 'browse', 'params' => 'productID=0&branch=all&browseType=¶m=0&storyType=requirement&orderBy=&recTotal=0&recPerPage=20&pageID=1&projectID=0&from=doc', 'priv' => 'requirementBrowse');
|
||||
|
||||
|
||||
@@ -26,9 +26,9 @@ class release extends control
|
||||
$this->loadModel('product')->setMenu($productID, $branch);
|
||||
|
||||
$product = $this->product->getById($productID);
|
||||
$products = $this->product->getPairs('all', 0, '', 'all');
|
||||
if(empty($product)) $this->locate($this->createLink('product', 'create'));
|
||||
|
||||
$products = $this->product->getPairs('all', 0, '', 'all');
|
||||
$this->product->checkAccess($productID, $products);
|
||||
|
||||
$this->view->product = $product;
|
||||
@@ -48,20 +48,35 @@ class release extends control
|
||||
* @param int $recTotal
|
||||
* @param int $recPerPage
|
||||
* @param int $pageID
|
||||
* @param string $from
|
||||
* @param int $blockID
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function browse(int $productID, string $branch = 'all', string $type = 'all', string $orderBy = 't1.date_desc', string $param = '', int $recTotal = 0, int $recPerPage = 20, int $pageID = 1)
|
||||
public function browse(int $productID, string $branch = 'all', string $type = 'all', string $orderBy = 't1.date_desc', string $param = '', int $recTotal = 0, int $recPerPage = 20, int $pageID = 1, string $from = 'product', int $blockID = 0)
|
||||
{
|
||||
if($from === 'doc')
|
||||
{
|
||||
$this->app->loadLang('doc');
|
||||
|
||||
$products = $this->loadModel('product')->getPairs('all', 0, '', 'all');
|
||||
if(empty($products)) return $this->send(array('result' => 'fail', 'message' => $this->lang->doc->tips->noProduct));
|
||||
|
||||
if(!$productID) $productID = key($products);
|
||||
|
||||
$this->view->products = $products;
|
||||
}
|
||||
|
||||
$this->commonAction($productID, $branch);
|
||||
|
||||
$this->app->loadClass('pager', true);
|
||||
$pager = new pager($recTotal, $recPerPage, $pageID);
|
||||
$this->commonAction($productID, $branch);
|
||||
|
||||
$uri = $this->app->getURI(true);
|
||||
$this->session->set('releaseList', $uri, 'product');
|
||||
$this->session->set('buildList', $uri);
|
||||
$showBranch = $this->view->product->type != 'normal';
|
||||
|
||||
$showBranch = $this->view->product->type != 'normal';
|
||||
if(!$showBranch)
|
||||
{
|
||||
unset($this->config->release->dtable->fieldList['branch']);
|
||||
@@ -73,7 +88,7 @@ class release extends control
|
||||
if(strpos($sort, 'branchName_') !== false) $sort = str_replace('branchName_', 'branch_', $sort);
|
||||
|
||||
$queryID = $type == 'bySearch' ? (int)$param : 0;
|
||||
$actionURL = $this->createLink('release', 'browse', "productID={$productID}&branch={$branch}&type=bySearch&orderBy={$sort}¶m=myQueryID");
|
||||
$actionURL = $this->createLink('release', 'browse', "productID={$productID}&branch={$branch}&type=bySearch&orderBy={$sort}¶m=myQueryID&recTotal=$recTotal&recPerPage=$recPerPage&pageID=$pageID&from=$from&blockID=$blockID");
|
||||
$this->releaseZen->buildSearchForm($queryID, $actionURL, $this->view->product, $branch);
|
||||
|
||||
$releaseQuery = $type == 'bySearch' ? $this->releaseZen->getSearchQuery($queryID) : '';
|
||||
@@ -94,6 +109,16 @@ class release extends control
|
||||
$this->view->branchPairs = $this->loadModel('branch')->getPairs($productID);
|
||||
$this->view->appList = $this->loadModel('system')->getPairs();
|
||||
$this->view->childReleases = $this->release->getListByCondition(explode(',', $children), 0, true);
|
||||
$this->view->from = $from;
|
||||
$this->view->blockID = $blockID;
|
||||
$this->view->idList = '';
|
||||
|
||||
if($from === 'doc')
|
||||
{
|
||||
$content = $this->loadModel('doc')->getDocBlockContent($blockID);
|
||||
$this->view->idList = zget($content, 'idList', '');
|
||||
}
|
||||
|
||||
$this->display();
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
.red{color: red;}
|
||||
.mb-4-important{margin-bottom: 12px!important}
|
||||
|
||||
@@ -46,3 +46,42 @@ window.getCellSpan = function(cell)
|
||||
return {rowSpan: cell.row.data.rowspan};
|
||||
}
|
||||
}
|
||||
|
||||
window.insertListToDoc = function()
|
||||
{
|
||||
const dtable = zui.DTable.query($('#releases'));
|
||||
const checkedList = dtable.$.getChecks();
|
||||
if(!checkedList.length) return;
|
||||
|
||||
let {cols, data} = dtable.options;
|
||||
data = data.filter((item) => checkedList.includes(item.id + ''));
|
||||
const docID = getDocApp()?.docID;
|
||||
|
||||
const blockType = 'productRelease';
|
||||
const url = $.createLink('doc', 'buildZentaoList', `docID=${docID}&type=${blockType}&blockID=${blockID}`);
|
||||
const formData = new FormData();
|
||||
formData.append('cols', JSON.stringify(cols));
|
||||
formData.append('data', JSON.stringify(data));
|
||||
formData.append('idList', checkedList.join(','));
|
||||
formData.append('url', insertListLink);
|
||||
$.post(url, formData, function(resp)
|
||||
{
|
||||
resp = JSON.parse(resp);
|
||||
if(resp.result == 'success')
|
||||
{
|
||||
const oldBlockID = resp.oldBlockID;
|
||||
const newBlockID = resp.newBlockID;
|
||||
zui.Modal.hide();
|
||||
window.insertZentaoList && window.insertZentaoList(blockType, newBlockID, null, oldBlockID);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
window.firstRendered = false;
|
||||
window.toggleCheckRows = function(idList)
|
||||
{
|
||||
if(!idList?.length || firstRendered) return;
|
||||
firstRendered = true;
|
||||
const dtable = zui.DTable.query($('#releases'));
|
||||
dtable.$.toggleCheckRows(idList.split(','), true);
|
||||
}
|
||||
|
||||
@@ -10,16 +10,79 @@ declare(strict_types=1);
|
||||
*/
|
||||
namespace zin;
|
||||
|
||||
dropmenu();
|
||||
$isFromDoc = $from == 'doc';
|
||||
|
||||
$isFromDoc ? null : dropmenu();
|
||||
|
||||
if($isFromDoc)
|
||||
{
|
||||
jsVar('blockID', $blockID);
|
||||
|
||||
$this->app->loadLang('doc');
|
||||
$productChangeLink = createLink('release', 'browse', "productID={productID}&branch=$branch&type=$type&orderBy=$orderBy¶m=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}&from=$from&blockID=$blockID");
|
||||
|
||||
jsVar('insertListLink', createLink('release', 'browse', "productID={$product->id}&branch=$branch&type=$type&orderBy=$orderBy¶m=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}&from=$from&blockID={blockID}"));
|
||||
|
||||
formPanel
|
||||
(
|
||||
setID('zentaolist'),
|
||||
setClass('mb-4-important'),
|
||||
set::title(sprintf($this->lang->doc->insertTitle, $this->lang->doc->zentaoList['productRelease'])),
|
||||
set::actions(array()),
|
||||
set::showExtra(false),
|
||||
to::titleSuffix
|
||||
(
|
||||
span
|
||||
(
|
||||
setClass('text-muted text-sm text-gray-600 font-light'),
|
||||
span
|
||||
(
|
||||
setClass('text-warning mr-1'),
|
||||
icon('help'),
|
||||
),
|
||||
$lang->doc->previewTip
|
||||
)
|
||||
),
|
||||
formRow
|
||||
(
|
||||
formGroup
|
||||
(
|
||||
set::width('1/2'),
|
||||
set::name('product'),
|
||||
set::label($lang->doc->product),
|
||||
set::control(array('required' => false)),
|
||||
set::items($products),
|
||||
set::value($product->id),
|
||||
set::required(),
|
||||
span
|
||||
(
|
||||
setClass('error-tip text-danger hidden'),
|
||||
$lang->doc->emptyError
|
||||
),
|
||||
on::change('[name="product"]')->do("loadModal('$productChangeLink'.replace('{productID}', $(this).val()))")
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/* zin: Define the set::module('release') feature bar on main menu. */
|
||||
featureBar
|
||||
(
|
||||
set::current($type),
|
||||
set::linkParams("productID={$product->id}&branch={$branch}&type={key}&orderBy={$orderBy}¶m=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}"),
|
||||
li(searchToggle(set::module('release'), set::open($type == 'bySearch')))
|
||||
set::linkParams("productID={$product->id}&branch={$branch}&type={key}&orderBy={$orderBy}¶m=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}&from={$from}&blockID={$blockID}"),
|
||||
set::isModal($isFromDoc),
|
||||
set::modalTarget('#releases_table'),
|
||||
li(searchToggle
|
||||
(
|
||||
set::simple($isFromDoc),
|
||||
set::open($type == 'bysearch'),
|
||||
set::module('release'),
|
||||
$isFromDoc ? set::target('#docSearchForm') : null
|
||||
))
|
||||
);
|
||||
|
||||
if($isFromDoc) div(setID('docSearchForm'));
|
||||
|
||||
/* zin: Define the toolbar on main menu. */
|
||||
$canCreateRelease = hasPriv('release', 'create') && common::canModify('product', $product);
|
||||
$canManageSystem = hasPriv('system', 'browse') && common::canModify('product', $product);
|
||||
@@ -27,6 +90,7 @@ if($canCreateRelease) $createItem = array('icon' => 'plus', 'class' => 'primary'
|
||||
if($canManageSystem) $manageSystemItem = array('class' => 'primary', 'text' => $lang->release->manageSystem, 'url' => $this->createLink('system', 'browse', "productID={$product->id}"), 'data-app' => 'product');
|
||||
toolbar
|
||||
(
|
||||
setClass(array('hidden' => $isFromDoc)),
|
||||
!empty($manageSystemItem) ? item(set($manageSystemItem)) : null,
|
||||
!empty($createItem) ? item(set($createItem)) : null
|
||||
);
|
||||
@@ -44,19 +108,31 @@ foreach(array_column($releases, 'system') as $system)
|
||||
}
|
||||
if(!empty($cols['system'])) $cols['system']['map'] = array(0 => '') + $appList;
|
||||
|
||||
if($isFromDoc)
|
||||
{
|
||||
$cols['id']['type'] = 'checkID';
|
||||
|
||||
if(isset($cols['actions'])) unset($cols['actions']);
|
||||
|
||||
foreach($cols as $key => $col)
|
||||
{
|
||||
$cols[$key]['sortType'] = false;
|
||||
if(isset($col['link'])) unset($cols[$key]['link']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$releases = initTableData($releases, $cols, $this->release);
|
||||
dtable
|
||||
(
|
||||
set::id('releases'),
|
||||
set::cols(array_values($cols)),
|
||||
set::data($releases),
|
||||
set::customCols(true),
|
||||
set::rowKey('rowID'),
|
||||
set::plugins(array('cellspan')),
|
||||
set::onRenderCell(jsRaw('window.renderCell')),
|
||||
set::getCellSpan(jsRaw('window.getCellSpan')),
|
||||
set::orderBy($orderBy),
|
||||
set::sortLink(createLink('release', 'browse', "productID={$product->id}&branch={$branch}&type={$type}&orderBy={name}_{sortType}¶m=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}")),
|
||||
set::footer([jsRaw("function(){return {html: '{$pageSummary}'};}"), 'flex', 'pager']),
|
||||
set::footPager(
|
||||
usePager
|
||||
(
|
||||
@@ -64,8 +140,14 @@ dtable
|
||||
)
|
||||
),
|
||||
set::emptyTip($lang->release->noRelease),
|
||||
set::createTip($lang->release->create),
|
||||
set::createLink($canCreateRelease ? createLink('release', 'create', "productID={$product->id}&branch={$branch}") : '')
|
||||
set::checkable($isFromDoc),
|
||||
$isFromDoc ? set::footToolbar(array(array('text' => $lang->doc->insertText, 'data-on' => 'click', 'data-call' => 'insertListToDoc'))) : set::footer([jsRaw("function(){return {html: '{$pageSummary}'};}"), 'flex', 'pager']),
|
||||
!$isFromDoc ? null : set::afterRender(jsCallback()->call('toggleCheckRows', $idList)),
|
||||
!$isFromDoc ? null : set::height(400),
|
||||
$isFromDoc ? null : set::customCols(true),
|
||||
$isFromDoc ? null : set::sortLink(createLink('release', 'browse', "productID={$product->id}&branch={$branch}&type={$type}&orderBy={name}_{sortType}¶m=$param&recTotal={$pager->recTotal}&recPerPage={$pager->recPerPage}&pageID={$pager->pageID}")),
|
||||
$isFromDoc ? null : set::createTip($lang->release->create),
|
||||
$isFromDoc ? null : set::createLink($canCreateRelease ? createLink('release', 'create', "productID={$product->id}&branch={$branch}") : '')
|
||||
);
|
||||
|
||||
/* ====== Render page ====== */
|
||||
|
||||
Reference in New Issue
Block a user