<eg-staff-banner bannerText="MARC Batch Edit" i18n-bannerText></eg-staff-banner>
<div class="row">
- <div class="col-lg-7">
+ <div class="col-lg-7 common-form striped-odd">
<ng-container *ngFor="let rule of templateRules; let idx = index">
<hr *ngIf="idx > 0"/>
<div class="row mb-2">
<div class="row mb-2">
<div class="col-lg-3" i18n>Action (Rule Type)</div>
<div class="col-lg-3">
- <select class="form-control" [(ngModel)]="rule.ruleType">
- <option value='replace' i18n>Replace</option>
- <option value='add' i18n>Add</option>
- <option value='delete' i18n>Delete</option>
+ <select class="form-control" [(ngModel)]="rule.ruleType"
+ (change)="rulesetToRecord()">
+ <option value='r' i18n>Replace</option>
+ <option value='a' i18n>Add</option>
+ <option value='d' i18n>Delete</option>
</select>
</div>
<div class="col-lg-6" i18n>How to change the existing record.</div>
<div class="row mb-2">
<div class="col-lg-3" i18n>MARC Tag</div>
<div class="col-lg-3">
- <input type="text" class="form-control" [(ngModel)]="rule.marcTag"/>
+ <input type="text" class="form-control"
+ (change)="rulesetToRecord(true)" [(ngModel)]="rule.marcTag"/>
</div>
<div class="col-lg-6" i18n>
Three characters, no spaces, no indicators, etc. eg: 245
<div class="row mb-2">
<div class="col-lg-3" i18n>Subfields (optional)</div>
<div class="col-lg-3">
- <input type="text" class="form-control" [(ngModel)]="rule.marcSubfields"/>
+ <input type="text" class="form-control"
+ (change)="rulesetToRecord(true)" [(ngModel)]="rule.marcSubfields"/>
</div>
<div class="col-lg-6" i18n>No spaces, no delimiters, eg: abcnp</div>
</div>
<div class="row mb-2">
<div class="col-lg-3" i18n>MARC Data</div>
<div class="col-lg-3">
- <input type="text" class="form-control" [(ngModel)]="rule.marcData"/>
+ <input type="text" class="form-control"
+ (change)="rulesetToRecord()" [(ngModel)]="rule.marcData"/>
</div>
<div class="col-lg-6" i18n>
MARC-Breaker formatted data with indicators and subfield delimiters,
</div>
<div class="row mb-2">
<div class="col-lg-3" i18n>Subfield</div>
- <div class="col-lg-3"></div>
- <div class="col-lg-6" i18n></div>
+ <div class="col-lg-3">
+ <input type="text" class="form-control"
+ (change)="rulesetToRecord()" [(ngModel)]="rule.advSubfield"/>
+ </div>
+ <div class="col-lg-6" i18n>
+ A single subfield code, no delimiters, eg: a
+ </div>
</div>
<div class="row mb-2">
<div class="col-lg-3" i18n>Expression</div>
- <div class="col-lg-3"></div>
- <div class="col-lg-6" i18n></div>
+ <div class="col-lg-3">
+ <input type="text" class="form-control"
+ (change)="rulesetToRecord()" [(ngModel)]="rule.advRegex"/>
+ </div>
+ <div class="col-lg-6" i18n>
+ See the
+ <a href="https://perldoc.perl.org/perlre.html#Regular-Expressions">
+ Perl documentation
+ </a> for an explanation of Regular Expressions.
+ </div>
+ </div>
+ <div class="row mb-2">
+ <div class="col-lg-12 d-flex justify-content-end">
+ <button class="btn btn-outline-danger label-with-material-icon"
+ (click)="removeRule(idx)" i18n>
+ <span>Remove this Template Rule</span>
+ <span class="material-icons ml-2">delete</span>
+ </button>
+ </div>
</div>
</ng-container>
+ <div class="row mb-2">
+ <div class="col-lg-6">
+ <button class="btn btn-outline-dark label-with-material-icon"
+ (click)="addRule()">
+ <span i18n>Add a New Merge Rule</span>
+ <span class="material-icons ml-2">arrow_downward</span>
+ </button>
+ </div>
+ </div>
</div>
<div class="col-lg-5">
<div class="row pb-2 pt-2 border">
<div class="col-lg-12">
<div i18n>Update Template Preview</div>
<div>
- <textarea class="form-control" [(ngModel)]="templateBreaker" disabled>
- </textarea>
+ <textarea class="form-control" [ngModel]="breaker()"
+ disabled rows="{{breakerRows()}}"></textarea>
</div>
</div>
</div>
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';
interface TemplateRule {
- ruleType: 'replace' | 'add' | 'delete';
+ ruleType: 'r' | 'a' | 'd';
marcTag?: string;
marcSubfields?: string;
marcData?: string;
csvColumn = 0;
selectedFile: File;
xactPerRecord = false;
- templateBreaker = '';
templateRules: TemplateRule[] = [];
+ record: MarcRecord;
constructor(
private router: Router,
}
load() {
- this.templateRules = [{ruleType: 'replace'}];
+ this.addRule();
this.getBuckets();
}
+ rulesetToRecord(resetRuleData?: boolean) {
+ this.record = new MarcRecord();
+
+ this.templateRules.forEach(rule => {
+
+ let ruleText = rule.marcTag + (rule.marcSubfields || '');
+ if (rule.advSubfield) {
+ ruleText += `[${rule.advSubfield} ~ ${rule.advRegex}]`;
+ }
+
+ // Merge behavior is encoded in the 905 field.
+ const ruleTag = this.record.newField({
+ tag: '905',
+ ind1: ' ',
+ ind2: ' ',
+ subfields: [[rule.ruleType, ruleText, 0]]
+ });
+
+ this.record.insertOrderedFields(ruleTag);
+
+ if (rule.ruleType === 'd') { return; }
+
+ const dataRec = new MarcRecord();
+ if (resetRuleData) {
+
+ // Build a new value for the 'MARC Data' field based on
+ // changes to the selected tag or subfields.
+
+ const subfields = rule.marcSubfields ?
+ rule.marcSubfields.split('').map((sf, idx) => [sf, '', idx])
+ : [];
+
+ dataRec.appendFields(
+ dataRec.newField({
+ tag: rule.marcTag,
+ ind1: ' ',
+ ind2: ' ',
+ subfields: subfields
+ })
+ );
+
+ console.log(dataRec.toBreaker());
+ rule.marcData = dataRec.toBreaker().split(/\n/)[1];
+
+ } else {
+
+ // Absorb the breaker data already in the 'MARC Data' field
+ // so it can be added to the template record in progress.
+
+ dataRec.breakerText = rule.marcData;
+ dataRec.absorbBreakerChanges();
+ }
+
+ this.record.appendFields(dataRec.fields[0]);
+ });
+ }
+
+ breakerRows(): number {
+ if (this.record) {
+ const breaker = this.record.toBreaker();
+ if (breaker) {
+ return breaker.split(/\n/).length + 1;
+ }
+ }
+ return 3;
+ }
+
+ breaker(): string {
+ return this.record ? this.record.toBreaker() : '';
+ }
+
+ addRule() {
+ this.templateRules.push({ruleType: 'r'});
+ }
+
+ removeRule(idx: number) {
+ this.templateRules.splice(idx, 1);
+ }
+
getBuckets(): Promise<any> {
if (this.buckets) { return Promise.resolve(); }