implement the run-immediately checkbox
authorGalen Charlton <gmc@equinoxinitiative.org>
Sat, 25 Jan 2020 15:28:08 +0000 (10:28 -0500)
committerGalen Charlton <gmc@equinoxinitiative.org>
Sat, 25 Jan 2020 15:28:08 +0000 (10:28 -0500)
Signed-off-by: Galen Charlton <gmc@equinoxinitiative.org>
Open-ILS/src/eg2/src/app/staff/acq/search/acq-search-form.component.html
Open-ILS/src/eg2/src/app/staff/acq/search/acq-search-form.component.ts
Open-ILS/src/eg2/src/app/staff/acq/search/acq-search.service.ts
Open-ILS/src/eg2/src/app/staff/acq/search/invoice-results.component.html
Open-ILS/src/eg2/src/app/staff/acq/search/lineitem-results.component.html
Open-ILS/src/eg2/src/app/staff/acq/search/picklist-results.component.html
Open-ILS/src/eg2/src/app/staff/acq/search/purchase-order-results.component.html
Open-ILS/src/sql/Pg/950.data.seed-values.sql
Open-ILS/src/sql/Pg/upgrade/YYYY.data.acq_search_run_immediately_settings.sql [new file with mode: 0644]

index 4f4221e..0858c8c 100644 (file)
     <div class="col-lg-2">
       <button class="form-control btn btn-success" (click)="submitSearch()" type="submit" i18n>Search</button>
     </div>
-    <div class="col-lg-7"></div>
+    <div class="col-lg-5"></div>
+    <div class="col-lg-2">
+      <input class="form-check-input" type="checkbox" id="retrieve-immediately"
+             (change)="saveRunImmediately()"
+             [ngModelOptions]="{standalone: true}" [(ngModel)]="runImmediately"/>
+      <label for="retrieve-immediately" class="form-check-label" i18n>Retrieve Results Immediately</label>
+    </div>
     <div class="col-lg-3">
       <button class="form-control btn btn-primary" (click)="saveSearchAsDefault()" type="button" i18n>Set As Default {{searchTypeLabel}} Search</button>
     </div>
