From a77de262a0209636f2b3186008c76592b9c6e768 Mon Sep 17 00:00:00 2001 From: Bill Erickson Date: Fri, 28 Dec 2018 12:16:13 -0500 Subject: [PATCH] LP1806087 Metarecord holds formats/lang selectors Signed-off-by: Bill Erickson --- .../eg2/src/app/share/catalog/catalog.service.ts | 8 +- .../eg2/src/app/share/catalog/search-context.ts | 10 ++ .../src/app/staff/catalog/hold/hold.component.html | 133 ++++++++++++++------- .../src/app/staff/catalog/hold/hold.component.ts | 104 ++++++++++++++-- .../app/staff/catalog/result/record.component.html | 1 - .../app/staff/catalog/result/record.component.ts | 13 +- .../src/eg2/src/app/staff/share/hold.service.ts | 2 +- 7 files changed, 209 insertions(+), 62 deletions(-) diff --git a/Open-ILS/src/eg2/src/app/share/catalog/catalog.service.ts b/Open-ILS/src/eg2/src/app/share/catalog/catalog.service.ts index 86a014d6b4..068fef728a 100644 --- a/Open-ILS/src/eg2/src/app/share/catalog/catalog.service.ts +++ b/Open-ILS/src/eg2/src/app/share/catalog/catalog.service.ts @@ -189,13 +189,7 @@ export class CatalogService { ctx.org.root().ou_type().depth() : ctx.searchOrg.ou_type().depth(); - // Term search, looking for metarecords, but no - // specific metarecord has been selected for display. - const isMeta = ( - ctx.termSearch.isSearchable() && - ctx.termSearch.groupByMetarecord && - !ctx.termSearch.fromMetarecord - ); + const isMeta = ctx.termSearch.isMetarecordSearch(); let observable: Observable; diff --git a/Open-ILS/src/eg2/src/app/share/catalog/search-context.ts b/Open-ILS/src/eg2/src/app/share/catalog/search-context.ts index 11e5c896b3..d34d71105d 100644 --- a/Open-ILS/src/eg2/src/app/share/catalog/search-context.ts +++ b/Open-ILS/src/eg2/src/app/share/catalog/search-context.ts @@ -154,6 +154,16 @@ export class CatalogTermContext { CATALOG_CCVM_FILTERS.forEach(code => this.ccvmFilters[code] = ['']); } + // True when grouping by metarecord but not when displaying the + // contents of a metarecord. + isMetarecordSearch(): boolean { + return ( + this.isSearchable() && + this.groupByMetarecord && + this.fromMetarecord === null + ); + } + isSearchable(): boolean { return ( this.query[0] !== '' diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/hold/hold.component.html b/Open-ILS/src/eg2/src/app/staff/catalog/hold/hold.component.html index e4f24332c3..1ef096c495 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/hold/hold.component.html +++ b/Open-ILS/src/eg2/src/app/staff/catalog/hold/hold.component.html @@ -193,55 +193,100 @@
Override
- -
- - {{iconFormatLabel(code)}} - -
- -
{{ctx.holdMeta.bibSummary.display.author}}
-
- - {{ctx.holdMeta.volume.label()}} - -
-
- - {{ctx.holdMeta.copy.barcode()}} - -
-
- -
Hold Pending
-
- -
Hold Processing...
-
- - -
Hold Succeeded
+
+
+
+ + {{iconFormatLabel(code)}} + +
+ + +
{{ctx.holdMeta.bibSummary.display.author}}
+
+ + {{ctx.holdMeta.volume.label()}} + +
+
+ + {{ctx.holdMeta.copy.barcode()}} + +
+
+ +
Hold Pending
+
+ +
Hold Processing...
- -
- {{ctx.lastRequest.result.evt.textcode}} + + +
Hold Succeeded
+
+ +
+ {{ctx.lastRequest.result.evt.textcode}} +
+
+
+
+
+ + + +
+
+ +
+
+
+ +
+ + {{iconFormatLabel(ccvm.code())}} +
- +
-
- - - +
+
+
+ +
+ + +
+
+
- +
diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/hold/hold.component.ts b/Open-ILS/src/eg2/src/app/staff/catalog/hold/hold.component.ts index b7f341d07b..a0a0dc24f4 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/hold/hold.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/catalog/hold/hold.component.ts @@ -23,6 +23,17 @@ class HoldContext { lastRequest: HoldRequest; canOverride?: boolean; processing: boolean; + selectedFormats: any; + + constructor(target: number) { + this.holdTarget = target; + this.processing = false; + this.selectedFormats = { + // code => selected-boolean + formats: {}, + langs: {} + } + } } @Component({ @@ -89,8 +100,7 @@ export class HoldComponent implements OnInit { this.pickupLib = this.auth.user().ws_ou(); this.holdContexts = this.holdTargets.map(target => { - const ctx = new HoldContext(); - ctx.holdTarget = target; + const ctx = new HoldContext(target); return ctx; }); @@ -118,10 +128,82 @@ export class HoldComponent implements OnInit { this.holds.getHoldTargetMeta(this.holdType, this.holdTargets) .subscribe(meta => { this.holdContexts.filter(ctx => ctx.holdTarget === meta.target) - .forEach(ctx => ctx.holdMeta = meta); + .forEach(ctx => { + ctx.holdMeta = meta; + this.mrFiltersToSelectors(ctx); + }); }); } + // By default, all metarecord filters options are enabled. + mrFiltersToSelectors(ctx: HoldContext) { + if (this.holdType !== 'M') { return; } + + const meta = ctx.holdMeta; + if (meta.metarecord_filters) { + if (meta.metarecord_filters.formats) { + meta.metarecord_filters.formats.forEach( + ccvm => ctx.selectedFormats.formats[ccvm.code()] = true); + } + if (meta.metarecord_filters.langs) { + meta.metarecord_filters.langs.forEach( + ccvm => ctx.selectedFormats.langs[ccvm.code()] = true); + } + } + } + + // Map the selected metarecord filters optoins to a JSON-encoded + // list of attr filters as required by the API. + // Compiles a blob of + // {target: JSON({"0": [{_attr: ctype, _val: code}, ...], "1": [...]})} + // TODO: this should live in the hold service, not in the UI code. + mrSelectorsToFilters(ctx: HoldContext): {[target: number]: string} { + + const meta = ctx.holdMeta; + const slf = ctx.selectedFormats; + const result: any = {}; + + const formats = Object.keys(slf.formats) + .filter(code => Boolean(slf.formats[code])); // user-selected + + const langs = Object.keys(slf.langs) + .filter(code => Boolean(slf.langs[code])); // user-selected + + const compiled: any = {}; + + if (formats.length > 0) { + compiled['0'] = []; + formats.forEach(code => { + const ccvm = meta.metarecord_filters.formats.filter( + format => format.code() === code)[0]; + compiled['0'].push({ + _attr: ccvm.ctype(), + _val: ccvm.code() + }); + }); + } + + if (langs.length > 0) { + compiled['1'] = []; + langs.forEach(code => { + const ccvm = meta.metarecord_filters.langs.filter( + format => format.code() === code)[0]; + compiled['1'].push({ + _attr: ccvm.ctype(), + _val: ccvm.code() + }); + }); + } + + if (Object.keys(compiled).length > 0) { + const result = {}; + result[ctx.holdTarget] = JSON.stringify(compiled); + return result; + } + + return null; + } + holdForChanged() { this.user = null; @@ -248,6 +330,7 @@ export class HoldComponent implements OnInit { placeOneHold(ctx: HoldContext, override?: boolean): Promise { ctx.processing = true; + const selectedFormats = this.mrSelectorsToFilters(ctx); return this.holds.placeHold({ holdTarget: ctx.holdTarget, @@ -261,7 +344,8 @@ export class HoldComponent implements OnInit { notifySms: this.notifySms ? this.smsValue : null, smsCarrier: this.notifySms ? this.smsCarrier : null, thawDate: this.suspend ? this.activeDate : null, - frozen: this.suspend + frozen: this.suspend, + holdableFormats: selectedFormats }).toPromise().then( request => { @@ -301,10 +385,16 @@ export class HoldComponent implements OnInit { return this.cat.iconFormatLabel(code); } + // TODO: for now, only show meta filters for meta holds. + // Add an "advanced holds" option to display these for T hold. hasMetaFilters(ctx: HoldContext): boolean { - return ctx.holdMeta.metarecord_filters && ( - ctx.holdMeta.metarecord_filters.langs.length > 1 || - ctx.holdMeta.metarecord_filters.formats.length > 1); + return ( + this.holdType === 'M' && // TODO + ctx.holdMeta.metarecord_filters && ( + ctx.holdMeta.metarecord_filters.langs.length > 1 || + ctx.holdMeta.metarecord_filters.formats.length > 1 + ) + ); } } diff --git a/Open-ILS/src/eg2/src/app/staff/catalog/result/record.component.html b/Open-ILS/src/eg2/src/app/staff/catalog/result/record.component.html index 41dd3bc511..90f066b1e9 100644 --- a/Open-ILS/src/eg2/src/app/staff/catalog/result/record.component.html +++ b/Open-ILS/src/eg2/src/app/staff/catalog/result/record.component.html @@ -122,7 +122,6 @@