import {Component, OnInit, AfterViewInit, Input, ViewChild} from '@angular/core';
+import {tap} from 'rxjs/operators/tap';
import {IdlObject} from '@eg/core/idl.service';
+import {NetService} from '@eg/core/net.service';
+import {EventService} from '@eg/core/event.service';
import {OrgService} from '@eg/core/org.service';
+import {AuthService} from '@eg/core/auth.service';
import {ToastService} from '@eg/share/toast/toast.service';
import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
import {VandelayService} from './vandelay.service';
minQualityRatio: number;
autoOverlayAcqCopies: boolean;
+ // True after the first upload, then remains true.
showProgress: boolean;
+ // Upload in progress.
+ isUploading: boolean;
+
+ // Upload / processsing session key
+ // Generated by the server
+ sessionKey: string;
+
@ViewChild('fileSelector') private fileSelector;
@ViewChild('uploadProgress')
private uploadProgress: ProgressInlineComponent;
+ @ViewChild('enqueueProgress')
+ private enqueueProgress: ProgressInlineComponent;
+ @ViewChild('importProgress')
+ private importProgress: ProgressInlineComponent;
constructor(
private http: HttpClient,
private toast: ToastService,
+ private evt: EventService,
+ private net: NetService,
+ private auth: AuthService,
private org: OrgService,
private vandelay: VandelayService
) {
this.selectedFile = $event.target.files[0];
}
+ // Required form data varies depending on context.
+ confirmNeededData(): boolean {
+ if (!this.selectedQueue) {
+ return false;
+ }
+ return true;
+ }
+
+ // 1. create queue if necessary
+ // 2. upload MARC file
+ // 3. Enqueue MARC records
+ // 4. Import records
upload() {
+ if (!this.confirmNeededData()) { return; }
+
+ this.sessionKey = null;
this.showProgress = true;
+ this.isUploading = true;
this.uploadProgress.reset();
+ this.enqueueProgress.update({value: 0, max: 1});
+ this.importProgress.update({value: 0, max: 1});
+
+ let useQueueId; // find or create
+
+ this.resolveQueue()
+ .then(
+ queueId => {
+ useQueueId = queueId;
+ return this.uploadFile();
+ },
+ err => {
+ this.isUploading = false;
+ }
+ ).then(
+ ok => this.processSpool(useQueueId),
+ err => {
+ this.isUploading = false;
+ }
+ );
+ }
+
+ // Extract selected queue ID or create a new queue when requested.
+ resolveQueue(): Promise<number> {
+ if (this.selectedQueue.freetext) {
+ // Free text queue selector means create a new entry.
+ // TODO: first check for name dupes
+
+ return this.vandelay.createQueue(
+ this.selectedQueue.label,
+ this.recordType,
+ this.selectedHoldingsProfile,
+ this.selectedMatchSet,
+ this.selectedBucket
+ );
+
+ } else {
+ return Promise.resolve(this.selectedQueue.id);
+ }
+ }
+
+ uploadFile(): Promise<any> {
const formData: FormData = new FormData();
- formData.append(
- 'marc_upload', this.selectedFile, this.selectedFile.name);
- // TODO: fill in other fields
+ formData.append('marc_upload',
+ this.selectedFile, this.selectedFile.name);
+
+ if (this.selectedBibSource) {
+ formData.append('bib_source', ''+this.selectedBibSource);
+ }
const req = new HttpRequest('POST', VAND_UPLOAD_URL, formData,
{reportProgress: true, responseType: 'text'});
- this.http.request(req).subscribe(
+ return this.http.request(req).pipe(tap(
evt => {
if (evt.type === HttpEventType.UploadProgress) {
this.uploadProgress.update(
{value: evt.loaded, max: evt.total});
} else if (evt instanceof HttpResponse) {
- console.log('file uploaded OK');
+ this.sessionKey = evt.body as string;
+ console.log(
+ 'Vandelay file uploaded OK with key '+this.sessionKey);
}
},
console.error(err);
this.toast.danger(err.error.error);
}
- );
+ )).toPromise();
+ }
+ //processSpool(key, queueId, type, onload) {
+ processSpool(queueId: number): Promise<any> {
+ const rtype = this.recordType === 'bib' ? 'bib' : 'authority';
+ const method = `open-ils.vandelay.${rtype}.process_spool`;
+
+ return this.net.request(
+ 'open-ils.vandelay', method,
+ this.auth.token(), this.sessionKey, queueId
+ ).pipe(tap(
+ resp => {
+ const e = this.evt.parse(resp);
+ if (e) {
+ console.log(e);
+ return;
+ }
+
+ // the enqeueu process currently only returns the
+ // number of items processed.
+ this.enqueueProgress.update({max: null, value: resp});
+ },
+ err => {},
+ () => this.enqueueProgress.update({max: 1, value: 1})
+
+ )).toPromise();
}
+
}
import {Injectable, EventEmitter} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {tap} from 'rxjs/operators/tap';
+import {map} from 'rxjs/operators/map';
import {IdlService, IdlObject} from '@eg/core/idl.service';
import {OrgService} from '@eg/core/org.service';
import {NetService} from '@eg/core/net.service';
});
}
+
+ // Create a queue and return the ID of the new queue via promise.
+ createQueue(
+ queueName: string,
+ recordType: string,
+ importDefId: number,
+ matchSet: number,
+ matchBucket: number): Promise<number> {
+
+ const name = recordType === 'bib' ? 'bib' : 'authority';
+ const method = `open-ils.vandelay.${name}_queue.create`;
+
+ let qType = name;
+ if (recordType.match(/acq/)) {
+ let qType = 'acq';
+ }
+
+ return this.net.request(
+ 'open-ils.vandelay', method,
+ this.auth.token(), queueName, null, qType,
+ matchSet, importDefId, matchBucket
+ ).pipe(map(queue => {
+ const e = this.evt.parse(queue);
+ if (e) {
+ console.error(e);
+ return null;
+ }
+ return queue.id();
+ })).toPromise();
+ }
+
}