<links>
<link field="def_maps" reltype="has_many" key="entry" map="" class="mbedm"/>
</links>
+ <permacrud xmlns="http://open-ils.org/spec/opensrf/IDL/permacrud/v1">
+ <actions>
+ <retrieve/>
+ </actions>
+ </permacrud>
</class>
<class id="mbedm" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="metabib::browse_entry_def_map" oils_persist:tablename="metabib.browse_entry_def_map" reporter:label="Combined Browse Entry Definition Map" oils_persist:readonly="true">
<fields oils_persist:primary="id" oils_persist:sequence="metabib.browse_entry_def_map_id_seq">
params.matchOp = [];
['format', 'available', 'hasBrowseEntry', 'date1',
- 'date2', 'dateOp', 'isMetarecord', 'fromMetarecord']
+ 'date2', 'dateOp', 'groupByMetarecord', 'fromMetarecord']
.forEach(field => {
if (ts[field]) {
params[field] = ts[field];
const ts = context.termSearch;
+ // browseEntry and query searches may be facet-limited
+ params.getAll('facets').forEach(blob => {
+ const facet = JSON.parse(blob);
+ ts.addFacet(new FacetFilter(facet.c, facet.n, facet.v));
+ });
+
if (params.has('hasBrowseEntry')) {
- // Browse entry display is (currently) a standalone filter.
- // Other filters could be applied if needed.
ts.hasBrowseEntry = params.get('hasBrowseEntry');
} else if (params.has('query')) {
// Scalars
['format', 'available', 'date1', 'date2',
- 'dateOp', 'isMetarecord', 'fromMetarecord']
+ 'dateOp', 'groupByMetarecord', 'fromMetarecord']
.forEach(field => {
if (params.has(field)) {
ts[field] = params.get(field);
}
});
- params.getAll('facets').forEach(blob => {
- const facet = JSON.parse(blob);
- ts.addFacet(new FacetFilter(facet.c, facet.n, facet.v));
- });
-
if (params.get('copyLocations')) {
ts.copyLocations = params.get('copyLocations').split(/,/);
}
ctx.identSearch.queryType === 'item_barcode') {
return this.barcodeSearch(ctx);
} else {
- return this.querySearch(ctx);
+ return this.termSearch(ctx);
}
}
});
}
- querySearch(ctx: CatalogSearchContext): Promise<void> {
+ termSearch(ctx: CatalogSearchContext): Promise<void> {
+
+ let method = 'open-ils.search.biblio.multiclass.query';
let fullQuery;
if (ctx.identSearch.isSearchable()) {
fullQuery = ctx.compileIdentSearchQuery();
+
} else {
fullQuery = ctx.compileTermSearchQuery();
- }
- console.debug(`search query: ${fullQuery}`);
+ if (ctx.termSearch.groupByMetarecord
+ && !ctx.termSearch.fromMetarecord) {
+ method = 'open-ils.search.metabib.multiclass.query';
+ }
- let method = 'open-ils.search.biblio.multiclass.query';
- if (ctx.termSearch.isSearchable()
- && ctx.termSearch.isMetarecord
- && !ctx.termSearch.fromMetarecord) {
- method = 'open-ils.search.metabib.multiclass.query';
+ if (ctx.termSearch.hasBrowseEntry) {
+ this.fetchBrowseEntry(ctx);
+ }
}
+ console.debug(`search query: ${fullQuery}`);
+
if (ctx.isStaff) {
method += '.staff';
}
-
+
return new Promise((resolve, reject) => {
this.net.request(
'open-ils.search', method, {
}
+ // When showing titles linked to a browse entry, fetch
+ // the entry data as well so the UI can display it.
+ fetchBrowseEntry(ctx: CatalogSearchContext) {
+ const ts = ctx.termSearch;
+
+ const parts = ts.hasBrowseEntry.split(',');
+ const mbeId = parts[0];
+ const cmfId = parts[1];
+
+ this.pcrud.retrieve('mbe', mbeId)
+ .subscribe(mbe => ctx.termSearch.browseEntry = mbe);
+ }
+
applyResultData(ctx: CatalogSearchContext, result: any): void {
ctx.result = result;
ctx.pager.resultCount = result.count;
// specific metarecord has been selected for display.
const isMeta = (
ctx.termSearch.isSearchable() &&
- ctx.termSearch.isMetarecord &&
+ ctx.termSearch.groupByMetarecord &&
!ctx.termSearch.fromMetarecord
);
copyLocations: string[]; // ID's, but treated as strings in the UI.
// True when searching for metarecords
- isMetarecord: boolean;
+ groupByMetarecord: boolean;
// Filter results by records which link to this metarecord ID.
fromMetarecord: number;
hasBrowseEntry: string; // "entryId,fieldId"
+ browseEntry: IdlObject;
date1: number;
date2: number;
dateOp: string; // before, after, between, is
<div class="row mt-2">
<div class="col-lg-3">
<button class="btn btn-success" (click)="placeHolds()"
- [disabled]="!user" i18n>Place Hold(s)</button>
+ [disabled]="!user || placeHoldsClicked" i18n>Place Hold(s)</button>
</div>
</div>
</form>
</ng-container>
</div>
<div class="col-lg-2">
- <ng-container *ngIf="!ctx.lastRequest">
+ <ng-container *ngIf="!ctx.lastRequest && !ctx.processing">
<div class="alert alert-info" i18n>Hold Pending</div>
</ng-container>
+ <ng-container *ngIf="ctx.processing">
+ <div class="alert alert-primary" i18n>Hold Processing...</div>
+ </ng-container>
<ng-container *ngIf="ctx.lastRequest">
<ng-container *ngIf="ctx.lastRequest.result.success">
<div class="alert alert-success" i18n>Hold Succeeded</div>
holdTarget: number;
lastRequest: HoldRequest;
canOverride?: boolean;
+ processing: boolean;
}
@Component({
smsCarriers: ComboboxEntry[];
smsEnabled: boolean;
+ placeHoldsClicked: boolean;
constructor(
private router: Router,
placeHolds(idx?: number) {
if (!idx) { idx = 0; }
if (!this.holdTargets[idx]) { return; }
- this.placeOneHold(this.holdTargets[idx])
- .then(() => this.placeHolds(idx + 1));
+ this.placeHoldsClicked = true;
+
+ const target = this.holdTargets[idx];
+ const ctx = this.holdContexts.filter(
+ ctx => ctx.holdTarget === target)[0];
+
+ this.placeOneHold(ctx).then(() => this.placeHolds(idx + 1));
}
- placeOneHold(target: number, override?: boolean): Promise<any> {
+ placeOneHold(ctx: HoldContext, override?: boolean): Promise<any> {
+
+ ctx.processing = true;
return this.holds.placeHold({
- holdTarget: target,
+ holdTarget: ctx.holdTarget,
holdType: this.holdType,
recipient: this.user.id(),
requestor: this.requestor.id(),
thawDate: this.suspend ? this.activeDate : null,
frozen: this.suspend
- }).toPromise().then(request => {
- console.log('hold returned: ', request);
-
- const ctx = this.holdContexts.filter(
- ctx => ctx.holdTarget === request.holdTarget)[0];
- ctx.lastRequest = request;
-
- // If this request failed and was not already an override,
- // see of this user has permission to override.
- if (!request.override &&
- !request.result.success && request.result.evt) {
-
- const txtcode = request.result.evt.textcode;
- const perm = txtcode + '.override';
-
- return this.perm.hasWorkPermHere(perm).then(
- permResult => ctx.canOverride = permResult[perm]);
+ }).toPromise().then(
+ request => {
+ console.log('hold returned: ', request);
+ ctx.lastRequest = request;
+ ctx.processing = false;
+
+ // If this request failed and was not already an override,
+ // see of this user has permission to override.
+ if (!request.override &&
+ !request.result.success && request.result.evt) {
+
+ const txtcode = request.result.evt.textcode;
+ const perm = txtcode + '.override';
+
+ return this.perm.hasWorkPermHere(perm).then(
+ permResult => ctx.canOverride = permResult[perm]);
+ }
+ },
+ error => {
+ ctx.processing = false;
+ console.error(error);
}
- });
+ );
}
override(ctx: HoldContext) {
- this.placeOneHold(ctx.holdTarget, true);
+ this.placeOneHold(ctx, true);
}
canOverride(ctx: HoldContext): boolean {
<div id="staff-catalog-results-container" *ngIf="searchHasResults()">
<div class="row">
<div class="col-lg-2" *ngIf="!searchContext.basket">
- <h3 i18n>Search Results ({{searchContext.result.count}})</h3>
+ <ng-container *ngIf="searchContext.termSearch.browseEntry">
+ <h3 i18n>Results for browse "{{searchContext.termSearch.browseEntry.value()}}"</h3>
+ </ng-container>
+ <ng-container *ngIf="!searchContext.termSearch.browseEntry">
+ <h3 i18n>Search Results ({{searchContext.result.count}})</h3>
+ </ng-container>
</div>
<div class="col-lg-2" *ngIf="searchContext.basket">
<h3 i18n>Basket View</h3>
<div class="checkbox pl-3">
<label>
<input type="checkbox"
- [(ngModel)]="context.termSearch.isMetarecord"/>
+ [(ngModel)]="context.termSearch.groupByMetarecord"/>
<span class="pl-1" i18n>Group Formats/Editions</span>
</label>
</div>
this.context.browseSearch.reset();
this.context.identSearch.reset();
this.context.termSearch.hasBrowseEntry = '';
+ this.context.termSearch.browseEntry = null;
this.context.termSearch.fromMetarecord = null;
this.context.termSearch.facetFilters = [];
this.staffCat.search();