From 841ae4d1b7e6498baf6af57f9a745aafeb87e73f Mon Sep 17 00:00:00 2001 From: Alex Gusev Date: Tue, 19 May 2020 18:57:09 +0300 Subject: [PATCH] OWN-159 Add grid to view reports --- App/Repo/Query/ClauseSet/Processor.php | 37 +++++++----- App/Repo/Query/Grid.php | 9 ++- App/Repo/Query/Grid/Builder.php | 18 +++++- App/Ui/DataProvider/Admin/Grid.php | 7 ++- view/adminhtml/web/js/grid/column/decimal.js | 46 +++++++++++++++ view/adminhtml/web/js/grid/column/integer.js | 18 ++++++ view/adminhtml/web/js/grid/column/link.js | 59 +++++++++++++++++++ .../web/template/grid/cells/number.html | 4 ++ 8 files changed, 179 insertions(+), 19 deletions(-) create mode 100644 view/adminhtml/web/js/grid/column/decimal.js create mode 100644 view/adminhtml/web/js/grid/column/integer.js create mode 100644 view/adminhtml/web/js/grid/column/link.js create mode 100644 view/adminhtml/web/template/grid/cells/number.html diff --git a/App/Repo/Query/ClauseSet/Processor.php b/App/Repo/Query/ClauseSet/Processor.php index c735853..697c7e0 100644 --- a/App/Repo/Query/ClauseSet/Processor.php +++ b/App/Repo/Query/ClauseSet/Processor.php @@ -7,6 +7,7 @@ */ namespace Flancer32\Base\App\Repo\Query\ClauseSet; + /** * Apply set of clauses on query. */ @@ -25,14 +26,16 @@ public function __construct( /** * @param \Magento\Framework\DB\Select $query * @param \Flancer32\Base\App\Repo\Data\ClauseSet $clauses + * @param array $aliasMap * @param bool $filterOnly 'true' - apply only filter clauses (for totals) */ public function exec( \Magento\Framework\DB\Select $query, \Flancer32\Base\App\Repo\Data\ClauseSet $clauses, + $aliasMap = null, $filterOnly = false ) { - $aliases = $this->mapAliases($query); + $aliases = is_null($aliasMap) ? $this->mapAliases($query) : $aliasMap; $filter = $clauses->filter; $order = $clauses->order; $pagination = $clauses->pagination; @@ -44,22 +47,26 @@ public function exec( } /** - * @param $query + * @param \Magento\Framework\DB\Select $query * @return array */ private function mapAliases(\Magento\Framework\DB\Select $query) { $result = []; - $columns = $query->getPart(\Zend_Db_Select::COLUMNS); - foreach ($columns as $one) { - $table = $one[0]; - $expression = $one[1]; - $alias = $one[2]; - $data = new \Flancer32\Base\App\Repo\Query\ClauseSet\Processor\AliasMapEntry(); - $data->alias = $alias; - $data->expression = $expression; - $data->table = $table; - $result[$alias] = $data; + try { + $columns = $query->getPart(\Zend_Db_Select::COLUMNS); + foreach ($columns as $one) { + $table = $one[0]; + $expression = $one[1]; + $alias = $one[2]; + $data = new \Flancer32\Base\App\Repo\Query\ClauseSet\Processor\AliasMapEntry(); + $data->alias = $alias; + $data->expression = $expression; + $data->table = $table; + $result[$alias] = $data; + } + } catch (\Zend_Db_Select_Exception $e) { + // just stealth the exception } return $result; } @@ -67,7 +74,9 @@ private function mapAliases(\Magento\Framework\DB\Select $query) private function processFilter($query, $filter, $aliases) { $where = $this->ownFilterParser->parse($filter, $aliases); - if ($where) $query->where($where); + if ($where) { + $query->where($where); + } } private function processOrder($query, $order, $aliases) @@ -99,4 +108,4 @@ private function processPagination($query, $pagination) } } } -} \ No newline at end of file +} diff --git a/App/Repo/Query/Grid.php b/App/Repo/Query/Grid.php index 36da3b5..0d2bc71 100644 --- a/App/Repo/Query/Grid.php +++ b/App/Repo/Query/Grid.php @@ -10,6 +10,13 @@ interface Grid { + /** + * Map SELECT aliases to "table.column" or "expression" to process UI clauses in . + * + * @return array + */ + public function getAliasMap(); + /** * Base query to select total count for the grid. * @@ -23,4 +30,4 @@ public function getCountQuery(); * @return \Magento\Framework\DB\Select */ public function getSelectQuery(); -} \ No newline at end of file +} diff --git a/App/Repo/Query/Grid/Builder.php b/App/Repo/Query/Grid/Builder.php index 1434164..61f7dfe 100644 --- a/App/Repo/Query/Grid/Builder.php +++ b/App/Repo/Query/Grid/Builder.php @@ -27,4 +27,20 @@ public function __construct( $this->conn = $resource->getConnection(); } -} \ No newline at end of file + /** + * Use in children to create mapping for aliases to table.column or expression. + * + * @param $alias + * @param $table + * @param $expression + * @return \Flancer32\Base\App\Repo\Query\ClauseSet\Processor\AliasMapEntry + */ + protected function createAliasMapEntry($alias, $table, $expression) + { + $result = new \Flancer32\Base\App\Repo\Query\ClauseSet\Processor\AliasMapEntry(); + $result->alias = $alias; + $result->table = $table; + $result->expression = $expression; + return $result; + } +} diff --git a/App/Ui/DataProvider/Admin/Grid.php b/App/Ui/DataProvider/Admin/Grid.php index 87b7a6b..adf7b8b 100644 --- a/App/Ui/DataProvider/Admin/Grid.php +++ b/App/Ui/DataProvider/Admin/Grid.php @@ -74,12 +74,13 @@ public function getData() $criteria = $this->getSearchCriteria(); $clauses = $this->adptClauseSet->getClauseSet($criteria); + $map = $this->qGrid->getAliasMap(); $qTotal = $this->qGrid->getCountQuery(); - $this->procClauseSet->exec($qTotal, $clauses, true); + $this->procClauseSet->exec($qTotal, $clauses, $map, true); $totals = $this->conn->fetchOne($qTotal); $qItems = $this->qGrid->getSelectQuery(); - $this->procClauseSet->exec($qItems, $clauses); + $this->procClauseSet->exec($qItems, $clauses, $map); $items = $this->conn->fetchAll($qItems); $result = [ 'items' => $items, @@ -87,4 +88,4 @@ public function getData() ]; return $result; } -} \ No newline at end of file +} diff --git a/view/adminhtml/web/js/grid/column/decimal.js b/view/adminhtml/web/js/grid/column/decimal.js new file mode 100644 index 0000000..2231820 --- /dev/null +++ b/view/adminhtml/web/js/grid/column/decimal.js @@ -0,0 +1,46 @@ +/** + * UI component to render cell data as a decimal number. + * + * Based on "./magento/module-ui/view/base/web/js/grid/columns/column.js" + */ +define([ + "Magento_Ui/js/grid/columns/column" +], function (Column) { + "use strict"; + /** + * Formatting function. + * See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat + */ + const language = 'en-US'; + const fraction = 2; + const options = { + minimumFractionDigits: fraction, + maximumFractionDigits: fraction + }; + const formatter = new Intl.NumberFormat(language, options); + const fnFormat = function (num) { + const value = Number(num); + const result = formatter.format(value); + return result; + } + + /** + * Magento UI component based on 'Column': + */ + return Column.extend({ + defaults: { + bodyTmpl: 'Flancer32_Base/grid/cells/number', + }, + + /** + * Override parent function to format numeric value. + * + * @param {Object} row + * @returns {String} + */ + getLabel: function (row) { + const num = Column.prototype.getLabel.apply(this, [row]); + return fnFormat(num); + } + }); +}); diff --git a/view/adminhtml/web/js/grid/column/integer.js b/view/adminhtml/web/js/grid/column/integer.js new file mode 100644 index 0000000..f95b136 --- /dev/null +++ b/view/adminhtml/web/js/grid/column/integer.js @@ -0,0 +1,18 @@ +/** + * UI component to render cell data as an integer number. + * + * Based on "./magento/module-ui/view/base/web/js/grid/columns/column.js" + */ +define([ + "Magento_Ui/js/grid/columns/column" +], function (Column) { + "use strict"; + /** + * Magento UI component based on "Column": + */ + return Column.extend({ + defaults: { + bodyTmpl: "Flancer32_Base/grid/cells/number", + } + }); +}); diff --git a/view/adminhtml/web/js/grid/column/link.js b/view/adminhtml/web/js/grid/column/link.js new file mode 100644 index 0000000..b1b6618 --- /dev/null +++ b/view/adminhtml/web/js/grid/column/link.js @@ -0,0 +1,59 @@ +/** + * Base UI component to render row data as link to other adminhtml routes. + */ +define([ + "Magento_Ui/js/grid/columns/column", + "mageUtils" +], function (Column, utils) { + "use strict"; + + + /** + * Remove route part from BASE URL (http://.../admin/customer/ => http://.../admin). + * + * BASE_URL see at "./module-backend/view/adminhtml/templates/page/js/require_js.phtml" + */ + const ROOT_URL = function () { + const length = BASE_URL.length; + const lastCharOff = BASE_URL.substr(0, length - 1); + const lastSlashPos = lastCharOff.lastIndexOf('/'); + const result = BASE_URL.substr(0, lastSlashPos); + return result; + }(); + + return Column.extend({ + defaults: { + /** + * Replace idAttrName & route in children. + */ + /* name of the identification attribute */ + idAttrName: "customerId", + /* route part to the page */ + route: "/customer/index/edit/id/", + bodyTmpl: "ui/grid/cells/link" + }, + + /** + * Returns link to given record. + * + * @param {object} record - grid row data. + * @returns {string} + */ + getLink: function (record) { + const id = utils.nested(record, this.idAttrName); + const result = ROOT_URL + this.route + id; + return result; + }, + + /** + * Check if link attribute exists in record. + * + * @param {object} record - grid row data. + * @returns {boolean} + */ + isLink: function (record) { + const result = !!utils.nested(record, this.idAttrName); + return result; + } + }); +}); diff --git a/view/adminhtml/web/template/grid/cells/number.html b/view/adminhtml/web/template/grid/cells/number.html new file mode 100644 index 0000000..1ba9176 --- /dev/null +++ b/view/adminhtml/web/template/grid/cells/number.html @@ -0,0 +1,4 @@ + +
+
+