From: Bill Erickson Date: Thu, 21 May 2020 21:10:13 +0000 (-0400) Subject: LPXXX MARC Batch update Angular port X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=ea252f170cf2e45a99273a1f21655418abf5fd97;p=working%2FEvergreen.git LPXXX MARC Batch update Angular port Signed-off-by: Bill Erickson --- diff --git a/Open-ILS/src/eg2/src/app/staff/cat/marcbatch/marcbatch.component.html b/Open-ILS/src/eg2/src/app/staff/cat/marcbatch/marcbatch.component.html index 1ea34b0045..aeaf002726 100644 --- a/Open-ILS/src/eg2/src/app/staff/cat/marcbatch/marcbatch.component.html +++ b/Open-ILS/src/eg2/src/app/staff/cat/marcbatch/marcbatch.component.html @@ -115,27 +115,27 @@
Record Source:
- +
Bucket named:
- +
Record ID:
- +
Column:
@@ -180,7 +180,8 @@
- +
@@ -189,5 +190,12 @@
+
+
+
Processing Complete
+
Success count: {{this.numSucceeded}}
+
Failed count: {{this.numFailed}}
+
+
diff --git a/Open-ILS/src/eg2/src/app/staff/cat/marcbatch/marcbatch.component.ts b/Open-ILS/src/eg2/src/app/staff/cat/marcbatch/marcbatch.component.ts index 1b37b70290..478aa2f42f 100644 --- a/Open-ILS/src/eg2/src/app/staff/cat/marcbatch/marcbatch.component.ts +++ b/Open-ILS/src/eg2/src/app/staff/cat/marcbatch/marcbatch.component.ts @@ -1,11 +1,16 @@ import {Component, OnInit, ViewChild, Renderer2} from '@angular/core'; import {Router, ActivatedRoute, ParamMap} from '@angular/router'; +import {HttpClient} from '@angular/common/http'; import {tap} from 'rxjs/operators'; import {NetService} from '@eg/core/net.service'; import {AuthService} from '@eg/core/auth.service'; import {PcrudService} from '@eg/core/pcrud.service'; import {ComboboxEntry} from '@eg/share/combobox/combobox.component'; import {MarcRecord, MarcField} from '@eg/staff/share/marc-edit/marcrecord'; +import {AnonCacheService} from '@eg/share/util/anon-cache.service'; + +const MERGE_TEMPLATE_PATH = '/opac/extras/merge_template'; +const SESSION_POLL_INTERVAL = 2; // seconds interface TemplateRule { ruleType: 'r' | 'a' | 'd'; @@ -22,12 +27,12 @@ interface TemplateRule { export class MarcBatchComponent implements OnInit { session: string; - source: 'bucket' | 'csv' | 'id' = 'bucket'; + source: 'b' | 'c' | 'r' = 'b'; buckets: ComboboxEntry[]; bucket: number; recordId: number; csvColumn = 0; - selectedFile: File; + csvFile: File; xactPerRecord = false; templateRules: TemplateRule[] = []; record: MarcRecord; @@ -35,21 +40,21 @@ export class MarcBatchComponent implements OnInit { processing = false; progressMax: number = null; progressValue: number = null; + numSucceeded = 0; + numFailed = 0; constructor( private router: Router, private route: ActivatedRoute, + private http: HttpClient, private renderer: Renderer2, private net: NetService, private pcrud: PcrudService, - private auth: AuthService + private auth: AuthService, + private cache: AnonCacheService ) {} ngOnInit() { - this.route.paramMap.subscribe((params: ParamMap) => { - this.session = this.route.snapshot.paramMap.get('session'); - }); - this.load(); } @@ -160,23 +165,90 @@ export class MarcBatchComponent implements OnInit { } fileSelected($event) { - this.selectedFile = $event.target.files[0]; + this.csvFile = $event.target.files[0]; + } + + disableSave(): boolean { + if (!this.record || !this.source || this.processing) { + return true; + } + + if (!this.processing && this.progressMax) { + // Just completed a session. + return true; + } + + if (this.source === 'b') { + return !this.bucket; + + } else if (this.source === 'c') { + return (!this.csvColumn || !this.csvFile); + + } else if (this.source === 'r') { + return !this.recordId; + } } process() { this.processing = true; - this.postForm() - .then(_ => this.pollProgress()) - .then(_ => this.processing = false); + this.progressValue = null; + this.progressMax = null; + this.numSucceeded = 0; + this.numFailed = 0; + + this.postForm().then(_ => this.pollProgress()); } postForm(): Promise { - return Promise.resolve(); + + const formData: FormData = new FormData(); + formData.append('ses', this.auth.token()); + formData.append('skipui', '1'); + formData.append('template', this.record.toXml()); + formData.append('recordSource', this.source); + + if (this.source === 'b') { + formData.append('containerid', this.bucket + ''); + + } else if (this.source === 'c') { + formData.append('idcolumn', this.csvColumn + ''); + formData.append('idfile', this.csvFile, this.csvFile.name); + + } else if (this.source === 'r') { + formData.append('recid', this.recordId + ''); + } + + return this.http.post( + MERGE_TEMPLATE_PATH, formData, {responseType: 'text'}) + .pipe(tap(cacheKey => this.session = cacheKey)) + .toPromise(); } pollProgress(): Promise { - return Promise.resolve(); + console.debug('Polling session ', this.session); + + return this.cache.getItem(this.session, 'batch_edit_progress') + .then(progress => { + // {"success":"t","complete":1,"failed":0,"succeeded":252} + + if (!progress) { + console.error('No batch edit session found for ', this.session); + return; + } + + this.progressValue = progress.succeeded; + this.progressMax = progress.total; + this.numSucceeded = progress.succeeded; + this.numFailed = progress.failed; + + if (progress.complete) { + this.processing = false; + return; + } + + setTimeout(() => this.pollProgress(), SESSION_POLL_INTERVAL * 1000); + }); } } diff --git a/Open-ILS/src/eg2/src/app/staff/cat/marcbatch/marcbatch.module.ts b/Open-ILS/src/eg2/src/app/staff/cat/marcbatch/marcbatch.module.ts index c16eb6a973..bf81553919 100644 --- a/Open-ILS/src/eg2/src/app/staff/cat/marcbatch/marcbatch.module.ts +++ b/Open-ILS/src/eg2/src/app/staff/cat/marcbatch/marcbatch.module.ts @@ -3,6 +3,7 @@ import {StaffCommonModule} from '@eg/staff/common.module'; import {CommonWidgetsModule} from '@eg/share/common-widgets.module'; import {MarcBatchRoutingModule} from './routing.module'; import {MarcBatchComponent} from './marcbatch.component'; +import {HttpClientModule} from '@angular/common/http'; @NgModule({ declarations: [ @@ -10,6 +11,7 @@ import {MarcBatchComponent} from './marcbatch.component'; ], imports: [ StaffCommonModule, + HttpClientModule, CommonWidgetsModule, MarcBatchRoutingModule ], diff --git a/Open-ILS/src/eg2/src/app/staff/cat/marcbatch/routing.module.ts b/Open-ILS/src/eg2/src/app/staff/cat/marcbatch/routing.module.ts index 0c9ad4b8d8..bb268e644d 100644 --- a/Open-ILS/src/eg2/src/app/staff/cat/marcbatch/routing.module.ts +++ b/Open-ILS/src/eg2/src/app/staff/cat/marcbatch/routing.module.ts @@ -5,9 +5,6 @@ import {MarcBatchComponent} from './marcbatch.component'; const routes: Routes = [{ path: '', component: MarcBatchComponent - }, { - path: ':session', - component: MarcBatchComponent }]; @NgModule({ diff --git a/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat.pm b/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat.pm index 4c4d977cca..fd4df38f71 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/Application/Cat.pm @@ -263,11 +263,13 @@ sub template_overlay_container { $template = $e->retrieve_biblio_record_entry( $titem->target_biblio_record_entry )->marc; } + my $num_total = scalar(@$items); my $num_failed = 0; my $num_succeeded = 0; $conn->respond_complete( - $actor->request('open-ils.actor.anon_cache.set_value', $auth, batch_edit_progress => {})->gather(1) + $actor->request('open-ils.actor.anon_cache.set_value', $auth, + batch_edit_progress => {total => $num_total})->gather(1) ) if ($actor); for my $item ( @$items ) { @@ -291,6 +293,7 @@ sub template_overlay_container { $actor->request( 'open-ils.actor.anon_cache.set_value', $auth, batch_edit_progress => { + total => $num_total, succeeded => $num_succeeded, failed => $num_failed }, @@ -308,6 +311,7 @@ sub template_overlay_container { batch_edit_progress => { complete => 1, success => 'f', + total => $num_total, succeeded => $num_succeeded, failed => $num_failed, } @@ -331,6 +335,7 @@ sub template_overlay_container { batch_edit_progress => { complete => 1, success => 't', + total => $num_total, succeeded => $num_succeeded, failed => $num_failed, } @@ -345,6 +350,7 @@ sub template_overlay_container { batch_edit_progress => { complete => 1, success => 'f', + total => $num_total, succeeded => $num_succeeded, failed => $num_failed, } diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/TemplateBatchBibUpdate.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/TemplateBatchBibUpdate.pm index 27a03e1107..777ab8f2e0 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/TemplateBatchBibUpdate.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/TemplateBatchBibUpdate.pm @@ -4,7 +4,7 @@ use warnings; use bytes; use Apache2::Log; -use Apache2::Const -compile => qw(OK REDIRECT DECLINED NOT_FOUND :log); +use Apache2::Const -compile => qw(OK REDIRECT DECLINED NOT_FOUND HTTP_BAD_REQUEST :log); use APR::Const -compile => qw(:error SUCCESS); use APR::Table; @@ -56,11 +56,16 @@ sub handler { my $cgi = new CGI; my $authid = $cgi->cookie('ses') || $cgi->param('ses'); + + # Avoid sending the HTML to the caller. Final response will + # will just be the cache key or HTTP_BAD_REQUEST on error. + my $skipui = $cgi->param('skipui'); + my $usr = verify_login($authid); - return show_template($r) unless ($usr); + return show_template($r, $skipui) unless ($usr); my $template = $cgi->param('template'); - return show_template($r) unless ($template); + return show_template($r, $skipui) unless ($template); my $rsource = $cgi->param('recordSource'); @@ -118,7 +123,7 @@ sub handler { unless (@records) { $e->request('open-ils.cstore.transaction.rollback')->gather(1); $e->disconnect; - return show_template($r); + return show_template($r, $skipui); } # we have a template and some record ids, so... @@ -176,7 +181,8 @@ sub handler { ->request('open-ils.cat.container.template_overlay.background', $authid, $bucket->id) ->gather(1); - return show_processing_template($r, $bucket->id, \@records, $cache_key); + return show_processing_template( + $r, $bucket->id, \@records, $cache_key, $skipui); } sub verify_login { @@ -201,6 +207,13 @@ sub show_processing_template { my $bid = shift; my $recs = shift; my $cache_key = shift; + my $skipui = shift; + + if ($skipui) { + $r->content_type('text/plain'); + $r->print($cache_key); + return Apache2::Const::OK; + } my $rec_string = @$recs; @@ -366,6 +379,11 @@ HTML sub show_template { my $r = shift; + my $skipui = shift; + + # Makes no sense to call the API in such a way that the caller + # is returned the UI code if skipui is set. + return Apache2::Const::HTTP_BAD_REQUEST if $skipui; $r->content_type('text/html'); $r->print(<<'HTML');