1 import {Component, AfterViewInit, ViewChild, Renderer2, OnInit} from '@angular/core';
2 import {ActivatedRoute} from '@angular/router';
3 import {NgbPanelChangeEvent} from '@ng-bootstrap/ng-bootstrap';
4 import {HttpClient, HttpRequest, HttpEventType} from '@angular/common/http';
5 import {HttpResponse, HttpErrorResponse} from '@angular/common/http';
6 import {saveAs} from 'file-saver';
7 import {AuthService} from '@eg/core/auth.service';
8 import {ToastService} from '@eg/share/toast/toast.service';
9 import {ProgressInlineComponent} from '@eg/share/dialog/progress-inline.component';
10 import {VANDELAY_EXPORT_PATH} from './vandelay.service';
11 import {BasketService} from '@eg/share/catalog/basket.service';
15 templateUrl: 'export.component.html'
17 export class ExportComponent implements AfterViewInit, OnInit {
26 recordEncoding: string;
27 includeHoldings: boolean;
29 exportingBasket: boolean;
30 basketRecords: number[];
32 @ViewChild('fileSelector') private fileSelector;
33 @ViewChild('exportProgress')
34 private exportProgress: ProgressInlineComponent;
37 private renderer: Renderer2,
38 private route: ActivatedRoute,
39 private http: HttpClient,
40 private toast: ToastService,
41 private auth: AuthService,
42 private basket: BasketService
44 this.recordType = 'biblio';
45 this.recordFormat = 'USMARC';
46 this.recordEncoding = 'UTF-8';
47 this.includeHoldings = false;
48 this.basketRecords = [];
52 const segments = this.route.snapshot.url.length;
54 this.route.snapshot.url[segments - 1].path === 'basket') {
55 this.exportingBasket = true;
56 this.basket.getRecordIds().then(
57 ids => this.basketRecords = ids
63 if (this.exportingBasket) {
64 return; // no source to focus
66 this.renderer.selectRootElement('#csv-input').focus();
69 sourceChange($event: NgbPanelChangeEvent) {
70 this.recordSource = $event.panelId;
72 if (this.exportingBasket) {
73 return; // no source to focus
76 if ($event.nextState) { // panel opened
78 // give the panel a chance to render before focusing input
80 this.renderer.selectRootElement(
81 `#${this.recordSource}-input`).focus();
86 fileSelected($event) {
87 this.selectedFile = $event.target.files[0];
90 hasNeededData(): boolean {
95 (this.exportingBasket && this.basketRecords.length > 0)
100 this.isExporting = true;
101 this.exportProgress.update({value: 0});
103 const formData: FormData = new FormData();
105 formData.append('ses', this.auth.token());
106 formData.append('rectype', this.recordType);
107 formData.append('encoding', this.recordEncoding);
108 formData.append('format', this.recordFormat);
110 if (this.includeHoldings) {
111 formData.append('holdings', '1');
114 if (this.exportingBasket) {
115 this.basketRecords.forEach(id => formData.append('id', '' + id));
119 switch (this.recordSource) {
122 formData.append('idcolumn', '' + this.fieldNumber);
123 formData.append('idfile',
124 this.selectedFile, this.selectedFile.name);
128 formData.append('id', '' + this.recordId);
132 formData.append('containerid', '' + this.bucketId);
137 this.sendExportRequest(formData);
140 sendExportRequest(formData: FormData) {
142 const fileName = `export.${this.recordType}.` +
143 `${this.recordEncoding}.${this.recordFormat}`;
145 const req = new HttpRequest('POST', VANDELAY_EXPORT_PATH,
146 formData, {reportProgress: true, responseType: 'text'});
148 this.http.request(req).subscribe(
151 if (evt.type === HttpEventType.DownloadProgress) {
152 // File size not reported by server in advance.
153 this.exportProgress.update({value: evt.loaded});
155 } else if (evt instanceof HttpResponse) {
157 saveAs(new Blob([evt.body as Blob],
158 {type: 'application/octet-stream'}), fileName);
160 this.isExporting = false;
164 (err: HttpErrorResponse) => {
166 this.toast.danger(err.error);
167 this.isExporting = false;