<class id="mmr" controller="open-ils.cstore open-ils.pcrud" oils_obj:fieldmapper="metabib::metarecord" oils_persist:tablename="metabib.metarecord" reporter:label="Metarecord">
<fields oils_persist:primary="id" oils_persist:sequence="metabib.metarecord_id_seq">
<field name="fingerprint" reporter:datatype="text"/>
- <field name="id" reporter:datatype="id" />
+ <field name="id" reporter:datatype="id" reporter:selector="fingerprint" />
<field name="master_record" reporter:datatype="link"/>
<field name="mods" reporter:datatype="text"/>
<field name="source_records" oils_persist:virtual="true" reporter:datatype="link"/>
if (!params.idlClass || !params.idlField) {
// Without a full accounting of the field data,
- // we can't determine the display value.
+ // we can't determine the linked selector field.
return value + '';
}
- const localClass = this.idl.classes[params.idlClass];
+ const selector =
+ this.idl.getLinkSelector(params.idlClass, params.idlField);
- if (!localClass) {
- console.warn(`No such IDL class ${params.idlClass}`);
- return value + '';
- }
+ if (selector && typeof value[selector] === 'function') {
+ const val = value[selector]();
- if (!localClass.field_map[params.idlField]) {
- console.warn(`IDL class ${params.idlClass} ` +
- `has no field named "${params.idlField}"`);
- return value + '';
- }
+ if (Array.isArray(val)) {
+ // Typically has_many links will not be fleshed,
+ // but in the off-chance the are, avoid displaying
+ // an array reference value.
+ return '';
+ } else {
+ return val + '';
+ }
- const linkType = localClass.field_map[params.idlField]['reltype'];
- if (linkType !== 'has_a') {
- return value + ''; // eh?
+ } else {
+ return value + '';
}
- const localField = localClass.field_map[params.idlField];
- const remoteKey = localField['key'];
-
- const remoteClass = this.idl.classes[localField['class']];
- const remoteField = remoteClass.field_map[remoteKey];
- const remoteSelector = remoteField.selector || remoteField.name;
-
- return value[remoteSelector]() + '';
-
case 'org_unit':
const orgField = params.orgField || 'shortname';
const org = this.org.get(value);
// on the linked class that acts as the selector for the linked class.
// Returns null if no selector is found or the field is not a link.
getLinkSelector(fmClass: string, field: string): string {
- const fieldDef = this.classes[fmClass].field_map[field];
+ let fieldDef = this.classes[fmClass].field_map[field];
+
+ if (fieldDef.map) {
+ // For mapped fields, we want the selector field on the
+ // remotely linked object instead of the directly
+ // linked object.
+ const linkedClass = this.classes[fieldDef.class];
+ fieldDef = linkedClass.field_map[fieldDef.map];
+ }
+
if (fieldDef.class) {
const classDef = this.classes[fieldDef.class];
if (classDef.pkey) {
}
this.idl.classes[fmClass].fields
- .filter(f =>
+ .filter(f =>
f.datatype === 'link' && (
- f.reltype === 'has_a' || f.reltype === 'might_have'
+ f.reltype === 'has_a' || f.reltype === 'might_have'
)
).forEach(field => {
+
const selector = this.idl.getLinkSelector(fmClass, field.name);
if (!selector) { return; }
+ if (field.map) {
+ // For mapped fields, we only want to auto-flesh them
+ // if both steps along the path are single-row fleshers.
+
+ const mapClass = field['class'];
+ const mapField = field.map;
+ const def = this.idl.classes[mapClass].field_map[mapField];
+
+ if (!(def.reltype === 'has_a' ||
+ def.reltype === 'might_have')) {
+ // Field maps to a remote field which may contain
+ // multiple rows. Skip it.
+ return;
+ }
+ }
+
if (!pcrudOps.flesh_fields[fmClass]) {
pcrudOps.flesh_fields[fmClass] = [];
}
<br/><br/>
+<h4>PCRUD auto flesh and FormatService detection</h4>
+<div *ngIf="aMetarecord">Fingerprint: {{aMetarecord}}</div>
import {DateSelectComponent} from '@eg/share/date-select/date-select.component';
import {PrintService} from '@eg/share/print/print.service';
import {ComboboxEntry} from '@eg/share/combobox/combobox.component';
+import {FormatService} from '@eg/core/format.service';
@Component({
templateUrl: 'sandbox.component.html'
complimentEvergreen: (rows: IdlObject[]) => void;
notOneSelectedRow: (rows: IdlObject[]) => boolean;
+ // selector field value on metarecord object
+ aMetarecord: string;
+
constructor(
private idl: IdlService,
private org: OrgService,
private pcrud: PcrudService,
private strings: StringService,
private toast: ToastService,
+ private format: FormatService,
private printer: PrintService
) {
}
this.complimentEvergreen = (rows: IdlObject[]) => alert('Evergreen is great!');
this.notOneSelectedRow = (rows: IdlObject[]) => (rows.length !== 1);
+
+ this.pcrud.retrieve('bre', 1, {}, {fleshSelectors: true})
+ .subscribe(bib => {
+ // Format service will automatically find the selector
+ // value to display from our fleshed metarecord field.
+ this.aMetarecord = this.format.transform({
+ value: bib.metarecord(),
+ idlClass: 'bre',
+ idlField: 'metarecord'
+ });
+ });
}
btGridRowClassCallback(row: any): string {