export interface GridRowFlairEntry {
icon: string; // name of material icon
- title: string; // tooltip string
+ title?: string; // tooltip string
}
export class GridColumnPersistConf {
<div class="row mb-3" *ngIf="importSelection()">
- <div class="col-lg-2">
+ <div class="col-lg-2" *ngIf="selectedQueue">
<button class="btn btn-info label-with-material-icon"
routerLink="/staff/cat/vandelay/queue/{{recordType}}/{{selectedQueue.id}}">
<span class="material-icons">arrow_back</span>
-import {Component, OnInit, AfterViewInit, Input, ViewChild} from '@angular/core';
+import {Component, OnInit, AfterViewInit, Input, ViewChild, OnDestroy} from '@angular/core';
import {tap} from 'rxjs/operators/tap';
import {IdlObject} from '@eg/core/idl.service';
import {NetService} from '@eg/core/net.service';
import {Subject} from 'rxjs/Subject';
interface ImportOptions {
- overlay_map?: any;
+ overlay_map?: {[qrId: number]: /* breId */ number};
import_no_match?: boolean;
auto_overlay_exact?: boolean;
auto_overlay_best_match?: boolean;
templateUrl: 'import.component.html',
styleUrls: ['import.component.css']
})
-export class ImportComponent implements OnInit, AfterViewInit {
+export class ImportComponent implements OnInit, AfterViewInit, OnDestroy {
recordType: string;
selectedQueue: ComboboxEntry; // freetext enabled
this.selectedBibSource = 1; // default to system local
this.recordType = 'bib';
- if (!this.vandelay.importSelection) {
- return;
- }
+ if (this.vandelay.importSelection) {
+
+ if (!this.vandelay.importSelection.queue) {
+ // Incomplete import selection, clear it.
+ this.vandelay.importSelection = null;
+ return;
+ }
- const queue = this.vandelay.importSelection.queue;
- this.recordType = queue.queue_type();
- this.selectedMatchSet = queue.match_set();
+ const queue = this.vandelay.importSelection.queue;
+ this.recordType = queue.queue_type();
+ this.selectedMatchSet = queue.match_set();
- // This will be propagated to selectedQueue as a combobox
- // entry via the combobox
- this.startQueueId = queue.id();
+ // This will be propagated to selectedQueue as a combobox
+ // entry via the combobox
+ this.startQueueId = queue.id();
- if (this.recordType === 'bib') {
- this.selectedBucket = queue.match_bucket();
- this.selectedHoldingsProfile = queue.item_attr_def();
+ if (this.recordType === 'bib') {
+ this.selectedBucket = queue.match_bucket();
+ this.selectedHoldingsProfile = queue.item_attr_def();
+ }
}
}
this.loadStartupData();
}
+ ngOnDestroy() {
+ // If we successfully completed the most recent
+ // upload/import assume the importSelection can be cleared.
+ if (this.uploadComplete) {
+ this.clearSelection();
+ }
+ }
+
importSelection(): VandelayImportSelection {
return this.vandelay.importSelection;
}
compileImportOptions(): ImportOptions {
const options: ImportOptions = {
- overlay_map: null, // TODO
import_no_match: this.importNonMatching,
auto_overlay_exact: this.mergeOnExact,
auto_overlay_best_match: this.mergeOnBestMatch,
strip_field_groups: null // TODO
};
+ if (this.vandelay.importSelection) {
+ options.overlay_map = this.vandelay.importSelection.overlayMap;
+ }
+
return options;
}
</ng-container>
<ng-template #matchesTmpl let-row="row">
- <a i18n
+ <a i18n [ngClass]="{'font-weight-bold': hasOverlayTarget(row.id)}"
routerLink="/staff/cat/vandelay/queue/{{queueType}}/{{queueId}}/record/{{row.id}}/matches">
({{row.matches.length}})
+ {{hasOverlayTarget(row.id) ? '*' : ''}}
</a>
</ng-template>
(onRowActivate)="openRecord($event)"
hideFields="language,pagination,price,rec_identifier,eg_tcn_source,eg_identifier,item_barcode,zsource">
- <eg-grid-toolbar-checkbox i18n-label label="Limit to Records With Matches"
+ <eg-grid-toolbar-checkbox i18n-label label="Records With Matches"
[onChange]="limitToMatches"></eg-grid-toolbar-checkbox>
- <eg-grid-toolbar-checkbox i18n-label label="Limit to Non-Imported Records"
+ <eg-grid-toolbar-checkbox i18n-label label="Non-Imported Records"
[onChange]="limitToNonImported"></eg-grid-toolbar-checkbox>
- <eg-grid-toolbar-checkbox i18n-label label="Limit to Records with Import Errors"
+ <eg-grid-toolbar-checkbox i18n-label label="Records with Import Errors"
[onChange]="limitToImportErrors"></eg-grid-toolbar-checkbox>
<eg-grid-column name="id" [index]="true"
import {map} from 'rxjs/operators/map';
import {filter} from 'rxjs/operators/filter';
import {Router, ActivatedRoute, ParamMap} from '@angular/router';
-import {HttpClient} from '@angular/common/http';
import {Pager} from '@eg/share/util/pager';
import {IdlObject} from '@eg/core/idl.service';
import {EventService} from '@eg/core/event.service';
constructor(
private router: Router,
private route: ActivatedRoute,
- private http: HttpClient,
private evt: EventService,
private net: NetService,
private auth: AuthService,
}
ngOnInit() {
- // Clear previous selection
- this.vandelay.importSelection = null;
}
ngAfterViewInit() {
}));
}
+ findOrCreateImportSelection() {
+ let selection = this.vandelay.importSelection;
+ if (!selection) {
+ selection = new VandelayImportSelection();
+ this.vandelay.importSelection = selection;
+ }
+ selection.queue = this.queueSummary.queue;
+ return selection;
+ }
+
+ hasOverlayTarget(rid: number): boolean {
+ return this.vandelay.importSelection &&
+ Boolean(this.vandelay.importSelection.overlayMap[rid]);
+ }
+
importSelected() {
const rows = this.queueGrid.context.getSelectedRows();
- if (rows.length === 0) { return; }
- const selection = new VandelayImportSelection();
- selection.recordIds = rows.map(row => row.id);
- selection.queue = this.queueSummary.queue;
- this.vandelay.importSelection = selection;
- this.router.navigate(['/staff/cat/vandelay/import']);
+ if (rows.length) {
+ const selection = this.findOrCreateImportSelection();
+ selection.recordIds = rows.map(row => row.id);
+ console.log('importing: ', this.vandelay.importSelection);
+ this.router.navigate(['/staff/cat/vandelay/import']);
+ }
}
importAll() {
- const selection = new VandelayImportSelection();
- selection.queue = this.queueSummary.queue;
+ const selection = this.findOrCreateImportSelection();
selection.importQueue = true;
- this.vandelay.importSelection = selection;
this.router.navigate(['/staff/cat/vandelay/import']);
}
<ng-template #bibIdTemplate let-row="row">
<a routerLink="/staff/catalog/record/{{row.eg_record}}/marc_view" i18n>
- View In Catalog
+ {{row.eg_record}}
</a>
</ng-template>
<ng-container *ngIf="queueType == 'bib'">
- <eg-grid #bibGrid [dataSource]="bibDataSource" [disableMultiSelect]="true">
+ <eg-grid #bibGrid [dataSource]="bibDataSource"
+ [rowFlairIsEnabled]="true"
+ [rowFlairCallback]="matchRowCallback"
+ [disableMultiSelect]="true">
+ <eg-grid-toolbar-action i18n-label label="Mark As Overlay Target"
+ [action]="markOverlayTarget">
+ </eg-grid-toolbar-action>
<eg-grid-column name="id" [index]="true" [hidden]="true"
i18n-label label="Match ID">
</eg-grid-column>
import {map} from 'rxjs/operators/map';
import {Pager} from '@eg/share/util/pager';
import {GridComponent} from '@eg/share/grid/grid.component';
-import {GridDataSource, GridColumn} from '@eg/share/grid/grid';
+import {GridDataSource, GridColumn, GridRowFlairEntry} from '@eg/share/grid/grid';
import {IdlObject} from '@eg/core/idl.service';
import {EventService} from '@eg/core/event.service';
import {NetService} from '@eg/core/net.service';
import {AuthService} from '@eg/core/auth.service';
import {PcrudService} from '@eg/core/pcrud.service';
import {BibRecordService, BibRecordSummary} from '@eg/share/catalog/bib-record.service';
-import {VandelayService} from './vandelay.service';
+import {VandelayService, VandelayImportSelection} from './vandelay.service';
@Component({
selector: 'eg-queued-record-matches',
queuedRecord: IdlObject;
bibDataSource: GridDataSource;
authDataSource: GridDataSource;
+ markOverlayTarget: (rows: any[]) => any;
+ matchRowCallback: (row: any) => GridRowFlairEntry;
constructor(
private router: Router,
this.authDataSource.getRows = (pager: Pager) => {
}
*/
+
+ this.markOverlayTarget = (rows: any[]) => {
+
+ // Start a new import selection object if needed.
+ // This will be adopted by the queue UI before import.
+ let selection = this.vandelay.importSelection;
+ if (!selection) {
+ selection = new VandelayImportSelection();
+ this.vandelay.importSelection = selection;
+ }
+
+ // Grid is configured for single-row-select.
+ const match = rows[0];
+ selection.overlayMap[this.recordId] = match.eg_record;
+ }
+
+ this.matchRowCallback = (row: any) => {
+ const selection = this.vandelay.importSelection;
+ if (selection) {
+ const target = selection.overlayMap[this.recordId];
+ if (target === row.eg_record) {
+ return {icon: 'check_circle'};
+ }
+ }
+ return null;
+ }
+ }
+
+ hasOverlayTarget(rid: number): boolean {
+ return this.vandelay.importSelection &&
+ Boolean(this.vandelay.importSelection.overlayMap[rid]);
}
ngOnInit() {}
</div>
<ngb-tabset #recordTabs [activeId]="recordTab" (tabChange)="onTabChange($event)">
- <ngb-tab title="Queued Record HTML" i18n-title id="marc">
+ <ngb-tab title="Queued Record MARC" i18n-title id="marc">
<ng-template ngbTabContent>
<eg-marc-html [recordId]="recordId" [recordType]="'vandelay-'+queueType">
</eg-marc-html>
recordIds: number[];
queue: IdlObject;
importQueue: boolean; // import the whole queue
+ overlayMap: {[qrId: number]: /* breId */ number};
+
+ constructor() {
+ this.recordIds = [];
+ this.overlayMap = {};
+ }
}
@Injectable()
method, this.auth.token(), queueId, options);
}
+ // Download a queue as a MARC file.
exportQueue(queue: IdlObject, nonImported?: boolean) {
const etype = queue.queue_type().match(/auth/) ? 'auth' : 'bib';