import {AuthorityMarcEditComponent} from './marc-edit.component';
import {BrowseAuthorityComponent} from './browse.component';
import {ManageAuthorityComponent} from './manage.component';
+import {AuthorityMergeDialogComponent} from './merge-dialog.component';
import {BrowseService} from './browse.service';
import {BibListModule} from '@eg/staff/share/bib-list/bib-list.module';
declarations: [
AuthorityMarcEditComponent,
BrowseAuthorityComponent,
- ManageAuthorityComponent
+ ManageAuthorityComponent,
+ AuthorityMergeDialogComponent
],
imports: [
StaffCommonModule,
<eg-string #rowSelected text="Row Selected for Merge" i18n-text></eg-string>
+<eg-authority-merge-dialog #mergeDialog></eg-authority-merge-dialog>
+
<div class="row form-inline mb-3">
<div class="col-lg-3">
<div class="input-group">
<eg-grid-toolbar-action label="Clear All Merge Marks" i18n-label
(onClick)="clearMergeSelection()"></eg-grid-toolbar-action>
+ <eg-grid-toolbar-action label="Merge Marked Records" i18n-label
+ (onClick)="openMergeDialog()"></eg-grid-toolbar-action>
+
<eg-grid-column name="id" label="ID" path="authority.id" i18n-label
[index]="true" flex="1"></eg-grid-column>
<eg-grid-column name="link_count" label="Linked Bibs"
import {ComboboxEntry, ComboboxComponent} from '@eg/share/combobox/combobox.component';
import {BrowseService} from './browse.service';
import {StringComponent} from '@eg/share/string/string.component';
+import {AuthorityMergeDialogComponent} from './merge-dialog.component';
/* Find, merge, and edit authority records */
@ViewChild('grid', {static: false}) grid: GridComponent;
@ViewChild('axisCbox', {static: false}) axisCbox: ComboboxComponent;
@ViewChild('rowSelected', {static: false}) rowSelected: StringComponent;
+ @ViewChild('mergeDialog', {static: false})
+ mergeDialog: AuthorityMergeDialogComponent;
constructor(
private net: NetService,
this.browse.authorityAxis = this.authorityAxis.id;
} else {
+ // Our browse service may have cached search params
if (this.browse.authorityAxis) {
this.axisCbox.selectedId = this.browse.authorityAxis;
this.authorityAxis = this.axisCbox.selected;
}
return this.browse.loadAuthorities();
- }
+ };
this.cellTextGenerator = {
heading: row => row.heading
- }
+ };
this.rowFlairCallback = (row: any): GridRowFlairEntry => {
const flair = {icon: null, title: null};
flair.title = this.rowSelected.text;
}
return flair;
- }
+ };
}
markForMerge(rows: any[]) {
rows.forEach(row =>
- this.browse.markedForMerge[row.authority.id()] = true);
+ this.browse.markedForMerge[row.authority.id()] = row);
}
unMarkForMerge(rows: any[]) {
}
this.grid.reload();
}
+
+ openMergeDialog() {
+ const rows = Object.values(this.browse.markedForMerge);
+ if (rows.length > 0) {
+ this.mergeDialog.authData = rows;
+ this.mergeDialog.open({size: 'lg'}).subscribe(success => {
+ if (success) {
+ this.clearMergeSelection();
+ this.search();
+ }
+ });
+ }
+ }
}
-<eg-staff-banner bannerText="Manage Authority Record #{{authId}}" i18n-bannerText>
+<eg-staff-banner bannerText="#{{authId}} {{authMeta ? authMeta.heading : ''}}" i18n-bannerText>
</eg-staff-banner>
<div class="row mb-2">
<ngb-tab title="Linked Bibs" i18n-title id="bibs">
<ng-template ngbTabContent>
<div class="mt-3" *ngIf="authMeta">
- <eg-bib-list #bibList [bibIds]="authMeta.linked_bibs"></eg-bib-list>
+ <eg-bib-list #bibList [bibIds]="authMeta.linked_bibs"
+ gridPersistKey="cat.authority.manage.bibs"></eg-bib-list>
</div>
</ng-template>
</ngb-tab>
--- /dev/null
+
+<eg-string #successMsg
+ text="Successfully Merged Authority Records" i18n-text></eg-string>
+<eg-string #errorMsg
+ text="Failed To Merge Authority Records" i18n-text></eg-string>
+
+<ng-template #dialogContent>
+ <div class="modal-header bg-info">
+ <h4 class="modal-title">
+ <span i18n>Merge Authority Records</span>
+ </h4>
+ <button type="button" class="close"
+ i18n-aria-label aria-label="Close" (click)="close()">
+ <span aria-hidden="true">×</span>
+ </button>
+ </div>
+ <div class="modal-body">
+ <div class="row d-flex justify-content-center">
+ <h5>Merge {{authData.length}} Records?</h5>
+ </div>
+ <div class="row">
+ <div class="col-lg-2" i18n>Lead Record</div>
+ </div>
+ <div class="row" *ngFor="let data of authData">
+ <div class="col-lg-2">
+ <input type="radio" name="leadRecord"
+ [value]="data.authority.id()" [(ngModel)]="leadRecord"/>
+ </div>
+ <div class="col-lg-1">#{{data.authority.id()}}</div>
+ <div class="col-lg-6">{{data.heading}}</div>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <ng-container *ngIf="!chargeResponse">
+ <button type="button" class="btn btn-warning"
+ (click)="close()" i18n>Cancel</button>
+ <button type="button" class="btn btn-success"
+ (click)="merge()" i18n>Merge Records</button>
+ </ng-container>
+ </div>
+</ng-template>
+
--- /dev/null
+import {Component, OnInit, Input, ViewChild} from '@angular/core';
+import {NetService} from '@eg/core/net.service';
+import {EventService} from '@eg/core/event.service';
+import {ToastService} from '@eg/share/toast/toast.service';
+import {AuthService} from '@eg/core/auth.service';
+import {DialogComponent} from '@eg/share/dialog/dialog.component';
+import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
+import {StringComponent} from '@eg/share/string/string.component';
+
+/**
+ * Dialog for merging authority records.
+ */
+
+@Component({
+ selector: 'eg-authority-merge-dialog',
+ templateUrl: 'merge-dialog.component.html'
+})
+
+export class AuthorityMergeDialogComponent
+ extends DialogComponent implements OnInit {
+
+ // Rows passed from the authority browse grid.
+ @Input() authData: any[] = [];
+
+ leadRecord: number;
+
+ @ViewChild('successMsg', {static: true})
+ private successMsg: StringComponent;
+
+ @ViewChild('errorMsg', {static: true})
+ private errorMsg: StringComponent;
+
+ constructor(
+ private modal: NgbModal, // required for passing to parent
+ private toast: ToastService,
+ private net: NetService,
+ private evt: EventService,
+ private auth: AuthService) {
+ super(modal); // required for subclassing
+ }
+
+ ngOnInit() {
+ this.onOpen$.subscribe(_ => {
+ if (this.authData.length > 0) {
+ this.leadRecord = this.authData[0].authority.id();
+ }
+ });
+ }
+
+ merge() {
+
+ const list = this.authData
+ .map(data => data.authority.id())
+ .filter(id => id !== this.leadRecord);
+
+ this.net.request('open-ils.cat',
+ 'open-ils.cat.authority.records.merge',
+ this.auth.token(), this.leadRecord, list)
+ .subscribe(resp => {
+ const evt = this.evt.parse(resp);
+
+ if (evt) {
+ this.errorMsg.current().then(str => this.toast.warning(str));
+ this.close(false);
+ } else {
+ this.successMsg.current().then(str => this.toast.success(str));
+ this.close(true);
+ }
+ });
+ }
+}
+
+
+
}
return empty();
- }
+ };
this.cellTextGenerator = {
title: row => row.title