Skip to content

Commit

Permalink
fix(journal): ui-grid expands all rows by default
Browse files Browse the repository at this point in the history
Fixes #573.

This commit fixes the bug that collapsed all rows of the grid by default
using a $timeout hack.

It also migrates the entire journal grouping service to a independent
service fit to be attached to any grid.  This partially addresses #376.
  • Loading branch information
Jonathan Niles committed Jul 21, 2016
1 parent deb4e2d commit 447bc8a
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 146 deletions.
156 changes: 156 additions & 0 deletions client/src/js/services/grid/GridGrouping.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
angular.module('bhima.services')
.service('GridGroupingService', GridGroupingService);

GridGroupingService.$inject = [
'uiGridGroupingConstants', '$filter', 'SessionService', '$timeout', 'util'
];

/**
* Grid Grouping Service
*
* This service is responsible for setting the grouping configuration for the
* client side posting journal module. It also provides a number of helper
* methods that can be used to provide custom transaction grouping.
*/
function GridGroupingService(uiGridGroupingConstants, $filter, Session, $timeout, util) {

// cache the enterprise currency id for easy lookup
var currencyId = Session.enterprise.currency_id;

// cache the currency filter for later lookup
var $currency = $filter('currency');

/** @const renders any currencied amount */
var DEFAULT_COST_AGGREGATOR = {

// used to render amounts in the aggregate columns
// TODO - this should render the currency from the row set.
customTreeAggregationFinalizerFn : function amountRenderer(aggregation) {
//console.log('aggregation:', aggregation);
aggregation.rendered = $currency(aggregation.value, currencyId);
},

treeAggregationType : uiGridGroupingConstants.aggregation.SUM,
};

/** @const aggregates quantities as needed */
var DEFAULT_QUANTITY_AGGREGATOR= {
treeAggregationType : uiGridGroupingConstants.aggregation.SUM,
};

/** @const aggregators assigned by column ids */
var DEFAULT_AGGREGATORS = {
'debit_equiv' : DEFAULT_COST_AGGREGATOR,
'credit_equiv' : DEFAULT_COST_AGGREGATOR,
'cost' : DEFAULT_COST_AGGREGATOR,
'quantity' : DEFAULT_QUANTITY_AGGREGATOR,
'amount' : DEFAULT_QUANTITY_AGGREGATOR
};

/**
* @method configureDefaultAggregators
*
* @description
* Certain columns will always be aggregated in certain ways. For example,
* debit and credit fields should always be summed, no matter scenario. This
* function will scan the grid columns for common fields and provide pre-made
* aggregators for those columns.
*
* @param {Object} columns - the columns object from the gridOptions
*
* @private
*/
function configureDefaultAggregators(columns) {
columns.forEach(function (column) {
var aggregator = DEFAULT_AGGREGATORS[column.field];

if (aggregator) {
column.treeAggregationType = aggregator.treeAggregationType;
column.customTreeAggregationFinalizerFn = aggregator.customTreeAggregationFinalizerFn;
}
});
}


/**
* @method selectAllGroupElements
*
* @description
* This method enables group level selections when the posting journal is grouped
* according to a column. It first checks to ensure the row that changed is a
* header and then selects each of the rows children.
*
* @param {object} rowChanged Object containing the row that has just been selected
*
* @private
*/
function selectAllGroupElements(rowChanged) {
var gridApi = this.gridApi;

// determine that this selection is a header row
if (angular.isDefined(rowChanged.treeLevel) && rowChanged.treeLevel > -1) {

var children = gridApi.treeBase.getRowChildren(rowChanged);
children.forEach(function (child) {

// determine if we should we be selected or deselecting
var select = rowChanged.isSelected ? gridApi.selection.selectRow : gridApi.selection.unSelectRow;
select(child.entity);
});
}
}

/**
* @method configureDefaultGroupingOptions
*
* @description
* This method binds grouping utility methods to UI grid API actions. It sets
* up the default grouping functionality of the grid, specifically:
* - Selecting a header row will select all children elements
* - Grid transactions will be expanded on initialisation
*
* @param {object} gridApi Angular UI Grid API
*
* @private
*/
function configureDefaultGroupingOptions(gridApi) {

// bind the group selection method
gridApi.selection.on.rowSelectionChanged(null, selectAllGroupElements.bind(this));

// hook into rows rendered call to ensure the grid is ready before expanding initial nodes
gridApi.core.on.rowsRendered(null, util.once(function () {
gridApi.grouping.groupColumn('trans_id');

// for the expandAllRows() to be fired last
$timeout(gridApi.treeBase.expandAllRows, 0, false);
}));
}

function GridGrouping(gridOptions) {
var cacheGridApi = gridOptions.onRegisterApi;

// global grouping configuration
gridOptions.enableGroupHeaderSelection = true;
gridOptions.treeRowHeaderAlwaysVisible = false;

// register for the grid API
gridOptions.onRegisterApi = function onRegisterApi(api) {
this.gridApi = api;

// attach custom renderers
configureDefaultAggregators(gridOptions.columnDefs);

// configure default grouping
configureDefaultGroupingOptions(api);

// call the method that had previously been registered to request the grid's API
if (angular.isDefined(cacheGridApi)) {
cacheGridApi(api);
}
}.bind(this);
}


return GridGrouping;
}
5 changes: 3 additions & 2 deletions client/src/js/services/grid/GridSorting.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,17 @@ function GridSortingService() {
gridOptions.enableSorting = true;

// // Register for the Grid API
gridOptions.onRegisterApi = function (api) {
gridOptions.onRegisterApi = function onRegisterApi(api) {
this.gridApi = api;

this.transactionIds = transactionIds.bind(this);

// Call the method that had previously been registered to request the grid's API
if (angular.isDefined(cacheGridApi)) {
cacheGridApi(api);
}
}.bind(this);

this.transactionIds = transactionIds.bind(this);
}

return GridSorting;
Expand Down
141 changes: 0 additions & 141 deletions client/src/js/services/grid/JournalGrouping.js

This file was deleted.

14 changes: 14 additions & 0 deletions client/src/js/services/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,18 @@ function UtilService($filter, moment) {
service.getMomentAge = function (date, duration) {
return duration ? moment().diff(date, duration) : moment().diff(date);
};

// ensure that a function is only called once.
service.once = function once(fn, context) {
var result;

return function () {

if (!fn) { return; }

// call the function only once
result = fn.apply(context || this, arguments);
fn = null;
};
};
}
7 changes: 4 additions & 3 deletions client/src/partials/journal/journal.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ angular.module('bhima.controllers')
.controller('JournalController', JournalController);

JournalController.$inject = [
'TransactionService', 'JournalService', 'GridSortingService', 'JournalGroupingService',
'TransactionService', 'JournalService', 'GridSortingService', 'GridGroupingService',
'JournalPaginationService', 'JournalFilteringService', 'GridColumnService', 'JournalConfigService',
'NotifyService'
];
Expand Down Expand Up @@ -31,7 +31,7 @@ JournalController.$inject = [
function JournalController(Transactions, Journal, Sorting, Grouping, Pagination, Filtering, Columns, Config, Notify) {
var vm = this;

// Journal utilites
// Journal utilities
var sorting, grouping, pagination, filtering, columnConfig;

// gridOptions is bound to the UI Grid and used to configure many of the
Expand All @@ -46,6 +46,8 @@ function JournalController(Transactions, Journal, Sorting, Grouping, Pagination,
pagination = new Pagination(vm.gridOptions, Transactions.list.data);
columnConfig = new Columns(vm.gridOptions, 'JournalColumns');

console.log('Grouping:', grouping);


// Populate the grid with posting journal data
Journal.read()
Expand Down Expand Up @@ -83,7 +85,6 @@ function JournalController(Transactions, Journal, Sorting, Grouping, Pagination,
headerCellFilter: 'translate' ,
sortingAlgorithm : sorting.transactionIds,
sort : { priority : 0, direction : 'asc' },
grouping : { groupPriority : 0 }
},

// @todo this should be formatted as a currency icon vs. an ID
Expand Down

0 comments on commit 447bc8a

Please sign in to comment.