LP#
1831788: add result filtering and other improvements to the Angular eg-grid
This patch enables users to filter results in Angular eg-grids that
use PCRUD-based data sources.
Filtering can be enabled in an eg-grid defintion by adding the following
attribute to <eg-grid>:
[filterable]="true"
If, for some reason, a particular column should not be filterable by the
user, filtering can be disabled by passing false to the [filterable]
attribute of an <eg-grid-column> element like this:
<eg-grid-column [sortable]="true" [filterable]="false" path="barcode"></eg-grid-column>
When filtering is enabled, a new section of the grid header is displayed that
includes, for each filterable column:
* A drop-down menu letting the user specify an operator such as
"is exactly", "exists" (i.e., is not null), "is greater than", and so
forth. The drop-down also allows the user to clear a filter for a
specific column or re-apply it after changing the operator.
* An input widget for setting the value to filter on. The type of input
displayed depend on the IDL type of the column. For example, a text field
will use a normal text <input>; an OU field will use an eg-org-select,
a link to another IDL class will use a combobox, a timestamp field
will use an eg-date-select, and so forth.
* A separate display of the current operator.
When filtering is enabled, the grid will also display a "Remove Filters" button
in the action bar.
Under the hood, the widgets for entering filtering parameters expect
the data source to have a "filters" key that in turn contains a
dictionary of PCRUD-style filtering conditions indexed by column name.
Consequently, a grid data source that wants to use filtering should
look something like this:
this.acpSource.getRows = (pager: Pager, sort: any[]) => {
const orderBy: any = {acp: 'id'};
if (sort.length) {
orderBy.acp = sort[0].name + ' ' + sort[0].dir;
}
// base query to grab everything
let base: Object = {};
base[this.idl.classes['acp'].pkey] = {'!=' : null};
var query: any = new Array();
query.push(base);
// and add any filters
Object.keys(this.acpSource.filters).forEach(key => {
Object.keys(this.acpSource.filters[key]).forEach(key2 => {
query.push(this.acpSource.filters[key][key2]);
});
});
return this.pcrud.search('acp',
query, {
flesh: 1,
flesh_fields: {acp: ['location']},
offset: pager.offset,
limit: pager.limit,
order_by: orderBy
});
};
This patch also adds two related grid options, sticky headers and the ability
to reload the data source without losing one's current place in page.
Sticky headers are enabled by adding the following attribute to the
<eg-grid> element:
[stickyHeader]="true"
When this is enabled, as the user scrolls the grid from top to bottom, the
header row, including the filter controls, will continue to remain visible
at the top of the viewport until the user scrolls past the end of the
grid entirely.
Reloading grids without losing the current paging settings can now be
done by a caller (such as code that opens an edit modal) invoking a new
reloadSansPagerReset() method.
Implementation Notes
--------------------
[1] This patch adds special-case logic for handling the "dob" column,
which is the sole date column in the Evergreen schema. Longer-term,
it would be better to define a new "date" IDL field type that's
distinct from "timestamp".
[2] stickyHeader currently makes only the grid header sticky, not both
the header and the action bar. This outcome is a result of z-index
messiness with the ng-bootstrap dropdown menu which I couldn't get
past. However, the forthcoming grid context menus hopefully will
be a reasonable amelioration.
[3] During testing it became evident that it would be handy to add
support for open-ils.fielder as a grid data source at some
point in the near future.
To test
-------
General testing can be done using the new second grid in the
Angular sandbox page added by the following test. Things to check
include:
- grid filter operators are displayed
- hitting enter in text inputs activates the filter
- the grid-level Remove Filters button works
- per-column filter clearing works
- operators have the expected results
- The header of both grids on the sandbox page is sticky. This can
be tested by increasing the row count in the second grid and
scrolling.
Sponsored-by: MassLNC
Sponsored-by: Georgia Public Library Service
Sponsored-by: Indiana State Library
Sponsored-by: CW MARS
Sponsored-by: King County Library System
Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Signed-off-by: Jane Sandberg <sandbej@linnbenton.edu>