<div class="common-form striped-odd form-validated ml-3 mr-3">
<div class="row">
<div class="col-lg-3">
+ <label i18n>Apply/Create Form Template</label>
+ </div>
+ <div class="col-lg-3">
+ <eg-combobox #formTemplateSelector
+ (onChange)="templateSelectorChange($event)"
+ [allowFreeText]="true"
+ [startId]="selectedTemplate"
+ [startIdFiresOnChange]="true"
+ [entries]="formatTemplateEntries()"
+ placeholder="Apply or Create Form Template..." i18n-placeholder>
+ </eg-combobox>
+ </div>
+ <div class="col-lg-6">
+ <button class="btn btn-success"
+ [disabled]="!selectedTemplate"
+ (click)="saveTemplate()" i18n>Save As New Template</button>
+ <button class="btn btn-outline-primary ml-3"
+ [disabled]="!selectedTemplate"
+ (click)="markTemplateDefault()" i18n>Mark Template as Default</button>
+ <button class="btn btn-danger ml-3"
+ [disabled]="!selectedTemplate"
+ (click)="deleteTemplate()" i18n>Delete Template</button>
+ </div>
+ </div>
+
+ <div class="row">
+ <div class="col-lg-3">
<label i18n>Record Type</label>
</div>
<div class="col-lg-3">
- <eg-combobox (onChange)="selectEntry($event, 'recordType')"
- [disabled]="importSelection()"
- [required]="true"
+ <eg-combobox #recordTypeSelector
+ (onChange)="selectEntry($event, 'recordType')"
+ [disabled]="importSelection()" [required]="true"
[startId]="recordType" placeholder="Record Type..." i18n-placeholder>
<eg-combobox-entry entryId="bib" entryLabel="Bibliographic Records"
i18n-entryLabel></eg-combobox-entry>
<label i18n>Select a Record Source</label>
</div>
<div class="col-lg-3">
- <eg-combobox [entries]="formatEntries('bibSources')"
+ <eg-combobox #bibSourceSelector
+ [entries]="formatEntries('bibSources')"
(onChange)="selectEntry($event, 'bibSources')"
[startId]="selectedBibSource"
placeholder="Record Source..." i18n-placeholder>
<label i18n>Record Match Set</label>
</div>
<div class="col-lg-3">
- <eg-combobox [entries]="formatEntries('matchSets')"
+ <eg-combobox #matchSetSelector
+ [entries]="formatEntries('matchSets')"
[disabled]="(selectedQueue && !selectedQueue.freetext) || importSelection()"
[startId]="selectedMatchSet || defaultMatchSet"
(onChange)="selectEntry($event, 'matchSets')"
<label i18n>Holdings Import Profile</label>
</div>
<div class="col-lg-3"> <!-- TODO disable for authority -->
- <eg-combobox [entries]="formatEntries('importItemDefs')"
+ <eg-combobox #holdingsProfileSelector
+ [entries]="formatEntries('importItemDefs')"
[startId]="selectedHoldingsProfile"
[disabled]="(selectedQueue && !selectedQueue.freetext) || importSelection()"
(onChange)="selectEntry($event, 'importItemDefs')"
<label i18n>Merge Profile</label>
</div>
<div class="col-lg-3">
- <eg-combobox [entries]="formatEntries('mergeProfiles')"
+ <eg-combobox #mergeProfileSelector
+ [entries]="formatEntries('mergeProfiles')"
(onChange)="selectEntry($event, 'mergeProfiles')"
placeholder="Merge Profile..." i18n-placeholder>
</eg-combobox>
<div class="col-lg-3">
<label i18n>Insufficient Quality Fall-Through Profile</label></div>
<div class="col-lg-3">
- <eg-combobox [entries]="formatEntries('mergeProfiles')"
+ <eg-combobox #fallThruMergeProfileSelector
+ [entries]="formatEntries('mergeProfiles')"
(onChange)="selectEntry($event, 'FallThruMergeProfile')"
placeholder="Fall-Through Merge Profile..." i18n-placeholder>
</eg-combobox>
import {OrgService} from '@eg/core/org.service';
import {AuthService} from '@eg/core/auth.service';
import {ToastService} from '@eg/share/toast/toast.service';
-import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
+import {ComboboxComponent,
+ ComboboxEntry} from '@eg/share/combobox/combobox.component';
import {VandelayService, VandelayImportSelection,
VANDELAY_UPLOAD_PATH} from './vandelay.service';
import {HttpClient, HttpRequest, HttpEventType} from '@angular/common/http';
import {HttpResponse, HttpErrorResponse} from '@angular/common/http';
import {ProgressInlineComponent} from '@eg/share/dialog/progress-inline.component';
import {Subject} from 'rxjs/Subject';
+import {ServerStoreService} from '@eg/core/server-store.service';
+
+const TEMPLATE_SETTING_NAME = 'eg.cat.vandelay.import.templates';
+
+const TEMPLATE_ATTRS = [
+ 'recordType',
+ 'selectedBibSource',
+ 'selectedMatchSet',
+ 'mergeOnExact',
+ 'importNonMatch',
+ 'mergeOnBestMatch',
+ 'mergeOnSingleMatch',
+ 'autoOverlayAcqCopies',
+ 'selectedHoldingsProfile',
+ 'selectedMergeProfile',
+ 'selectedFallThruMergeProfile',
+ 'selectedTrashGroups',
+ 'minQualityRatio'
+];
interface ImportOptions {
session_key: string;
merge_profile?: any;
fall_through_merge_profile?: any;
strip_field_groups?: number[];
+ match_quality_ratio: number,
exit_early: boolean;
}
// Optional enqueue/import tracker session name.
sessionName: string;
+ selectedTemplate: string;
+ formTemplates: {[name: string]: any};
+ newTemplateName: string;
+
@ViewChild('fileSelector') private fileSelector;
@ViewChild('uploadProgress')
private uploadProgress: ProgressInlineComponent;
@ViewChild('importProgress')
private importProgress: ProgressInlineComponent;
+ // Need these refs so values can be applied via external stimuli
+ @ViewChild('formTemplateSelector')
+ private formTemplateSelector: ComboboxComponent;
+ @ViewChild('recordTypeSelector')
+ private recordTypeSelector: ComboboxComponent;
+ @ViewChild('bibSourceSelector')
+ private bibSourceSelector: ComboboxComponent;
+ @ViewChild('matchSetSelector')
+ private matchSetSelector: ComboboxComponent;
+ @ViewChild('holdingsProfileSelector')
+ private holdingsProfileSelector: ComboboxComponent;
+ @ViewChild('mergeProfileSelector')
+ private mergeProfileSelector: ComboboxComponent;
+ @ViewChild('fallThruMergeProfileSelector')
+ private fallThruMergeProfileSelector: ComboboxComponent;
+
constructor(
private http: HttpClient,
private toast: ToastService,
private net: NetService,
private auth: AuthService,
private org: OrgService,
+ private store: ServerStoreService,
private vandelay: VandelayService
) {
this.applyDefaults();
this.selectedBibSource = 1; // default to system local
this.recordType = 'bib';
this.bibTrashGroups = [];
+ this.formTemplates = {};
if (this.vandelay.importSelection) {
this.vandelay.getBibTrashGroups().then(
groups => this.bibTrashGroups = groups),
this.org.settings(['vandelay.default_match_set']).then(
- s => this.defaultMatchSet = s['vandelay.default_match_set'])
+ s => this.defaultMatchSet = s['vandelay.default_match_set']),
+ this.loadTemplates()
];
return Promise.all(promises);
}
+ loadTemplates() {
+ this.store.getItem(TEMPLATE_SETTING_NAME).then(
+ templates => {
+ this.formTemplates = templates || {};
+
+ Object.keys(this.formTemplates).forEach(name => {
+ if (this.formTemplates[name].default) {
+ this.selectedTemplate = name;
+ }
+ });
+ }
+ );
+ }
+
+ formatTemplateEntries(): ComboboxEntry[] {
+ const entries = [];
+
+ Object.keys(this.formTemplates || {}).forEach(
+ name => entries.push({id: name, label: name}));
+
+ return entries;
+ }
+
// Format typeahead data sets
formatEntries(etype: string): ComboboxEntry[] {
const rtype = this.recordType;
merge_profile: this.selectedMergeProfile,
fall_through_merge_profile: this.selectedFallThruMergeProfile,
strip_field_groups: this.selectedTrashGroups,
+ match_quality_ratio: this.minQualityRatio,
exit_early: true
};
openQueue() {
console.log('opening queue ' + this.activeQueueId);
}
+
+ saveTemplate() {
+
+ const template = {};
+ TEMPLATE_ATTRS.forEach(key => template[key] = this[key]);
+
+ console.debug("Saving import profile", template);
+
+ this.formTemplates[this.selectedTemplate] = template;
+ return this.store.setItem(TEMPLATE_SETTING_NAME, this.formTemplates);
+ }
+
+ markTemplateDefault() {
+
+ Object.keys(this.formTemplates).forEach(
+ name => delete this.formTemplates.default
+ );
+
+ this.formTemplates[this.selectedTemplate].default = true;
+
+ return this.store.setItem(TEMPLATE_SETTING_NAME, this.formTemplates);
+ }
+
+ templateSelectorChange(entry: ComboboxEntry) {
+
+ if (!entry) {
+ this.selectedTemplate = '';
+ return;
+ }
+
+ this.selectedTemplate = entry.label; // label == name
+
+ if (entry.freetext) {
+ // User is entering a new template name.
+ // Nothing to apply.
+ return;
+ }
+
+ // User selected an existing template, apply it to the form.
+
+ const template = this.formTemplates[entry.id];
+
+ // Copy the template values into "this"
+ TEMPLATE_ATTRS.forEach(key => this[key] = template[key]);
+
+ // Some values must be manually passed to the combobox'es
+
+ this.recordTypeSelector.applyEntryId(this.recordType);
+ this.bibSourceSelector.applyEntryId(this.selectedBibSource);
+ this.matchSetSelector.applyEntryId(this.selectedMatchSet);
+ this.holdingsProfileSelector
+ .applyEntryId(this.selectedHoldingsProfile);
+ this.mergeProfileSelector.applyEntryId(this.selectedMergeProfile);
+ this.fallThruMergeProfileSelector
+ .applyEntryId(this.selectedFallThruMergeProfile);
+ }
+
+ deleteTemplate() {
+ delete this.formTemplates[this.selectedTemplate];
+ this.formTemplateSelector.selected = null;
+ return this.store.setItem(TEMPLATE_SETTING_NAME, this.formTemplates);
+ }
}