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';
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,
this.translatableFields = [];
}
- applyOrgValues() {
+ applyOrgValues(orgId?: number) {
if (this.disableOrgFilter) {
this.orgField = null;
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();
}
}
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;
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) {
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.
this.org.descendants(this.contextOrg, true));
}
- const search = {};
search[this.orgField] = orgs;
- return this.pcrud.search(
- this.idlClass, search, searchOps, {fleshSelectors: true});
}
- // No org filter -- fetch all rows
- return this.pcrud.retrieveAll(
- this.idlClass, searchOps, {fleshSelectors: true});
+ 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});
};
}
</button>
</div>
<div class="modal-body">
- <div class="row">
- <div class="col-lg-12 d-flex justify-content-center">
+ <div class="row" *ngIf="!updateComplete">
+ <div class="col-lg-12">
<span i18n>Make {{copyIds.length}} Item(s) Bookable?</span>
</div>
</div>
+ <div class="row" *ngIf="updateComplete">
+ <div class="col-lg-12 d-flex flex-column">
+ <div i18n>{{numSucceeded}} Item(s) Made Bookable.</div>
+ <div class="mt-2">
+ <a target="_blank" routerLink="/staff/admin/booking/resource"
+ [queryParams]="manageUrlParams()" i18n>
+ Manage Bookable Resources
+ </a>
+ </div>
+ </div>
+ </div>
</div>
<div class="modal-footer">
<ng-container>
-import {Component, OnInit, OnDestroy, Input, ViewChild,
- Renderer2} from '@angular/core';
+import {Component, OnInit, OnDestroy, Input, ViewChild} from '@angular/core';
import {Subscription} from 'rxjs';
import {IdlObject} from '@eg/core/idl.service';
import {NetService} from '@eg/core/net.service';
import {PcrudService} from '@eg/core/pcrud.service';
import {ToastService} from '@eg/share/toast/toast.service';
import {AuthService} from '@eg/core/auth.service';
-import {NgbModal, NgbModalOptions} from '@ng-bootstrap/ng-bootstrap';
+import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
import {DialogComponent} from '@eg/share/dialog/dialog.component';
import {StringComponent} from '@eg/share/string/string.component';
numSucceeded: number;
numFailed: number;
updateComplete: boolean;
+ newResourceType: number;
+ newResourceOrg: number;
onOpenSub: Subscription;
private net: NetService,
private pcrud: PcrudService,
private evt: EventService,
- private renderer: Renderer2,
private auth: AuthService) {
super(modal); // required for subclassing
}
ngOnDestroy() {
this.onOpenSub.unsubscribe();
}
+
+ manageUrlParams(): any {
+ if (this.newResourceOrg) {
+ return {
+ gridFilters: JSON.stringify({type: this.newResourceType}),
+ contextOrg: this.newResourceOrg
+ };
+ }
+ }
+
+ makeBookable() {
+ this.newResourceType = null;
+
+ this.net.request(
+ 'open-ils.booking',
+ 'open-ils.booking.resources.create_from_copies',
+ this.auth.token(), this.copyIds
+ ).toPromise().then(
+ resp => {
+ // resp.brsrc = [[brsrc.id, acp.id, existed], ...]
+ // resp.brt = [[brt.id, brt.peer_record, existed], ...]
+ const evt = this.evt.parse(resp);
+ if (evt) { return Promise.reject(evt); }
+ this.numSucceeded = resp.brsrc.length;
+ this.newResourceType = resp.brt[0][0]; // new resource ID
+ this.updateComplete = true;
+ this.successMsg.current().then(msg => this.toast.success(msg));
+ },
+ err => Promise.reject(err)
+ ).then(
+ ok => {
+ // Once resource creation is complete, grab the call number
+ // for the first copy to get the owning library
+ this.pcrud.retrieve('acp', this.copyIds[0],
+ {flesh: 1, flesh_fields: {acp: ['call_number']}})
+ .toPromise().then(copy => {
+ this.newResourceOrg = copy.call_number().owning_lib();
+ this.updateComplete = true;
+ });
+ },
+ err => {
+ console.error(err);
+ this.numFailed++;
+ this.errorMsg.current().then(msg => this.toast.danger(msg));
+ this.updateComplete = true;
+ }
+ );
+ }
}