LP1806087 Catalog holds display WIP
authorBill Erickson <berickxx@gmail.com>
Tue, 19 Feb 2019 16:04:15 +0000 (11:04 -0500)
committerBill Erickson <berickxx@gmail.com>
Tue, 19 Feb 2019 16:04:15 +0000 (11:04 -0500)
Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/eg2/src/app/staff/catalog/catalog.module.ts
Open-ILS/src/eg2/src/app/staff/catalog/record/holds.component.html [deleted file]
Open-ILS/src/eg2/src/app/staff/catalog/record/holds.component.ts [deleted file]
Open-ILS/src/eg2/src/app/staff/catalog/record/record.component.html
Open-ILS/src/eg2/src/app/staff/catalog/record/record.component.ts
Open-ILS/src/eg2/src/app/staff/catalog/search-form.component.ts
Open-ILS/src/eg2/src/app/staff/share/holds-grid/holds-grid.component.html [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/share/holds-grid/holds-grid.component.ts [new file with mode: 0644]
Open-ILS/src/eg2/src/app/staff/share/holds-grid/holds-grid.module.ts [new file with mode: 0644]

index cc30f6c..d159437 100644 (file)
@@ -2,6 +2,7 @@ import {NgModule} from '@angular/core';
 import {StaffCommonModule} from '@eg/staff/common.module';
 import {CatalogCommonModule} from '@eg/share/catalog/catalog-common.module';
 import {CatalogRoutingModule} from './routing.module';
+import {HoldsGridModule} from '@eg/staff/share/holds-grid/holds-grid.module';
 import {CatalogComponent} from './catalog.component';
 import {SearchFormComponent} from './search-form.component';
 import {ResultsComponent} from './result/results.component';
@@ -21,7 +22,6 @@ import {PartsComponent} from './record/parts.component';
 import {PartMergeDialogComponent} from './record/part-merge-dialog.component';
 import {BrowseComponent} from './browse.component';
 import {BrowseResultsComponent} from './browse/results.component';
-import {HoldsComponent} from './record/holds.component';
 
 @NgModule({
   declarations: [
@@ -41,12 +41,12 @@ import {HoldsComponent} from './record/holds.component';
     PartMergeDialogComponent,
     BrowseComponent,
     BrowseResultsComponent,
-    HoldsComponent
   ],
   imports: [
     StaffCommonModule,
     CatalogCommonModule,
-    CatalogRoutingModule
+    CatalogRoutingModule,
+    HoldsGridModule
   ],
   providers: [
     StaffCatalogService,
diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/record/holds.component.html b/Open-ILS/src/eg2/src/app/staff/catalog/record/holds.component.html
deleted file mode 100644 (file)
index 59867a0..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-
-<eg-progress-dialog #progressDialog>
-</eg-progress-dialog>
-
-<div class='eg-holds w-100 mt-3'>
-
-  <div class="row">
-    <div class="col-lg-4">
-      <div class="input-group">
-        <div class="input-group-prepend">
-          <div class="input-group-text" i18n>Pickup Library</div>
-        </div>
-        <eg-org-select [initialOrg]="pickupLib" (onChange)="pickupLibChanged($event)">
-        </eg-org-select>
-      </div>
-    </div>
-  </div>
-
-  <eg-grid #holdsGrid [dataSource]="gridDataSource" [sortable]="true"
-    [multiSortable]="true" persistKey="cat.catalog.wide_holds" 
-    >
-
-    <!--
-    <eg-grid-menu-item handler="detail_view" 
-      i18n-label label="Detail View"></eg-grid-menu-item>
-
-    <eg-grid-action handler="grid_actions.show_recent_circs_wide" group="Item"
-      i18n-label label="Show Last Few Circulations"></eg-grid-action>
-    <eg-grid-action handler="grid_actions.show_patrons_wide" group="Patron"
-      i18n-label label="Retrieve Patron"></eg-grid-action>
-    <eg-grid-action group="Hold" handler="grid_actions.set_copy_quality_wide"
-      i18n-label label="Set Desired Item Quality"></eg-grid-action>
-    <eg-grid-action group="Hold" handler="grid_actions.edit_pickup_lib_wide"
-      i18n-label label="Edit Pickup Library"></eg-grid-action>
-    <eg-grid-action group="Hold" handler="grid_actions.edit_notify_prefs_wide"
-      i18n-label label="Edit Notification Settings"></eg-grid-action>
-    <eg-grid-action group="Hold" handler="grid_actions.edit_dates_wide"
-      i18n-label label="Edit Hold Dates"></eg-grid-action>
-    <eg-grid-action handler="grid_actions.activate_wide" group="Hold"
-      i18n-label label="Activate"></eg-grid-action>
-    <eg-grid-action handler="grid_actions.suspend_wide" group="Hold"
-      i18n-label label="Suspend"></eg-grid-action>
-    <eg-grid-action handler="grid_actions.set_top_of_queue_wide" group="Hold"
-      i18n-label label="Set Top of Queue"></eg-grid-action>
-    <eg-grid-action handler="grid_actions.clear_top_of_queue_wide" group="Hold"
-      i18n-label label="Un-Set Top of Queue"></eg-grid-action>
-    <eg-grid-action handler="grid_actions.transfer_to_marked_title_wide" group="Hold"
-      i18n-label label="Transfer To Marked Title"></eg-grid-action>
-    <eg-grid-action handler="grid_actions.mark_damaged_wide" group="Item"
-      i18n-label label="Mark Item Damaged"></eg-grid-action>
-    <eg-grid-action handler="grid_actions.mark_missing_wide" group="Item"
-      i18n-label label="Mark Item Missing"></eg-grid-action>
-    <eg-grid-action handler="grid_actions.retarget_wide" group="Hold"
-      i18n-label label="Find Another Target"></eg-grid-action>
-    <eg-grid-action handler="grid_actions.cancel_wide_hold" group="Hold"
-      i18n-label label="Cancel Hold"></eg-grid-action>
-      -->
-
-    <eg-grid-column i18n-label label="Hold ID" path='id' [index]="true">
-    </eg-grid-column>
-
-    <ng-template #barcodeTmpl let-hold="row">
-      <a href="/eg/staff/cat/item/{{cp_id}}/summary">
-        {{cp_barcode}}
-      </a>
-    </ng-template>
-    <eg-grid-column i18n-label label="Current Item" name='cp_barcode'
-      [cellTemplate]="barcodeTmpl">
-    </eg-grid-column>
-
-    <eg-grid-column i18n-label label="Patron Barcode" 
-        path='ucard_barcode' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Patron alias" path="usr_alias"></eg-grid-column>
-    <eg-grid-column i18n-label label="Request Date" 
-        path='request_time' datatype="timestamp"></eg-grid-column>
-    <eg-grid-column i18n-label label="Capture Date" path='capture_time' 
-        datatype="timestamp"></eg-grid-column>
-    <eg-grid-column i18n-label label="Available Date" path='shelf_time' 
-        datatype="timestamp"></eg-grid-column>
-    <eg-grid-column i18n-label label="Hold Type" path='hold_type'></eg-grid-column>
-    <eg-grid-column i18n-label label="Pickup Library" path='pl_shortname'></eg-grid-column>
-
-    <ng-template #titleTmpl let-hold="row">
-      <a class="no-href" routerLink="/staff/catalog/record/{{hold.record_id}}">
-        {{hold.title}}
-      </a>
-    </ng-template>
-    <eg-grid-column i18n-label label="Title" [hidden]="true"
-        name='title' [cellTemplate]="titleTmpl"></eg-grid-column>
-    <eg-grid-column i18n-label label="Author" path='author'
-        [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Potential Items" path='potentials'>
-    </eg-grid-column>
-    <eg-grid-column i18n-label label="Status" path='status_string'>
-    </eg-grid-column>
-    <eg-grid-column i18n-label label="Queue Position" 
-        path='relative_queue_position' [hidden]="true"></eg-grid-column>
-    <eg-grid-column path='usr_id' i18n-label label="User ID" [hidden]="true"></eg-grid-column>
-    <eg-grid-column path='usr_usrname' i18n-label label="Username" [hidden]="true"></eg-grid-column>
-
-    <eg-grid-column path='usr_first_given_name' i18n-label label="First Name" [hidden]="true"></eg-grid-column>
-    <eg-grid-column path='usr_family_name' i18n-label label="Last Name" [hidden]="true"></eg-grid-column>
-    <eg-grid-column path='rusr_id' i18n-label label="Requestor ID" [hidden]="true"></eg-grid-column>
-    <eg-grid-column path='rusr_usrname' i18n-label label="Requestor Username" [hidden]="true"></eg-grid-column>
-
-   <eg-grid-column i18n-label label="Item Status" path="cs_name" [hidden]="true"></eg-grid-column>
-
-    <eg-grid-column path='acnp_label' i18n-label label="CN Prefix" [hidden]="true"></eg-grid-column>
-    <eg-grid-column path='acns_label' i18n-label label="CN Suffix" [hidden]="true"></eg-grid-column>
-    <eg-grid-column path='mvr.*' parent-idl-class="mvr" [hidden]="true"></eg-grid-column>
-
-    <eg-grid-column i18n-label label="Copy Status" path="cs_name" [hidden]="true"></eg-grid-column>
-
-    <eg-grid-column i18n-label label="Fulfillment Date/Time" path='fulfillment_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Checkin Time" path='checkin_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Return Time" path='return_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Last Targeting Date/Time" path='prev_check_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Expire Time" path='expire_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Hold Cancel Date/Time" path='cancel_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Cancelation note" path='cancel_note' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Hold Target" path='target' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Current Copy" path='current_copy' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Fulfilling Staff" path='fulfillment_staff' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Fulfilling Library" path='fulfillment_lib' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Requesting Library" path='request_lib' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Requesting User" path='requestor' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="User" path='usr' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Selection Library" path='selection_ou' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Item Selection Depth" path='selection_depth' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Holdable Formats (for M-type hold)" path='holdable_formats' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Notifications Phone Number" path='phone_notify' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Notifications SMS Number" path='sms_notify' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Notify by Email?" path='email_notify' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="SMS Carrier" path='sms_carrier' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Currently Frozen" path='frozen' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Activation Date" path='thaw_date' datatype="timestamp" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Top of Queue" path='cut_in_line' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Is Mint Condition" path='mint_condition' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Shelf Expire Time" path='shelf_expire_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Current Shelf Library" path='current_shelf_lib' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Behind Desk" path='behind_desk' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Status" path='hold_status' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Clearable" path='clear_me' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Is Staff-placed Hold" path='is_staff_hold' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Cancelation Cause ID" path='cc_id' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Cancelation Cause" path='cc_label' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Pickup Library" path='pl_shortname'></eg-grid-column>
-    <eg-grid-column i18n-label label="Pickup Library Name" path='pl_name' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Pickup Library Email" path='pl_email' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Pickup Library Phone" path='pl_phone' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Pickup Library Opac Visible" path='pl_opac_visible' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Transit ID" path='tr_id' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Transit Send Time" path='tr_source_send_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Transit Receive Time" path='tr_dest_recv_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Transit Copy" path='tr_target_copy' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Transit Source" path='tr_source' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Transit Destination" path='tr_dest' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Transit Copy Status" path='tr_copy_status' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Transit Hold" path='tr_hold' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Transit Cancel Time" path='tr_cancel_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Hold Note Count" path='note_count' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="User Display Name" path='usr_display_name' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Requestor Username" path='rusr_usrname' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy ID" path='cp_id' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Number on Volume" path='cp_copy_number' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Fine Level" path='cp_fine_level' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Can Circulate" path='cp_circulate' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Deposit Amount" path='cp_deposit_amount' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Is Deposit Required" path='cp_deposit' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Is Reference" path='cp_ref' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Is Holdable" path='cp_holdable' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Price" path='cp_price' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Barcode" path='cp_barcode' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Circulation Modifier" path='cp_circ_modifier' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Circulate as MARC Type" path='cp_circ_as_type' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Precat Dummy Title" path='cp_dummy_title' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Precat Dummy Author" path='cp_dummy_author' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Alert Message (deprecated)" path='cp_alert_message' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy OPAC Visible" path='cp_opac_visible' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Deleted" path='cp_deleted' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Floating Group" path='cp_floating' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Precat Dummy ISBN" path='cp_dummy_isbn' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Status Change Time" path='cp_status_change_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Active Date" path='cp_active_date' datatype="timestamp" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Is Mint Condition" path='cp_mint_condition' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Cost" path='cp_cost' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Status" path='cs_name' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Status Is Holdable" path='cs_holdable' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Status Is OPAC Visible" path='cs_opac_visible' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Status Is Copy-Active" path='cs_copy_active' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Status Is Deleted" path='cs_restrict_copy_delete' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Status Is Available" path='cs_is_available' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Issuance i18n-label label" path='issuance_label' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Call Number ID" path='cn_id' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="CN i18n-label label" path='cn_label' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="CN i18n-label label Class" path='cn_label_class' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="CN Sort Key" path='cn_label_sortkey' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Part ID" path='p_id' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Part i18n-label label" path='p_label' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Part Sort Key" path='p_label_sortkey' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Part Is Deleted" path='p_deleted' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="CN Full i18n-label label" path='cn_full_label' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Record ID" path='record_id' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Location ID" path='acpl_id' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Location" path='acpl_name' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Location Holdable" path='acpl_holdable' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Location Hold-Verify" path='acpl_hold_verify' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Location OPAC Visible" path='acpl_opac_visible' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Location Can Circulate" path='acpl_circulate' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Location Prefix" path='acpl_label_prefix' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Location Suffix" path='acpl_label_suffix' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Location Checkin Alert" path='acpl_checkin_alert' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Location Is Deleted" path='acpl_deleted' datatype="bool" [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Location URL" path='acpl_url' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Copy Location Order" path='copy_location_order_position' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Default Estimated Wait Time" path='default_estimated_wait' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Minimum Estimated Wait Time" path='min_estimated_wait' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Peer Hold Count" path='other_holds' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Total Wait Time" path='total_wait_time' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Notify Count" path='notification_count' [hidden]="true"></eg-grid-column>
-    <eg-grid-column i18n-label label="Last Notify Time" path='last_notification_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
-
-  </eg-grid>
-
-</div>
-
-
diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/record/holds.component.ts b/Open-ILS/src/eg2/src/app/staff/catalog/record/holds.component.ts
deleted file mode 100644 (file)
index 5c281b6..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-import {Component, OnInit, Input, ViewChild} from '@angular/core';
-import {Observable, Observer, of} from 'rxjs';
-import {map, filter} from 'rxjs/operators';
-import {IdlObject} from '@eg/core/idl.service';
-import {NetService} from '@eg/core/net.service';
-import {OrgService} from '@eg/core/org.service';
-import {AuthService} from '@eg/core/auth.service';
-import {StaffCatalogService} from '../catalog.service';
-import {Pager} from '@eg/share/util/pager';
-import {GridDataSource} from '@eg/share/grid/grid';
-import {GridComponent} from '@eg/share/grid/grid.component';
-import {ProgressDialogComponent} from '@eg/share/dialog/progress.component';
-
-@Component({
-  selector: 'eg-catalog-holds',
-  templateUrl: 'holds.component.html'
-})
-export class HoldsComponent implements OnInit {
-
-    recId: number;
-    initDone = false;
-    gridDataSource: GridDataSource;
-    pickupLib: IdlObject;
-    holdsCount: number;
-    @ViewChild('holdsGrid') private holdsGrid: GridComponent;
-    @ViewChild('progressDialog') private progressDialog: ProgressDialogComponent;
-
-    @Input() set recordId(id: number) {
-        this.recId = id;
-        // Only force new data collection when recordId()
-        // is invoked after ngInit() has already run.
-        if (this.initDone) {
-            this.holdsGrid.reload();
-        }
-    }
-
-    constructor(
-        private net: NetService,
-        private org: OrgService,
-        private auth: AuthService,
-        private staffCat: StaffCatalogService,
-    ) {
-        this.gridDataSource = new GridDataSource();
-    }
-
-    ngOnInit() {
-        this.initDone = true;
-        this.pickupLib = this.staffCat.searchContext.searchOrg;
-
-        this.gridDataSource.getRows = (pager: Pager, sort: any[]) => {
-            // sorting not currently supported
-            return this.fetchHolds(pager, sort);
-        };
-    }
-
-    pickupLibChanged(org: IdlObject) {
-        this.pickupLib = org;
-        this.holdsGrid.reload();
-    }
-
-    fetchHolds(pager: Pager, sort: any[]): Observable<any> {
-        if (!this.recId) { return of([]); }
-
-        const orgs = this.org.descendants(this.pickupLib, true);
-
-        const restrictions = {
-            is_staff_request: true,
-            fulfillment_time: null,
-            cancel_time: null,
-            record_id: this.recId,
-            pickup_lib: orgs
-        };
-
-        const orderBy: any = [];
-        sort.forEach(obj => {
-            const subObj: any = {};
-            subObj[obj.name] = {dir: obj.dir, nulls: 'last'};
-            orderBy.push(subObj);
-        });
-
-        let observer: Observer<any>;
-        const observable = new Observable(obs => observer = obs);
-
-        this.progressDialog.open();
-        this.progressDialog.update({value: 0, max: 1});
-        let first = true;
-        let loadCount = 0;
-        this.net.request(
-            'open-ils.circ',
-            'open-ils.circ.hold.wide_hash.stream',
-            this.auth.token(), restrictions, orderBy, pager.limit, pager.offset
-        ).subscribe(
-            holdData => {
-
-                if (first) { // First response is the hold count.
-                    this.holdsCount = Number(holdData);
-                    first = false;
-
-                } else { // Subsequent responses are hold data blobs
-
-                    this.progressDialog.update(
-                        {value: ++loadCount, max: this.holdsCount});
-
-                    observer.next(holdData);
-                }
-            },
-            err => {
-                this.progressDialog.close();
-                observer.error(err);
-            },
-            ()  => {
-                this.progressDialog.close();
-                observer.complete();
-            }
-        );
-
-        return observable;
-    }
-}
-
-
index 5f3bf73..6868944 100644 (file)
@@ -42,7 +42,9 @@
       </ngb-tab>
       <ngb-tab title="View Holds" i18n-title id="holds">
         <ng-template ngbTabContent>
-          <eg-catalog-holds [recordId]="recordId"></eg-catalog-holds>
+          <eg-holds-grid [recordId]="recordId" 
+            [defaultSort]="[{name:'request_time',dir:'asc'}]"
+            [initialPickupLib]="currentSearchOrg()"></eg-holds-grid>
         </ng-template>
       </ngb-tab>
       <ngb-tab title="Monograph Parts" i18n-title id="monoparts">
index 6c935ff..a0ee5c1 100644 (file)
@@ -127,6 +127,13 @@ export class RecordComponent implements OnInit {
             this.bib.fleshBibUsers([summary.record]);
         });
     }
+
+    currentSearchOrg(): IdlObject {
+        if (this.staffCat && this.staffCat.searchContext) {
+            return this.staffCat.searchContext.searchOrg;
+        }
+        return null;
+    }
 }
 
 
index ed35231..785e69e 100644 (file)
@@ -100,9 +100,10 @@ export class SearchFormComponent implements OnInit, AfterViewInit {
         try {
             // TODO: sometime the selector is not available in the DOM
             // until even later (even with setTimeouts).  Need to fix this.
-            // Note the error is thrown selectRootElement().
+            // Note the error is thrown from selectRootElement(), not the
+            // call to .focus() on a null reference.
             this.renderer.selectRootElement(selector).focus();
-        } catch(E) {}
+        } catch (E) {}
     }
 
     /**
diff --git a/Open-ILS/src/eg2/src/app/staff/share/holds-grid/holds-grid.component.html b/Open-ILS/src/eg2/src/app/staff/share/holds-grid/holds-grid.component.html
new file mode 100644 (file)
index 0000000..59867a0
--- /dev/null
@@ -0,0 +1,227 @@
+
+<eg-progress-dialog #progressDialog>
+</eg-progress-dialog>
+
+<div class='eg-holds w-100 mt-3'>
+
+  <div class="row">
+    <div class="col-lg-4">
+      <div class="input-group">
+        <div class="input-group-prepend">
+          <div class="input-group-text" i18n>Pickup Library</div>
+        </div>
+        <eg-org-select [initialOrg]="pickupLib" (onChange)="pickupLibChanged($event)">
+        </eg-org-select>
+      </div>
+    </div>
+  </div>
+
+  <eg-grid #holdsGrid [dataSource]="gridDataSource" [sortable]="true"
+    [multiSortable]="true" persistKey="cat.catalog.wide_holds" 
+    >
+
+    <!--
+    <eg-grid-menu-item handler="detail_view" 
+      i18n-label label="Detail View"></eg-grid-menu-item>
+
+    <eg-grid-action handler="grid_actions.show_recent_circs_wide" group="Item"
+      i18n-label label="Show Last Few Circulations"></eg-grid-action>
+    <eg-grid-action handler="grid_actions.show_patrons_wide" group="Patron"
+      i18n-label label="Retrieve Patron"></eg-grid-action>
+    <eg-grid-action group="Hold" handler="grid_actions.set_copy_quality_wide"
+      i18n-label label="Set Desired Item Quality"></eg-grid-action>
+    <eg-grid-action group="Hold" handler="grid_actions.edit_pickup_lib_wide"
+      i18n-label label="Edit Pickup Library"></eg-grid-action>
+    <eg-grid-action group="Hold" handler="grid_actions.edit_notify_prefs_wide"
+      i18n-label label="Edit Notification Settings"></eg-grid-action>
+    <eg-grid-action group="Hold" handler="grid_actions.edit_dates_wide"
+      i18n-label label="Edit Hold Dates"></eg-grid-action>
+    <eg-grid-action handler="grid_actions.activate_wide" group="Hold"
+      i18n-label label="Activate"></eg-grid-action>
+    <eg-grid-action handler="grid_actions.suspend_wide" group="Hold"
+      i18n-label label="Suspend"></eg-grid-action>
+    <eg-grid-action handler="grid_actions.set_top_of_queue_wide" group="Hold"
+      i18n-label label="Set Top of Queue"></eg-grid-action>
+    <eg-grid-action handler="grid_actions.clear_top_of_queue_wide" group="Hold"
+      i18n-label label="Un-Set Top of Queue"></eg-grid-action>
+    <eg-grid-action handler="grid_actions.transfer_to_marked_title_wide" group="Hold"
+      i18n-label label="Transfer To Marked Title"></eg-grid-action>
+    <eg-grid-action handler="grid_actions.mark_damaged_wide" group="Item"
+      i18n-label label="Mark Item Damaged"></eg-grid-action>
+    <eg-grid-action handler="grid_actions.mark_missing_wide" group="Item"
+      i18n-label label="Mark Item Missing"></eg-grid-action>
+    <eg-grid-action handler="grid_actions.retarget_wide" group="Hold"
+      i18n-label label="Find Another Target"></eg-grid-action>
+    <eg-grid-action handler="grid_actions.cancel_wide_hold" group="Hold"
+      i18n-label label="Cancel Hold"></eg-grid-action>
+      -->
+
+    <eg-grid-column i18n-label label="Hold ID" path='id' [index]="true">
+    </eg-grid-column>
+
+    <ng-template #barcodeTmpl let-hold="row">
+      <a href="/eg/staff/cat/item/{{cp_id}}/summary">
+        {{cp_barcode}}
+      </a>
+    </ng-template>
+    <eg-grid-column i18n-label label="Current Item" name='cp_barcode'
+      [cellTemplate]="barcodeTmpl">
+    </eg-grid-column>
+
+    <eg-grid-column i18n-label label="Patron Barcode" 
+        path='ucard_barcode' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Patron alias" path="usr_alias"></eg-grid-column>
+    <eg-grid-column i18n-label label="Request Date" 
+        path='request_time' datatype="timestamp"></eg-grid-column>
+    <eg-grid-column i18n-label label="Capture Date" path='capture_time' 
+        datatype="timestamp"></eg-grid-column>
+    <eg-grid-column i18n-label label="Available Date" path='shelf_time' 
+        datatype="timestamp"></eg-grid-column>
+    <eg-grid-column i18n-label label="Hold Type" path='hold_type'></eg-grid-column>
+    <eg-grid-column i18n-label label="Pickup Library" path='pl_shortname'></eg-grid-column>
+
+    <ng-template #titleTmpl let-hold="row">
+      <a class="no-href" routerLink="/staff/catalog/record/{{hold.record_id}}">
+        {{hold.title}}
+      </a>
+    </ng-template>
+    <eg-grid-column i18n-label label="Title" [hidden]="true"
+        name='title' [cellTemplate]="titleTmpl"></eg-grid-column>
+    <eg-grid-column i18n-label label="Author" path='author'
+        [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Potential Items" path='potentials'>
+    </eg-grid-column>
+    <eg-grid-column i18n-label label="Status" path='status_string'>
+    </eg-grid-column>
+    <eg-grid-column i18n-label label="Queue Position" 
+        path='relative_queue_position' [hidden]="true"></eg-grid-column>
+    <eg-grid-column path='usr_id' i18n-label label="User ID" [hidden]="true"></eg-grid-column>
+    <eg-grid-column path='usr_usrname' i18n-label label="Username" [hidden]="true"></eg-grid-column>
+
+    <eg-grid-column path='usr_first_given_name' i18n-label label="First Name" [hidden]="true"></eg-grid-column>
+    <eg-grid-column path='usr_family_name' i18n-label label="Last Name" [hidden]="true"></eg-grid-column>
+    <eg-grid-column path='rusr_id' i18n-label label="Requestor ID" [hidden]="true"></eg-grid-column>
+    <eg-grid-column path='rusr_usrname' i18n-label label="Requestor Username" [hidden]="true"></eg-grid-column>
+
+   <eg-grid-column i18n-label label="Item Status" path="cs_name" [hidden]="true"></eg-grid-column>
+
+    <eg-grid-column path='acnp_label' i18n-label label="CN Prefix" [hidden]="true"></eg-grid-column>
+    <eg-grid-column path='acns_label' i18n-label label="CN Suffix" [hidden]="true"></eg-grid-column>
+    <eg-grid-column path='mvr.*' parent-idl-class="mvr" [hidden]="true"></eg-grid-column>
+
+    <eg-grid-column i18n-label label="Copy Status" path="cs_name" [hidden]="true"></eg-grid-column>
+
+    <eg-grid-column i18n-label label="Fulfillment Date/Time" path='fulfillment_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Checkin Time" path='checkin_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Return Time" path='return_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Last Targeting Date/Time" path='prev_check_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Expire Time" path='expire_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Hold Cancel Date/Time" path='cancel_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Cancelation note" path='cancel_note' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Hold Target" path='target' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Current Copy" path='current_copy' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Fulfilling Staff" path='fulfillment_staff' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Fulfilling Library" path='fulfillment_lib' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Requesting Library" path='request_lib' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Requesting User" path='requestor' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="User" path='usr' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Selection Library" path='selection_ou' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Item Selection Depth" path='selection_depth' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Holdable Formats (for M-type hold)" path='holdable_formats' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Notifications Phone Number" path='phone_notify' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Notifications SMS Number" path='sms_notify' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Notify by Email?" path='email_notify' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="SMS Carrier" path='sms_carrier' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Currently Frozen" path='frozen' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Activation Date" path='thaw_date' datatype="timestamp" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Top of Queue" path='cut_in_line' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Is Mint Condition" path='mint_condition' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Shelf Expire Time" path='shelf_expire_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Current Shelf Library" path='current_shelf_lib' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Behind Desk" path='behind_desk' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Status" path='hold_status' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Clearable" path='clear_me' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Is Staff-placed Hold" path='is_staff_hold' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Cancelation Cause ID" path='cc_id' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Cancelation Cause" path='cc_label' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Pickup Library" path='pl_shortname'></eg-grid-column>
+    <eg-grid-column i18n-label label="Pickup Library Name" path='pl_name' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Pickup Library Email" path='pl_email' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Pickup Library Phone" path='pl_phone' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Pickup Library Opac Visible" path='pl_opac_visible' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Transit ID" path='tr_id' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Transit Send Time" path='tr_source_send_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Transit Receive Time" path='tr_dest_recv_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Transit Copy" path='tr_target_copy' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Transit Source" path='tr_source' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Transit Destination" path='tr_dest' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Transit Copy Status" path='tr_copy_status' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Transit Hold" path='tr_hold' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Transit Cancel Time" path='tr_cancel_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Hold Note Count" path='note_count' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="User Display Name" path='usr_display_name' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Requestor Username" path='rusr_usrname' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy ID" path='cp_id' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Number on Volume" path='cp_copy_number' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Fine Level" path='cp_fine_level' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Can Circulate" path='cp_circulate' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Deposit Amount" path='cp_deposit_amount' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Is Deposit Required" path='cp_deposit' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Is Reference" path='cp_ref' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Is Holdable" path='cp_holdable' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Price" path='cp_price' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Barcode" path='cp_barcode' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Circulation Modifier" path='cp_circ_modifier' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Circulate as MARC Type" path='cp_circ_as_type' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Precat Dummy Title" path='cp_dummy_title' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Precat Dummy Author" path='cp_dummy_author' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Alert Message (deprecated)" path='cp_alert_message' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy OPAC Visible" path='cp_opac_visible' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Deleted" path='cp_deleted' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Floating Group" path='cp_floating' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Precat Dummy ISBN" path='cp_dummy_isbn' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Status Change Time" path='cp_status_change_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Active Date" path='cp_active_date' datatype="timestamp" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Is Mint Condition" path='cp_mint_condition' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Cost" path='cp_cost' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Status" path='cs_name' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Status Is Holdable" path='cs_holdable' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Status Is OPAC Visible" path='cs_opac_visible' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Status Is Copy-Active" path='cs_copy_active' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Status Is Deleted" path='cs_restrict_copy_delete' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Status Is Available" path='cs_is_available' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Issuance i18n-label label" path='issuance_label' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Call Number ID" path='cn_id' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="CN i18n-label label" path='cn_label' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="CN i18n-label label Class" path='cn_label_class' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="CN Sort Key" path='cn_label_sortkey' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Part ID" path='p_id' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Part i18n-label label" path='p_label' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Part Sort Key" path='p_label_sortkey' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Part Is Deleted" path='p_deleted' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="CN Full i18n-label label" path='cn_full_label' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Record ID" path='record_id' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Location ID" path='acpl_id' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Location" path='acpl_name' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Location Holdable" path='acpl_holdable' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Location Hold-Verify" path='acpl_hold_verify' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Location OPAC Visible" path='acpl_opac_visible' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Location Can Circulate" path='acpl_circulate' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Location Prefix" path='acpl_label_prefix' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Location Suffix" path='acpl_label_suffix' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Location Checkin Alert" path='acpl_checkin_alert' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Location Is Deleted" path='acpl_deleted' datatype="bool" [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Location URL" path='acpl_url' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Copy Location Order" path='copy_location_order_position' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Default Estimated Wait Time" path='default_estimated_wait' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Minimum Estimated Wait Time" path='min_estimated_wait' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Peer Hold Count" path='other_holds' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Total Wait Time" path='total_wait_time' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Notify Count" path='notification_count' [hidden]="true"></eg-grid-column>
+    <eg-grid-column i18n-label label="Last Notify Time" path='last_notification_time' datatype="timestamp" [hidden]="true"></eg-grid-column>
+
+  </eg-grid>
+
+</div>
+
+
diff --git a/Open-ILS/src/eg2/src/app/staff/share/holds-grid/holds-grid.component.ts b/Open-ILS/src/eg2/src/app/staff/share/holds-grid/holds-grid.component.ts
new file mode 100644 (file)
index 0000000..1b840e8
--- /dev/null
@@ -0,0 +1,177 @@
+import {Component, OnInit, Input, ViewChild} from '@angular/core';
+import {Observable, Observer, of} from 'rxjs';
+import {map, filter} from 'rxjs/operators';
+import {IdlObject} from '@eg/core/idl.service';
+import {NetService} from '@eg/core/net.service';
+import {OrgService} from '@eg/core/org.service';
+import {AuthService} from '@eg/core/auth.service';
+import {Pager} from '@eg/share/util/pager';
+import {GridDataSource} from '@eg/share/grid/grid';
+import {GridComponent} from '@eg/share/grid/grid.component';
+import {ProgressDialogComponent} from '@eg/share/dialog/progress.component';
+
+@Component({
+  selector: 'eg-holds-grid',
+  templateUrl: 'holds-grid.component.html'
+})
+export class HoldsGridComponent implements OnInit {
+
+    // If either are set/true, the pickup lib selector will display
+    @Input() initialPickupLib: number | IdlObject;
+
+    // How to sort when no sort parameters have been applied
+    // via grid controls.  This uses the eg-grid sort format:
+    // [{name: fname, dir: 'asc'}, {name: fname2, dir: 'desc'}]
+    @Input() defaultSort: any[];
+
+    initDone = false;
+    pickupLib: IdlObject;
+    holdsCount: number;
+    gridDataSource: GridDataSource;
+    @ViewChild('holdsGrid') private holdsGrid: GridComponent;
+    @ViewChild('progressDialog')
+        private progressDialog: ProgressDialogComponent;
+
+    // Bib record ID.
+    _recordId: number;
+    @Input() set recordId(id: number) {
+        this._recordId = id;
+        if (this.initDone) { // reload on update
+            this.holdsGrid.reload();
+        }
+    }
+
+    _userId: number;
+    @Input() set userId(id: number) {
+        this._userId = id;
+        if (this.initDone) {
+            this.holdsGrid.reload();
+        }
+    }
+
+    // Include holds canceled on or after the provided date.
+    // If no value is passed, canceled holds are not displayed.
+    _showCanceledSince: Date;
+    @Input() set showCanceledSince(show: Date) {
+        this._showCanceledSince = show;
+        if (this.initDone) { // reload on update
+            this.holdsGrid.reload();
+        }
+    }
+
+    // Include holds fulfilled on or after hte provided date.
+    // If no value is passed, fulfilled holds are not displayed.
+    _showFulfilledSince: Date;
+    @Input() set showFulfilledSince(show: Date) {
+        this._showFulfilledSince = show;
+        if (this.initDone) { // reload on update
+            this.holdsGrid.reload();
+        }
+    }
+
+    constructor(
+        private net: NetService,
+        private org: OrgService,
+        private auth: AuthService,
+    ) {
+        this.gridDataSource = new GridDataSource();
+    }
+
+    ngOnInit() {
+        this.initDone = true;
+        this.pickupLib = this.org.get(this.initialPickupLib);
+
+        this.gridDataSource.getRows = (pager: Pager, sort: any[]) => {
+
+            if (this.defaultSort && sort.length === 0) {
+                // Only use initial sort if sorting has not been modified
+                // by the grid's own sort controls.
+                sort = this.defaultSort;
+            }
+
+            // sorting not currently supported
+            return this.fetchHolds(pager, sort);
+        };
+    }
+
+    pickupLibChanged(org: IdlObject) {
+        this.pickupLib = org;
+        this.holdsGrid.reload();
+    }
+
+    fetchHolds(pager: Pager, sort: any[]): Observable<any> {
+
+        // We need at least one filter.
+        if (!this._recordId && !this.pickupLib && !this._userId) {
+            return of([]);
+        }
+
+        const restrictions: any = {
+            is_staff_request: true,
+            fulfillment_time: this._showFulfilledSince ?
+                this._showFulfilledSince.toISOString() : null,
+            cancel_time: this._showCanceledSince ?
+                this._showCanceledSince.toISOString() : null,
+        };
+
+        if (this.pickupLib) {
+            restrictions.pickup_lib =
+                this.org.descendants(this.pickupLib, true);
+        }
+
+        if (this._recordId) {
+            restrictions.record_id = this._recordId;
+        }
+
+        if (this._userId) {
+            restrictions.usr_id = this._userId;
+        }
+
+        const orderBy: any = [];
+        sort.forEach(obj => {
+            const subObj: any = {};
+            subObj[obj.name] = {dir: obj.dir, nulls: 'last'};
+            orderBy.push(subObj);
+        });
+
+        let observer: Observer<any>;
+        const observable = new Observable(obs => observer = obs);
+
+        this.progressDialog.open();
+        this.progressDialog.update({value: 0, max: 1});
+        let first = true;
+        let loadCount = 0;
+        this.net.request(
+            'open-ils.circ',
+            'open-ils.circ.hold.wide_hash.stream',
+            this.auth.token(), restrictions, orderBy, pager.limit, pager.offset
+        ).subscribe(
+            holdData => {
+
+                if (first) { // First response is the hold count.
+                    this.holdsCount = Number(holdData);
+                    first = false;
+
+                } else { // Subsequent responses are hold data blobs
+
+                    this.progressDialog.update(
+                        {value: ++loadCount, max: this.holdsCount});
+
+                    observer.next(holdData);
+                }
+            },
+            err => {
+                this.progressDialog.close();
+                observer.error(err);
+            },
+            ()  => {
+                this.progressDialog.close();
+                observer.complete();
+            }
+        );
+
+        return observable;
+    }
+}
+
+
diff --git a/Open-ILS/src/eg2/src/app/staff/share/holds-grid/holds-grid.module.ts b/Open-ILS/src/eg2/src/app/staff/share/holds-grid/holds-grid.module.ts
new file mode 100644 (file)
index 0000000..1364729
--- /dev/null
@@ -0,0 +1,19 @@
+import {NgModule} from '@angular/core';
+import {StaffCommonModule} from '@eg/staff/common.module';
+import {HoldsGridComponent} from './holds-grid.component';
+
+@NgModule({
+    declarations: [
+        HoldsGridComponent
+    ],
+    imports: [
+        StaffCommonModule
+    ],
+    exports: [
+        HoldsGridComponent
+    ],
+    providers: [
+    ]
+})
+
+export class HoldsGridModule {}