LP1821382 Make items bookable (part 2)
[evergreen-equinox.git] / Open-ILS / src / eg2 / src / app / staff / share / admin-page / admin-page.component.ts
index 03ba326..955e95a 100644 (file)
@@ -1,4 +1,5 @@
 import {Component, Input, OnInit, TemplateRef, ViewChild} from '@angular/core';
+import {ActivatedRoute} from '@angular/router';
 import {IdlService, IdlObject} from '@eg/core/idl.service';
 import {GridDataSource} from '@eg/share/grid/grid';
 import {GridComponent} from '@eg/share/grid/grid.component';
@@ -69,6 +70,8 @@ export class AdminPageComponent implements OnInit {
     @ViewChild('editDialog') editDialog: FmRecordEditorComponent;
     @ViewChild('successString') successString: StringComponent;
     @ViewChild('createString') createString: StringComponent;
+    @ViewChild('createErrString') createErrString: StringComponent;
+    @ViewChild('updateFailedString') updateFailedString: StringComponent;
     @ViewChild('translator') translator: TranslateComponent;
 
     idlClassDef: any;
@@ -88,7 +91,12 @@ export class AdminPageComponent implements OnInit {
     viewPerms: string;
     canCreate: boolean;
 
+    // Filters may be passed via URL query param.
+    // They are used to augment the grid data search query.
+    gridFilters: {[key: string]: string | number};
+
     constructor(
+        private route: ActivatedRoute,
         private idl: IdlService,
         private org: OrgService,
         private auth: AuthService,
@@ -99,7 +107,7 @@ export class AdminPageComponent implements OnInit {
         this.translatableFields = [];
     }
 
-    applyOrgValues() {
+    applyOrgValues(orgId?: number) {
 
         if (this.disableOrgFilter) {
             this.orgField = null;
@@ -119,7 +127,7 @@ export class AdminPageComponent implements OnInit {
 
         if (this.orgField) {
             this.orgFieldLabel = this.idlClassDef.field_map[this.orgField].label;
-            this.contextOrg = this.org.root();
+            this.contextOrg = this.org.get(orgId) || this.org.root();
         }
     }
 
@@ -137,6 +145,16 @@ export class AdminPageComponent implements OnInit {
                 this.idlClassDef.table;
         }
 
+        // gridFilters are a JSON encoded string
+        const filters = this.route.snapshot.queryParamMap.get('gridFilters');
+        if (filters) {
+            try {
+                this.gridFilters = JSON.parse(filters);
+            } catch (E) {
+                console.error('Invalid grid filters provided: ', filters)
+            }
+        }
+
         // Limit the view org selector to orgs where the user has
         // permacrud-encoded view permissions.
         const pc = this.idlClassDef.permacrud;
@@ -144,8 +162,9 @@ export class AdminPageComponent implements OnInit {
             this.viewPerms = pc.retrieve.perms;
         }
 
+        const contextOrg = this.route.snapshot.queryParamMap.get('contextOrg');
         this.checkCreatePerms();
-        this.applyOrgValues();
+        this.applyOrgValues(Number(contextOrg));
 
         // If the caller provides not data source, create a generic one.
         if (!this.dataSource) {
@@ -161,23 +180,33 @@ export class AdminPageComponent implements OnInit {
 
             // Edit each IDL thing one at a time
             const editOneThing = (thing: IdlObject) => {
-                if (!thing) return;
+                if (!thing) { return; }
 
                 this.showEditDialog(thing).then(
                     () => editOneThing(idlThings.shift()));
-            }
+            };
 
-            editOneThing(idlThings.shift()); };
+            editOneThing(idlThings.shift());
+        };
 
         this.createNew = () => {
             this.editDialog.mode = 'create';
+            // We reuse the same editor for all actions.  Be sure
+            // create action does not try to modify an existing record.
+            this.editDialog.recId = null;
+            this.editDialog.record = null;
             this.editDialog.open({size: this.dialogSize}).then(
                 ok => {
                     this.createString.current()
                         .then(str => this.toast.success(str));
                     this.grid.reload();
                 },
-                err => {}
+                rejection => {
+                    if (!rejection.dismissed) {
+                        this.createErrString.current()
+                            .then(str => this.toast.danger(str));
+                    }
+                }
             );
         };
 
@@ -276,6 +305,14 @@ export class AdminPageComponent implements OnInit {
                 order_by: orderBy
             };
 
+            if (!this.contextOrg && !this.gridFilters) {
+                // No org filter -- fetch all rows
+                return this.pcrud.retrieveAll(
+                    this.idlClass, searchOps, {fleshSelectors: true});
+            }
+
+            const search: any = {};
+
             if (this.contextOrg) {
                 // Filter rows by those linking to the context org and
                 // optionally ancestor and descendant org units.
@@ -292,13 +329,18 @@ export class AdminPageComponent implements OnInit {
                         this.org.descendants(this.contextOrg, true));
                 }
 
-                const search = {};
                 search[this.orgField] = orgs;
-                return this.pcrud.search(this.idlClass, search, searchOps);
             }
 
-            // No org filter -- fetch all rows
-            return this.pcrud.retrieveAll(this.idlClass, searchOps);
+            if (this.gridFilters) {
+                // Lay the URL grid filters over our search object.
+                Object.keys(this.gridFilters).forEach(key => {
+                    search[key] = this.gridFilters[key];
+                });
+            }
+
+            return this.pcrud.search(
+                this.idlClass, search, searchOps, {fleshSelectors: true});
         };
     }
 
@@ -320,7 +362,12 @@ export class AdminPageComponent implements OnInit {
                     .then(str => this.toast.success(str));
                 this.grid.reload();
             },
-            err => {}
+            rejection => {
+                if (!rejection.dismissed) {
+                    this.updateFailedString.current()
+                        .then(str => this.toast.danger(str));
+                }
+            }
         );
     }