index 1a2c685..92a07f6 100644 (file)
@@ -17,6 +17,7 @@ export class AcqSearchFormComponent implements OnInit, AfterViewInit {
 
     @Input() initialSearchTerms: AcqSearchTerm[] = [];
     @Input() defaultSearchSetting = '';
+    @Input() runImmediatelySetting = '';
     @Input() searchTypeLabel = '';
 
     @Output() searchSubmitted = new EventEmitter<AcqSearch>();
@@ -30,6 +31,7 @@ export class AcqSearchFormComponent implements OnInit, AfterViewInit {
     validSearchTypes = ['lineitems', 'purchaseorders', 'invoices', 'selectionlists'];
     defaultSearchType = 'lineitems';
     searchConjunction = 'all';
+    runImmediately = false;
 
     searchTerms: AcqSearchTerm[] = [];
 
@@ -44,58 +46,66 @@ export class AcqSearchFormComponent implements OnInit, AfterViewInit {
     ngOnInit() {
         const self = this;
 
-        this.hints.forEach(
-            function(hint) {
-                const o = {};
-                o['__label'] = self.idl.classes[hint].label;
-                o['__fields'] = [];
-                self.idl.classes[hint].fields.forEach(
-                    function(field) {
-                        if (!field.virtual) {
-                            o['__fields'].push(field.name);
-                            o[field.name] = {
-                                label: field.label,
-                                datatype: field.datatype
-                            };
-                            self.searchTermDatatypes[hint + ':' + field.name] = field.datatype;
-                            if (field.datatype === 'link') {
-                                self.searchFieldLinkedClasses[hint + ':' + field.name] = field.class;
+        this.store.getItem(this.runImmediatelySetting).then(val => {
+            this.runImmediately = val
+
+            this.hints.forEach(
+                function(hint) {
+                    const o = {};
+                    o['__label'] = self.idl.classes[hint].label;
+                    o['__fields'] = [];
+                    self.idl.classes[hint].fields.forEach(
+                        function(field) {
+                            if (!field.virtual) {
+                                o['__fields'].push(field.name);
+                                o[field.name] = {
+                                    label: field.label,
+                                    datatype: field.datatype
+                                };
+                                self.searchTermDatatypes[hint + ':' + field.name] = field.datatype;
+                                if (field.datatype === 'link') {
+                                    self.searchFieldLinkedClasses[hint + ':' + field.name] = field.class;
+                                }
                             }
                         }
+                    );
+                    self.availableSearchFields[hint] = o;
+                }
+            );
+
+            this.hints.push('acqlia');
+            this.availableSearchFields['acqlia'] = {'__label': this.idl.classes.acqlia.label, '__fields': []};
+            this.pcrud.retrieveAll('acqliad', {'order_by': {'acqliad': 'id'}})
+            .subscribe(liad => {
+                this.availableSearchFields['acqlia']['__fields'].push('' + liad.id());
+                this.availableSearchFields['acqlia'][liad.id()] = {
+                    label: liad.description(),
+                    datatype: 'text'
+                };
+                this.searchTermDatatypes['acqlia:' + liad.id()] = 'text';
+            });
+
+            if (this.initialSearchTerms.length > 0) {
+                this.searchTerms = JSON.parse(JSON.stringify(this.initialSearchTerms)); // deep copy
+                this.submitSearch(); // if we've been passed an initial search, e.g., via a URL, assume
+                                     // we want the results immediately regardless of the workstation
+                                     // setting
+            } else {
+                this.store.getItem(this.defaultSearchSetting).then(
+                    defaultSearch => {
+                        if (defaultSearch) {
+                            this.searchTerms = JSON.parse(JSON.stringify(defaultSearch.terms));
+                            this.searchConjunction = defaultSearch.conjunction;
+                        } else {
+                            this.addSearchTerm();
+                        }
+                        if (this.runImmediately) {
+                            this.submitSearch();
+                        }
                     }
                 );
-                self.availableSearchFields[hint] = o;
             }
-        );
-
-        this.hints.push('acqlia');
-        this.availableSearchFields['acqlia'] = {'__label': this.idl.classes.acqlia.label, '__fields': []};
-        this.pcrud.retrieveAll('acqliad', {'order_by': {'acqliad': 'id'}})
-        .subscribe(liad => {
-            this.availableSearchFields['acqlia']['__fields'].push('' + liad.id());
-            this.availableSearchFields['acqlia'][liad.id()] = {
-                label: liad.description(),
-                datatype: 'text'
-            };
-            this.searchTermDatatypes['acqlia:' + liad.id()] = 'text';
         });
-
-        if (this.initialSearchTerms.length > 0) {
-            this.searchTerms = JSON.parse(JSON.stringify(this.initialSearchTerms)); // deep copy
-            this.submitSearch();
-        } else {
-            this.store.getItem(this.defaultSearchSetting).then(
-                defaultSearch => {
-                    if (defaultSearch) {
-                        this.searchTerms = JSON.parse(JSON.stringify(defaultSearch.terms));
-                        this.searchConjunction = defaultSearch.conjunction;
-                        this.submitSearch();
-                    } else {
-                        this.addSearchTerm();
-                    }
-                }
-            );
-        }
     }
 
     ngAfterViewInit() {}
@@ -141,9 +151,13 @@ export class AcqSearchFormComponent implements OnInit, AfterViewInit {
     }
 
     submitSearch() {
-        this.searchSubmitted.emit({
-            terms: this.searchTerms,
-            conjunction: this.searchConjunction
+        // tossing setTimeout here to ensure that the
+        // grid data source is fully initialized
+        setTimeout(() => {
+            this.searchSubmitted.emit({
+                terms: this.searchTerms,
+                conjunction: this.searchConjunction
+            });
         });
     }
 
@@ -153,4 +167,7 @@ export class AcqSearchFormComponent implements OnInit, AfterViewInit {
             conjunction: this.searchConjunction
         });
     }
+    saveRunImmediately() {
+        return this.store.setItem(this.runImmediatelySetting, this.runImmediately);
+    }
 }
index c3847e2..8e9364e 100644 (file)
@@ -1,4 +1,5 @@
 import {Injectable} from '@angular/core';
+import {empty} from 'rxjs';
 import {NetService} from '@eg/core/net.service';
 import {AuthService} from '@eg/core/auth.service';
 import {GridDataSource} from '@eg/share/grid/grid';
@@ -91,6 +92,7 @@ export class AcqSearchService {
     _terms: AcqSearchTerm[] = [];
     _conjunction = 'all';
     attrDefs: {[code: string]: IdlObject};
+    firstRun = true;
 
     constructor(
         private net: NetService,
@@ -98,6 +100,7 @@ export class AcqSearchService {
         private pcrud: PcrudService
     ) {
         this.attrDefs = {};
+        this.firstRun = true;
     }
 
     fetchAttrDefs(): Promise<void> {
@@ -119,6 +122,7 @@ export class AcqSearchService {
     setSearch(search: AcqSearch) {
         this._terms = search.terms;
         this._conjunction = search.conjunction;
+        this.firstRun = false;
     }
 
     generateAcqSearch(searchType, filters): any {
@@ -214,6 +218,15 @@ export class AcqSearchService {
         this.fetchAttrDefs().then(() => {
             gridSource.getRows = (pager: Pager) => {
 
+                // don't do a search the very first time we
+                // get invoked, which is during initialization; we'll
+                // let components higher up the change decide whether
+                // to submit a search
+                if (this.firstRun) {
+                    this.firstRun = false;
+                    return empty();
+                }
+
                 const currentSearch = this.generateAcqSearch(searchType, gridSource.filters);
 
                 const opts = { ...searchOptions[searchType] };
index ee5dc0e..e5823a4 100644 (file)
@@ -1,5 +1,6 @@
 <eg-acq-search-form (searchSubmitted)="doSearch($event)" [initialSearchTerms]="initialSearchTerms"
-  i18n-searchTypeLabel searchTypeLabel="Invoice" defaultSearchSetting="eg.acq.search.default.invoices"></eg-acq-search-form>
+  i18n-searchTypeLabel searchTypeLabel="Invoice" runImmediatelySetting="eg.acq.search.invoices.run_immediately"
+  defaultSearchSetting="eg.acq.search.default.invoices"></eg-acq-search-form>
 
 <ng-template #inv_identTmpl let-invoice="row">
   <a href="/eg/staff/acq/legacy/invoice/view/{{invoice.id()}}"
index a4c90ad..d1ef61d 100644 (file)
@@ -1,5 +1,6 @@
 <eg-acq-search-form (searchSubmitted)="doSearch($event)" [initialSearchTerms]="initialSearchTerms"
-  i18n-searchTypeLabel searchTypeLabel="Line Item" defaultSearchSetting="eg.acq.search.default.lineitems"></eg-acq-search-form>
+  i18n-searchTypeLabel searchTypeLabel="Line Item" runImmediatelySetting="eg.acq.search.lineitems.run_immediately"
+  defaultSearchSetting="eg.acq.search.default.lineitems"></eg-acq-search-form>
 
 <ng-template #idTmpl let-lineitem="row">
   <a *ngIf="lineitem.purchase_order()" href="/eg/staff/acq/legacy/po/view/{{lineitem.purchase_order()}}?focus_li={{lineitem.id()}}"
index 9650811..9994ec2 100644 (file)
@@ -1,5 +1,6 @@
 <eg-acq-search-form (searchSubmitted)="doSearch($event)" [initialSearchTerms]="initialSearchTerms"
-  i18n-searchTypeLabel searchTypeLabel="Selection List" defaultSearchSetting="eg.acq.search.default.selectionlists"></eg-acq-search-form>
+  i18n-searchTypeLabel searchTypeLabel="Selection List" runImmediatelySetting="eg.acq.search.selectionlists.run_immediately"
+  defaultSearchSetting="eg.acq.search.default.selectionlists"></eg-acq-search-form>
 
 <eg-string #createSelectionListString i18n-text text="Selection List Created">
 </eg-string>
index b3c2528..14c6d96 100644 (file)
@@ -1,5 +1,6 @@
 <eg-acq-search-form (searchSubmitted)="doSearch($event)" [initialSearchTerms]="initialSearchTerms"
-  i18n-searchTypeLabel searchTypeLabel="Purchase Order" defaultSearchSetting="eg.acq.search.default.purchaseorders"></eg-acq-search-form>
+  i18n-searchTypeLabel searchTypeLabel="Purchase Order" runImmediatelySetting="eg.acq.search.purchaseorders.run_immediately"
+   defaultSearchSetting="eg.acq.search.default.purchaseorders"></eg-acq-search-form>
 
 <ng-template #nameTmpl let-purchaseorder="row">
   <a href="/eg/staff/acq/legacy/po/view/{{purchaseorder.id()}}"
index 1825be1..94386c5 100644 (file)
@@ -20335,3 +20335,31 @@ VALUES (
     'Acquisitions Default Search: Selection Lists',
     'cwst', 'label')
 );
+
+INSERT INTO config.workstation_setting_type
+    (name, grp, datatype, label)
+VALUES (
+    'eg.acq.search.lineitems.run_immediately', 'gui', 'bool',
+    oils_i18n_gettext(
+    'eg.acq.search.lineitems.run_immediately',
+    'Acquisitions Search: Immediately Search Lineitems',
+    'cwst', 'label')
+), (
+    'eg.acq.search.purchaseorders.run_immediately', 'gui', 'bool',
+    oils_i18n_gettext(
+    'eg.acq.search.purchaseorders.run_immediately',
+    'Acquisitions Search: Immediately Search Purchase Orders',
+    'cwst', 'label')
+), (
+    'eg.acq.search.invoices.run_immediately', 'gui', 'bool',
+    oils_i18n_gettext(
+    'eg.acq.search.invoices.run_immediately',
+    'Acquisitions Search: Immediately Search Invoices',
+    'cwst', 'label')
+), (
+    'eg.acq.search.selectionlists.run_immediately', 'gui', 'bool',
+    oils_i18n_gettext(
+    'eg.acq.search.selectionlists.run_immediately',
+    'Acquisitions Search: Immediately Search Selection Lists',
+    'cwst', 'label')
+);
diff --git a/Open-ILS/src/sql/Pg/upgrade/YYYY.data.acq_search_run_immediately_settings.sql b/Open-ILS/src/sql/Pg/upgrade/YYYY.data.acq_search_run_immediately_settings.sql
new file mode 100644 (file)
index 0000000..3e6b9b2
--- /dev/null
@@ -0,0 +1,33 @@
+BEGIN;
+
+-- SELECT evergreen.upgrade_deps_block_check('XXXX', :eg_version);
+
+INSERT INTO config.workstation_setting_type
+    (name, grp, datatype, label)
+VALUES (
+    'eg.acq.search.lineitems.run_immediately', 'gui', 'bool',
+    oils_i18n_gettext(
+    'eg.acq.search.lineitems.run_immediately',
+    'Acquisitions Search: Immediately Search Lineitems',
+    'cwst', 'label')
+), (
+    'eg.acq.search.purchaseorders.run_immediately', 'gui', 'bool',
+    oils_i18n_gettext(
+    'eg.acq.search.purchaseorders.run_immediately',
+    'Acquisitions Search: Immediately Search Purchase Orders',
+    'cwst', 'label')
+), (
+    'eg.acq.search.invoices.run_immediately', 'gui', 'bool',
+    oils_i18n_gettext(
+    'eg.acq.search.invoices.run_immediately',
+    'Acquisitions Search: Immediately Search Invoices',
+    'cwst', 'label')
+), (
+    'eg.acq.search.selectionlists.run_immediately', 'gui', 'bool',
+    oils_i18n_gettext(
+    'eg.acq.search.selectionlists.run_immediately',
+    'Acquisitions Search: Immediately Search Selection Lists',
+    'cwst', 'label')
+);
+
+COMMIT;