LP#1942220: do client-side sorting for all attributes
authorGalen Charlton <gmc@equinoxOLI.org>
Mon, 13 Dec 2021 16:04:46 +0000 (11:04 -0500)
committerGalen Charlton <gmc@equinoxOLI.org>
Mon, 13 Dec 2021 16:04:46 +0000 (11:04 -0500)
This adds client-side sorting for title, author, and publisher
using Intl.Collator to achieve case-insenstive, punctuation-ignoring,
and numeral-sensitive sorting.

Signed-off-by: Galen Charlton <gmc@equinoxOLI.org>
Open-ILS/src/eg2/src/app/staff/acq/lineitem/lineitem-list.component.ts
Open-ILS/src/eg2/src/app/staff/acq/lineitem/lineitem.service.ts

index 2f49dfe..83ee4ba 100644 (file)
@@ -301,14 +301,18 @@ export class LineitemListComponent implements OnInit {
         }
         Object.assign(opts, SORT_ORDER_MAP[this.sortOrder]);
 
-        let _doingTitleSort = false;
-        if (this.sortOrder === 'title_asc' ||
-            this.sortOrder === 'title_desc') {
-            // if we're going to sort by title, we'll need
+        let _doingClientSort = false;
+        if (this.sortOrder === 'title_asc'      ||
+            this.sortOrder === 'title_desc'     ||
+            this.sortOrder === 'author_asc'     ||
+            this.sortOrder === 'author_desc'    ||
+            this.sortOrder === 'publisher_asc'  ||
+            this.sortOrder === 'publisher_desc') {
+            // if we're going to sort by an attribute, we'll need
             // to actually fetch LI attributes so that we can
             // do a client-side sorting pass that ignores
-            // articles
-            _doingTitleSort = true;
+            // articles and attempts international collation
+            _doingClientSort = true;
             opts['flesh_attrs'] = true;
         } else {
             // not doing a title sort, so we can rely on
@@ -325,7 +329,7 @@ export class LineitemListComponent implements OnInit {
             null,
             opts
         ).toPromise().then(resp => {
-            if (_doingTitleSort) {
+            if (_doingClientSort) {
                 const sortOrder = this.sortOrder;
                 const liService = this.liService;
                 function _compareLIs(a, b) {
index e211c84..928ee9b 100644 (file)
@@ -75,6 +75,9 @@ export class LineitemService {
     // Alerts the user has already confirmed are OK.
     alertAcks: {[id: number]: boolean} = {};
 
+    naturalCollator = new Intl.Collator(undefined,
+        {numeric: true, sensitivity: 'base', ignorePunctuation: true});
+
     constructor(
         private idl: IdlService,
         private net: NetService,
@@ -404,8 +407,7 @@ export class LineitemService {
         return   a_val === b_val ?  0 :
                  a_val === null  ?  1 :
                  b_val === null  ? -1 :
-                 a_val > b_val   ?  1 :
-                 a_val < b_val   ? -1 : 0;
+                 this.naturalCollator.compare(a_val, b_val);
     }
 
     // Given a line item, get its sort key