From 40a209dd2b947cd55b0557be58d0c5baa109f1d9 Mon Sep 17 00:00:00 2001 From: Jason Etheridge Date: Fri, 10 May 2019 02:52:01 -0400 Subject: [PATCH] lp1811710: toward hopeless UI dedicated interface and grid tweaks Signed-off-by: Jason Etheridge Signed-off-by: Galen Charlton Signed-off-by: Terran McCanna Signed-off-by: Chris Sharp --- .../local/admin-local-splash.component.html | 2 + .../staff/hopeless/hopeless.component.html | 25 +++++ .../app/staff/hopeless/hopeless.component.ts | 59 ++++++++++++ .../src/app/staff/hopeless/hopeless.module.ts | 24 +++++ .../src/app/staff/hopeless/routing.module.ts | 16 ++++ .../src/eg2/src/app/staff/routing.module.ts | 3 + .../app/staff/share/holds/grid.component.html | 15 +++ .../app/staff/share/holds/grid.component.ts | 91 ++++++++++++++++++- .../Application/Storage/Publisher/action.pm | 10 ++ .../templates/staff/admin/local/t_splash.tt2 | 1 + 10 files changed, 245 insertions(+), 1 deletion(-) create mode 100644 Open-ILS/src/eg2/src/app/staff/hopeless/hopeless.component.html create mode 100644 Open-ILS/src/eg2/src/app/staff/hopeless/hopeless.component.ts create mode 100644 Open-ILS/src/eg2/src/app/staff/hopeless/hopeless.module.ts create mode 100644 Open-ILS/src/eg2/src/app/staff/hopeless/routing.module.ts diff --git a/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html b/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html index b18dda9da9..7fc28dc676 100644 --- a/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html +++ b/Open-ILS/src/eg2/src/app/staff/admin/local/admin-local-splash.component.html @@ -38,6 +38,8 @@ routerLink="/staff/admin/local/config/hold_matrix_matchpoint"> + + + + + +
+
Hopeless Date, Start Range:
+ + +
Hopeless Date, End Range:
+ + +
+ + + + diff --git a/Open-ILS/src/eg2/src/app/staff/hopeless/hopeless.component.ts b/Open-ILS/src/eg2/src/app/staff/hopeless/hopeless.component.ts new file mode 100644 index 0000000000..a7a4491afa --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/hopeless/hopeless.component.ts @@ -0,0 +1,59 @@ + +import {Component, OnInit, ViewChild, Input, TemplateRef} from '@angular/core'; +import {IdlObject} from '@eg/core/idl.service'; +import {PcrudService} from '@eg/core/pcrud.service'; +import {AuthService} from '@eg/core/auth.service'; +import {FormatService} from '@eg/core/format.service'; +import {Pager} from '@eg/share/util/pager'; +import {DateSelectComponent} from '@eg/share/date-select/date-select.component'; +import {BibRecordService, BibRecordSummary} from '@eg/share/catalog/bib-record.service'; + +@Component({ + templateUrl: 'hopeless.component.html' +}) +export class HopelessComponent implements OnInit { + + startDate: any; + endDate: any; + workstation_lib: IdlObject; + + changeStartDate(date) { + this.startDate = date; + } + + changeEndDate(date) { + date.setHours(23); + date.setMinutes(59); + date.setSeconds(59); + this.endDate = date; + } + + constructor( + private pcrud: PcrudService, + private auth: AuthService, + private format: FormatService, + private bib: BibRecordService, + ) {} + + ngOnInit() { + + // for the pickup library selector + this.workstation_lib = this.auth.user().ws_ou(); + + // Default startDate to today - 10 years + const sd = new Date(); + sd.setFullYear( sd.getFullYear() - 10 ); + this.startDate = sd.toISOString(); + + // Default endDate to today. + const ed = new Date(); + ed.setHours(23); + ed.setMinutes(59); + ed.setSeconds(59); + this.endDate = ed.toISOString(); + + } + +} + + diff --git a/Open-ILS/src/eg2/src/app/staff/hopeless/hopeless.module.ts b/Open-ILS/src/eg2/src/app/staff/hopeless/hopeless.module.ts new file mode 100644 index 0000000000..293d63005a --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/hopeless/hopeless.module.ts @@ -0,0 +1,24 @@ +import {NgModule} from '@angular/core'; +import {StaffCommonModule} from '@eg/staff/common.module'; +import {CatalogCommonModule} from '@eg/share/catalog/catalog-common.module'; +import {HopelessRoutingModule} from './routing.module'; +import {HopelessComponent} from './hopeless.component'; +import {HoldsModule} from '@eg/staff/share/holds/holds.module'; + +@NgModule({ + declarations: [ + HopelessComponent + ], + imports: [ + StaffCommonModule, + CatalogCommonModule, + HopelessRoutingModule, + HoldsModule + ], + providers: [ + ] +}) + +export class HopelessModule { + +} diff --git a/Open-ILS/src/eg2/src/app/staff/hopeless/routing.module.ts b/Open-ILS/src/eg2/src/app/staff/hopeless/routing.module.ts new file mode 100644 index 0000000000..444471c73b --- /dev/null +++ b/Open-ILS/src/eg2/src/app/staff/hopeless/routing.module.ts @@ -0,0 +1,16 @@ +import {NgModule} from '@angular/core'; +import {RouterModule, Routes} from '@angular/router'; +import {HopelessComponent} from './hopeless.component'; + +const routes: Routes = [{ + path: '', + component: HopelessComponent +}]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], + providers: [] +}) + +export class HopelessRoutingModule {} diff --git a/Open-ILS/src/eg2/src/app/staff/routing.module.ts b/Open-ILS/src/eg2/src/app/staff/routing.module.ts index 86428ba10e..edff9a805c 100644 --- a/Open-ILS/src/eg2/src/app/staff/routing.module.ts +++ b/Open-ILS/src/eg2/src/app/staff/routing.module.ts @@ -51,6 +51,9 @@ const routes: Routes = [{ path: 'sandbox', loadChildren: () => import('./sandbox/sandbox.module').then(m => m.SandboxModule) + }, { + path: 'hopeless', + loadChildren : '@eg/staff/hopeless/hopeless.module#HopelessModule' }, { path: 'admin', loadChildren: () => diff --git a/Open-ILS/src/eg2/src/app/staff/share/holds/grid.component.html b/Open-ILS/src/eg2/src/app/staff/share/holds/grid.component.html index 9cead96e0c..850f097f27 100644 --- a/Open-ILS/src/eg2/src/app/staff/share/holds/grid.component.html +++ b/Open-ILS/src/eg2/src/app/staff/share/holds/grid.component.html @@ -33,6 +33,7 @@ @@ -84,6 +85,20 @@ i18-group group="Hold" i18n-label label="Print Holds" (onClick)="printHolds()"> + + + + + + diff --git a/Open-ILS/src/eg2/src/app/staff/share/holds/grid.component.ts b/Open-ILS/src/eg2/src/app/staff/share/holds/grid.component.ts index 01b44bf653..5828243bcf 100644 --- a/Open-ILS/src/eg2/src/app/staff/share/holds/grid.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/share/holds/grid.component.ts @@ -19,6 +19,7 @@ import {HoldTransferDialogComponent} from './transfer-dialog.component'; import {HoldCancelDialogComponent} from './cancel-dialog.component'; import {HoldManageDialogComponent} from './manage-dialog.component'; import {PrintService} from '@eg/share/print/print.service'; +import {HoldingsService} from '@eg/staff/share/holdings/holdings.service'; /** Holds grid with access to detail page and other actions */ @@ -32,6 +33,10 @@ export class HoldsGridComponent implements OnInit { @Input() initialPickupLib: number | IdlObject; @Input() hidePickupLibFilter: boolean; + // If true, only retrieve holds with a Hopeless Date + // and enable related Actions + @Input() hopeless: boolean; + // Grid persist key @Input() persistKey: string; @@ -49,6 +54,9 @@ export class HoldsGridComponent implements OnInit { // [{name: fname, dir: 'asc'}, {name: fname2, dir: 'desc'}] @Input() defaultSort: any[]; + // To pass through to the underlying eg-grid + @Input() showFields: string; + mode: 'list' | 'detail' | 'manage' = 'list'; initDone = false; holdsCount: number; @@ -112,14 +120,34 @@ export class HoldsGridComponent implements OnInit { } } + cellTextGenerator: GridCellTextGenerator; + // Include holds marked Hopeless on or after this date. + _showHopelessAfter: Date; + @Input() set showHopelessAfter(show: Date) { + this._showHopelessAfter = show; + if (this.initDone) { // reload on update + this.holdsGrid.reload(); + } + } + + // Include holds marked Hopeless on or before this date. + _showHopelessBefore: Date; + @Input() set showHopelessBefore(show: Date) { + this._showHopelessBefore = show; + if (this.initDone) { // reload on update + this.holdsGrid.reload(); + } + } + constructor( private net: NetService, private org: OrgService, private store: ServerStoreService, private auth: AuthService, - private printer: PrintService + private printer: PrintService, + private holdings: HoldingsService ) { this.gridDataSource = new GridDataSource(); this.enablePreFetch = null; @@ -186,6 +214,7 @@ export class HoldsGridComponent implements OnInit { } applyFilters(): any { + const filters: any = { is_staff_request: true, fulfillment_time: this._showFulfilledSince ? @@ -194,6 +223,27 @@ export class HoldsGridComponent implements OnInit { this._showCanceledSince.toISOString() : null, }; + if (this.hopeless) { + filters['hopeless_holds'] = { + 'start_date' : this._showHopelessAfter + ? ( + // FIXME -- consistency desired, string or object + typeof this._showHopelessAfter === 'object' + ? this._showHopelessAfter.toISOString() + : this._showHopelessAfter + ) + : '1970-01-01T00:00:00.000Z', + 'end_date' : this._showHopelessBefore + ? ( + // FIXME -- consistency desired, string or object + typeof this._showHopelessBefore === 'object' + ? this._showHopelessBefore.toISOString() + : this._showHopelessBefore + ) + : (new Date()).toISOString() + }; + } + if (this.pickupLib) { filters.pickup_lib = this.org.descendants(this.pickupLib, true); @@ -270,6 +320,16 @@ export class HoldsGridComponent implements OnInit { return observable; } + metaRecordHoldsSelected(rows: IdlObject[]) { + var found = false; + rows.forEach( row => { + if (row.hold_type == 'M') { + found = true; + } + }); + return found; + } + showDetails(rows: any[]) { this.showDetail(rows[0]); } @@ -315,6 +375,35 @@ export class HoldsGridComponent implements OnInit { } } + showOrder(rows: any[]) { + //Doesn't work in Typescript currently without compiler option: + // const bibIds = [...new Set( rows.map(r => r.record_id) )]; + const bibIds = Array.from( + new Set( rows.filter(r => r.hold_type!='M').map(r => r.record_id) )); + bibIds.forEach( bibId => { + const url = + '/eg/staff/acq/legacy/lineitem/related/' + bibId + '?target=bib'; + window.open(url, '_blank'); + }); + } + + addVolume(rows: any[]) { + const bibIds = Array.from( + new Set( rows.filter(r => r.hold_type!='M').map(r => r.record_id) )); + bibIds.forEach( bibId => { + this.holdings.spawnAddHoldingsUi(bibId); + }); + } + + showTitle(rows: any[]) { + const bibIds = Array.from(new Set( rows.map(r => r.record_id) )); + bibIds.forEach( bibId => { + //const url = '/eg/staff/cat/catalog/record/' + bibId; + const url = '/eg2/staff/catalog/record/' + bibId; + window.open(url, '_blank'); + }); + } + showManageDialog(rows: any[]) { const holdIds = rows.map(r => r.id).filter(id => Boolean(id)); if (holdIds.length > 0) { diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm index 7cf6e26cc1..c72a55ec55 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Publisher/action.pm @@ -2142,6 +2142,9 @@ sub wide_hold_data { my $last_captured_hold = delete($$restrictions{last_captured_hold}) || 'false'; $last_captured_hold = $last_captured_hold eq 'true' ? 1 : 0; + # option to filter for hopeless holds by date range + my $hopeless_holds = delete($$restrictions{hopeless_holds}) || 'false'; + my $initial_condition = 'TRUE'; if ($last_captured_hold) { $initial_condition = <<" SQL"; @@ -2156,6 +2159,13 @@ sub wide_hold_data { SQL } + if (ref($hopeless_holds) =~ /HASH/ && $$hopeless_holds{start_date} && $$hopeless_holds{end_date}) { + my $start_date = DateTime::Format::ISO8601->parse_datetime(clean_ISO8601($$hopeless_holds{start_date})); + my $end_date = DateTime::Format::ISO8601->parse_datetime(clean_ISO8601($$hopeless_holds{end_date})); + my $hopeless_condition = "(frozen IS FALSE AND h.hopeless_date >= '$start_date' AND h.hopeless_date <= '$end_date')"; + $initial_condition .= " AND $hopeless_condition"; + } + my $select = <<" SQL"; WITH t_field AS (SELECT field FROM config.display_field_map WHERE name = 'title'), diff --git a/Open-ILS/src/templates/staff/admin/local/t_splash.tt2 b/Open-ILS/src/templates/staff/admin/local/t_splash.tt2 index 4d01c4a499..e5363015bd 100644 --- a/Open-ILS/src/templates/staff/admin/local/t_splash.tt2 +++ b/Open-ILS/src/templates/staff/admin/local/t_splash.tt2 @@ -23,6 +23,7 @@ ,[ l('Group Penalty Thresholds'), "./admin/local/permission/grp_penalty_threshold" ] ,[ l('Hold Policies'), "./admin/local/config/hold_matrix_matchpoint" ] ,[ l('Holdings Template Editor'), "./cat/volcopy/edit_templates" ] + ,[ l('Hopeless Holds'), "/eg2/staff/hopeless" ] ,[ l('Item Alert Suppression'), "./admin/local/actor/copy_alert_suppress" ] ,[ l('Item Alert Types'), "./admin/local/config/copy_alert_types" ] ,[ l('Item Tags'), "./admin/local/asset/copy_tag" ] -- 2.43.2