diff --git a/module/program/control.php b/module/program/control.php index d78837e901..aefba7d50f 100644 --- a/module/program/control.php +++ b/module/program/control.php @@ -883,7 +883,7 @@ class program extends control /* Load module and set session. */ $this->loadModel('product'); $this->loadModel('user'); - $this->session->set('productView', $this->app->getURI(true), 'program'); + $this->session->set('productList', $this->app->getURI(true), 'program'); $queryID = ($browseType == 'bySearch') ? (int)$param : 0; @@ -913,17 +913,17 @@ class program extends control $actionURL = $this->createLink('program', 'productview', "browseType=bySearch&orderBy=order_asc&queryID=myQueryID"); $this->product->buildProductSearchForm($param, $actionURL); - $this->view->title = $this->lang->product->common; - $this->view->recTotal = $pager->recTotal; - $this->view->productStats = $productStats; - $this->view->productStructure = $productStructure; - $this->view->productLines = $productLines; - $this->view->programLines = $programLines; - $this->view->users = $this->user->getPairs('noletter'); - $this->view->orderBy = $orderBy; - $this->view->browseType = $browseType; - $this->view->pager = $pager; - $this->view->showBatchEdit = $this->cookie->showProductBatchEdit; + $this->view->title = $this->lang->product->common; + $this->view->recTotal = $pager->recTotal; + $this->view->productStats = $productStats; + $this->view->productStructure = $productStructure; + $this->view->productLines = $productLines; + $this->view->programLines = $programLines; + $this->view->users = $this->user->getPairs('noletter'); + $this->view->orderBy = $orderBy; + $this->view->browseType = $browseType; + $this->view->pager = $pager; + $this->view->checkedEditProduct = !empty((int)$this->cookie->checkedEditProduct); $this->render(); } diff --git a/module/program/js/productview.ui.js b/module/program/js/productview.ui.js index 48182a6a98..882a426fb1 100644 --- a/module/program/js/productview.ui.js +++ b/module/program/js/productview.ui.js @@ -3,7 +3,7 @@ window.footerGenerator = function() return [{children: summary, className: "text-dark"}, "flex", "pager"]; } -window.renderReleaseCountCell = function(result, {col, row}) +window.renderCellProductView = function(result, {col, row}) { if(col.name === 'createdDate') { @@ -47,3 +47,70 @@ window.iconRenderProductView = function(value, row) return ''; } + +/** + * Submit data to product batch edit page by html form while click on the batch edit button. + * + * @param object event + * @access public + * @return void + */ +onClickBatchEdit = function(event) +{ + event.stopPropagation(); + event.preventDefault(); + + /* Get checked product ID list. */ + const dtable = zui.DTable.query(event.target); + const checkedList = dtable.$.getChecks(); + + if(checkedList.length === 0) return; + + /* Create form. */ + const f = document.createElement("form"); + f.action = $(event.target).attr('href'); + f.method = "POST"; + f.target = "_self"; + + /* Create element to carry data. */ + checkedList.forEach(function(id) + { + if(id.includes('-')) return; + + const item = document.createElement('input'); + item.name = 'productIDList[]'; + item.value = id; + + f.appendChild(item); + }); + + /* Append form to body. */ + document.body.appendChild(f); + + f.submit(); +} + +onClickCheckBatchEdit = function(event) +{ + $.cookie.set('checkedEditProduct', 1); + loadCurrentPage(["table/#dtable:type=json&data=props"]); +} + +window.footerSummary = function(checkedIdList) +{ + if(!checkedIdList.length) + { + return {html: pageSummary, className: 'text-dark'}; + } + + let totalProducts = 0; + checkedIdList.forEach(function(id) + { + if(id.includes('-')) return; + totalProducts++; + }); + + var summary = checkedSummary.replace('%total%', totalProducts); + + return {html: summary}; +} diff --git a/module/program/ui/productview.html.php b/module/program/ui/productview.html.php index 0f5bc6fd8f..031ec6f68b 100644 --- a/module/program/ui/productview.html.php +++ b/module/program/ui/productview.html.php @@ -12,6 +12,9 @@ declare(strict_types=1); namespace zin; +$canBatchEdit = common::hasPriv('product', 'batchEdit'); +$hasProduct = false; + /* Closure creating program buttons. */ $fnGenerateCreateProgramBtns = function() use ($lang, $browseType) { @@ -58,9 +61,20 @@ $fnGenerateCreateProgramBtns = function() use ($lang, $browseType) }; /* Generate cols for the data table. */ -$fnGenerateCols = function() +$fnGenerateCols = function() use ($canBatchEdit) { - return $this->loadModel('datatable') ->getSetting('program'); + $cols = $this->loadModel('datatable') ->getSetting('program'); + + foreach($cols as $colName => &$setting) + { + if($colName == 'name') + { + $setting['checkbox'] = $canBatchEdit; + break; + } + } + + return $cols; }; /* Closure for generating program row data. */ @@ -200,15 +214,16 @@ foreach($productStructure as $programID => $program) foreach($line['products'] as $productID => $product) { $productRow = $fnGenerateProductRowData($lineID, $product); - if(!empty($productRow)) - { - $totalProductExecutions += $productRow->totalExecutions; - $totalProductBugs += $productRow->totalBugs; - $totalProductActiveBugs += $productRow->totalActivatedBugs; - $totalProductProjects += $productRow->totalProjects; - $data[] = $productRow; - } + $totalProductExecutions += $productRow->totalExecutions; + $totalProductBugs += $productRow->totalBugs; + $totalProductActiveBugs += $productRow->totalActivatedBugs; + $totalProductProjects += $productRow->totalProjects; + + $data[] = $productRow; + + /* Set flag variable. */ + $hasProduct = true; } } @@ -243,22 +258,23 @@ foreach($productStructure as $programID => $program) } } -$summary = sprintf($lang->product->lineSummary, $linesCount, count($productStats)); -jsVar('summary', $summary); - -/* Layout. */ +/* ZIN: layout. */ featureBar ( set::current($browseType), set::linkParams("status={key}&orderBy=$orderBy"), - (hasPriv('product', 'batchEdit') && $hasProduct === true) ? item + (hasPriv('product', 'batchEdit') && $hasProduct === true) ? li(checkbox ( + on::click('onClickCheckBatchEdit'), set::type('checkbox'), set::text($lang->project->edit), + set('data-id', 'checkbox-batchedit'), + set('data-load', 'table'), set::checked($this->cookie->editProject) - ) : NULL, - li(searchToggle()) + )) : NULL, + li(searchToggle(set::open($browseType == 'bySearch'))), + li(btn(setClass('ghost'), set::icon('unfold-all'), $lang->sort)) ); toolbar @@ -285,12 +301,28 @@ dtable set::data($data), set::userMap($users), set::customCols(true), - set::checkable(true), + set::checkable($canBatchEdit), set::nested(true), set::className('shadow rounded'), set::footPager(usePager()), - set::onRenderCell(jsRaw('window.renderReleaseCountCell')), - set::footer(jsRaw('window.footerGenerator()')) + set::onRenderCell(jsRaw('window.renderCellProductView')), + set::footToolbar(array + ( + 'type' => 'btn-group', + 'items' => array( + $canBatchEdit ? array + ( + 'text' => $lang->edit, + 'btnType' => 'secondary', + 'url' => createLink('product', 'batchEdit'), + 'onClick' => jsRaw('onClickBatchEdit') + ) : null + ) + )), + set::checkInfo(jsRaw("function(checkedIDList){ return window.footerSummary(checkedIDList);}")) ); +jsVar('pageSummary', sprintf($lang->product->lineSummary, $linesCount, count($productStats))); +jsVar('checkedSummary', $lang->program->checkedProducts); + render();