[open-ils-commits] [GIT] Evergreen ILS branch master updated. 1db81cf40bd5b1f227db9efe3072e6ecbc3bd26c

Evergreen Git git at git.evergreen-ils.org
Fri Mar 22 17:01:52 EDT 2019


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Evergreen ILS".

The branch, master has been updated
       via  1db81cf40bd5b1f227db9efe3072e6ecbc3bd26c (commit)
       via  d26ece239b3e0b703b44bc0f6b23711d4daf9fb4 (commit)
       via  2fe42126c7a7a2f0f30b70a6eef1ee4f562feb2d (commit)
       via  8480ca2446a3c73e505a59f755a19cc4dd30731b (commit)
      from  0e18c2fe13b72c9b91f9b4dbcaf883c70cae2d4b (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 1db81cf40bd5b1f227db9efe3072e6ecbc3bd26c
Author: Bill Erickson <berickxx at gmail.com>
Date:   Fri Mar 8 13:16:35 2019 -0500

    LP1819179 PCRUD selector fleshing handles maps
    
    Teach the PCUD selector fleshing code to handle selector fields on
    mapped classes, where an intermediate object flesh is performed by pcrud
    at flesh time.
    
    Adds a 'selector' column on metabib.metarecord in the IDL so that we can
    have a functioning example of this to use in the sandbox test code.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Dan Wells <dbw2 at calvin.edu>

diff --git a/Open-ILS/examples/fm_IDL.xml b/Open-ILS/examples/fm_IDL.xml
index db651878bd..1f510735fb 100644
--- a/Open-ILS/examples/fm_IDL.xml
+++ b/Open-ILS/examples/fm_IDL.xml
@@ -3934,7 +3934,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 	<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"/>
diff --git a/Open-ILS/src/eg2/src/app/core/format.service.ts b/Open-ILS/src/eg2/src/app/core/format.service.ts
index ad7e9ce180..e788cd0e40 100644
--- a/Open-ILS/src/eg2/src/app/core/format.service.ts
+++ b/Open-ILS/src/eg2/src/app/core/format.service.ts
@@ -78,37 +78,29 @@ export class FormatService {
 
                 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);
diff --git a/Open-ILS/src/eg2/src/app/core/idl.service.ts b/Open-ILS/src/eg2/src/app/core/idl.service.ts
index b6f8173159..56b8b90e1f 100644
--- a/Open-ILS/src/eg2/src/app/core/idl.service.ts
+++ b/Open-ILS/src/eg2/src/app/core/idl.service.ts
@@ -138,7 +138,16 @@ export class IdlService {
     // 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) {
diff --git a/Open-ILS/src/eg2/src/app/core/pcrud.service.ts b/Open-ILS/src/eg2/src/app/core/pcrud.service.ts
index b3d4288a53..9e14191c0f 100644
--- a/Open-ILS/src/eg2/src/app/core/pcrud.service.ts
+++ b/Open-ILS/src/eg2/src/app/core/pcrud.service.ts
@@ -104,14 +104,31 @@ export class PcrudContext {
         }
 
         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] = [];
             }
diff --git a/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html b/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html
index 00c2ee7397..5f1f1ad0bf 100644
--- a/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html
+++ b/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.html
@@ -147,4 +147,6 @@
 
 <br/><br/>
 
+<h4>PCRUD auto flesh and FormatService detection</h4>
+<div *ngIf="aMetarecord">Fingerprint: {{aMetarecord}}</div>
 
diff --git a/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts b/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts
index ed2c496257..4ee4ebc0f7 100644
--- a/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts
+++ b/Open-ILS/src/eg2/src/app/staff/sandbox/sandbox.component.ts
@@ -13,6 +13,7 @@ import {Pager} from '@eg/share/util/pager';
 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'
@@ -58,12 +59,16 @@ export class SandboxComponent implements OnInit {
     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
     ) {
     }
@@ -114,6 +119,17 @@ export class SandboxComponent implements OnInit {
 
         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 {

commit d26ece239b3e0b703b44bc0f6b23711d4daf9fb4
Author: Bill Erickson <berickxx at gmail.com>
Date:   Fri Mar 8 12:30:26 2019 -0500

    LP1819179 IDL2js includes 'map' attribute data
    
    Patch from Mike Rylander to teach the IDL2js generator to include 'map'
    attributes, which allow JS clients to step through mapped, linked
    fields, particuarly useful for auto-fleshing these fields.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Dan Wells <dbw2 at calvin.edu>

diff --git a/Open-ILS/src/eg2/src/app/core/pcrud.service.ts b/Open-ILS/src/eg2/src/app/core/pcrud.service.ts
index f023b6d2f5..b3d4288a53 100644
--- a/Open-ILS/src/eg2/src/app/core/pcrud.service.ts
+++ b/Open-ILS/src/eg2/src/app/core/pcrud.service.ts
@@ -104,8 +104,11 @@ export class PcrudContext {
         }
 
         this.idl.classes[fmClass].fields
-        .filter(f => f.datatype === 'link' && !f.virtual)
-        .forEach(field => {
+        .filter(f => 
+            f.datatype === 'link' && (
+                f.reltype === 'has_a' || f.reltype === 'might_have'    
+            )
+        ).forEach(field => {
             const selector = this.idl.getLinkSelector(fmClass, field.name);
             if (!selector) { return; }
 
diff --git a/Open-ILS/xsl/fm_IDL2js.xsl b/Open-ILS/xsl/fm_IDL2js.xsl
index 6c7709f811..aeb4573f48 100644
--- a/Open-ILS/xsl/fm_IDL2js.xsl
+++ b/Open-ILS/xsl/fm_IDL2js.xsl
@@ -58,7 +58,7 @@ for (var c in _preload_fieldmapper_IDL) {
     <xsl:if test="$f/../../idl:links/idl:link[@field=$f/@name]">type:"link",<xsl:apply-templates select="$f/../../idl:links/idl:link[@field=$f/@name]"></xsl:apply-templates>,</xsl:if>
 </xsl:template>
 
-<xsl:template match="idl:link">key:"<xsl:value-of select="@key"/>","class":"<xsl:value-of select="@class"/>",reltype:"<xsl:value-of select="@reltype"/>"</xsl:template>
+<xsl:template match="idl:link"><xsl:if test="@map != ''">map:"<xsl:value-of select="@map"/>",</xsl:if>key:"<xsl:value-of select="@key"/>","class":"<xsl:value-of select="@class"/>",reltype:"<xsl:value-of select="@reltype"/>"</xsl:template>
 
 <xsl:template name="trueFalse">
     <xsl:param name="tf"/>

commit 2fe42126c7a7a2f0f30b70a6eef1ee4f562feb2d
Author: Bill Erickson <berickxx at gmail.com>
Date:   Wed Mar 6 17:41:25 2019 -0500

    LP#1819179: Angular value formatter gets link smarts
    
    Teach the FormatService to display selector values for linked objects
    when the requested field is a link field and it contains an object value
    instead of just a id/key value.
    
    Improve IDL data passing from the grid to the IDL service so it can
    better determine which fields are avialble for link selector display.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Mike Rylander <mrylander at gmail.com>
    Signed-off-by: Dan Wells <dbw2 at calvin.edu>

diff --git a/Open-ILS/src/eg2/src/app/core/format.service.ts b/Open-ILS/src/eg2/src/app/core/format.service.ts
index 2c7e3885d9..ad7e9ce180 100644
--- a/Open-ILS/src/eg2/src/app/core/format.service.ts
+++ b/Open-ILS/src/eg2/src/app/core/format.service.ts
@@ -71,6 +71,44 @@ export class FormatService {
 
         switch (datatype) {
 
+            case 'link':
+                if (typeof value !== 'object') {
+                    return value + ''; // no fleshed value here
+                }
+
+                if (!params.idlClass || !params.idlField) {
+                    // Without a full accounting of the field data,
+                    // we can't determine the display value.
+                    return value + '';
+                }
+
+                const localClass = this.idl.classes[params.idlClass];
+
+                if (!localClass) {
+                    console.warn(`No such IDL class ${params.idlClass}`);
+                    return value + '';
+                }
+
+                if (!localClass.field_map[params.idlField]) {
+                    console.warn(`IDL class ${params.idlClass} ` +
+                        `has no field named "${params.idlField}"`);
+                    return value + '';
+                }
+
+                const linkType = localClass.field_map[params.idlField]['reltype'];
+                if (linkType !== 'has_a') {
+                    return value + ''; // eh?
+                }
+
+                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);
diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid.ts b/Open-ILS/src/eg2/src/app/share/grid/grid.ts
index 16c5ea1279..3743488c39 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid.ts
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid.ts
@@ -20,6 +20,8 @@ export class GridColumn {
     hidden: boolean;
     visible: boolean;
     sort: number;
+    // IDL class of the object which contains this field.
+    // Not to be confused with the class of a linked object.
     idlClass: string;
     idlFieldDef: any;
     datatype: string;
@@ -189,6 +191,7 @@ export class GridColumnSet {
             const idlInfo = this.idlInfoFromDotpath(col.path);
             if (idlInfo) {
                 col.idlFieldDef = idlInfo.idlField;
+                col.idlClass = idlInfo.idlClass.name;
                 if (!col.label) {
                     col.label = col.idlFieldDef.label || col.idlFieldDef.name;
                     col.datatype = col.idlFieldDef.datatype;
@@ -634,6 +637,8 @@ export class GridContext {
 
         return this.format.transform({
             value: val,
+            idlClass: col.idlClass,
+            idlField: col.idlFieldDef ? col.idlFieldDef.name : col.name,
             datatype: col.datatype,
             datePlusTime: Boolean(col.datePlusTime)
         });
@@ -682,6 +687,12 @@ export class GridContext {
             if (!col.datatype) {
                 col.datatype = idlField.datatype;
             }
+            if (!col.idlFieldDef) {
+                idlField = col.idlFieldDef;
+            }
+            if (!col.idlClass) {
+                col.idlClass = idlClassDef.name;
+            }
             if (!col.label) {
                 col.label = idlField.label || idlField.name;
             }
@@ -858,6 +869,7 @@ export class GridContext {
             col.name = field.name;
             col.label = field.label || field.name;
             col.idlFieldDef = field;
+            col.idlClass = this.columnSet.idlClass;
             col.datatype = field.datatype;
             col.isIndex = (field.name === pkeyField);
             col.isAuto = true;

commit 8480ca2446a3c73e505a59f755a19cc4dd30731b
Author: Bill Erickson <berickxx at gmail.com>
Date:   Fri Jan 25 15:17:56 2019 -0500

    LP1812670 Angular grid shows selector labels
    
    * Teach PcrudService how to flesh link fields when a selector is defined
      on the linked class. This uses a new search/retrieve API flag
      {fleshSelectors:true}.
    
    * Teach the grid how to render selector values when configured to do so
      via a new grid component attribute [showLinkSelectors]="true".
    
    * Teach the Angular staff admin page to request linked selectors from
      pcrud and tell its grid to expect them.
    
    * Adds utility function to IdlServer for finding the selector for a
      given class + field.
    
    Signed-off-by: Bill Erickson <berickxx at gmail.com>
    Signed-off-by: Dan Wells <dbw2 at calvin.edu>

diff --git a/Open-ILS/src/eg2/src/app/core/idl.service.ts b/Open-ILS/src/eg2/src/app/core/idl.service.ts
index 89f8411de9..b6f8173159 100644
--- a/Open-ILS/src/eg2/src/app/core/idl.service.ts
+++ b/Open-ILS/src/eg2/src/app/core/idl.service.ts
@@ -133,5 +133,19 @@ export class IdlService {
 
         return result;
     }
+
+    // Given a field on an IDL class, returns the name of the field
+    // 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];
+        if (fieldDef.class) {
+            const classDef = this.classes[fieldDef.class];
+            if (classDef.pkey) {
+                return classDef.field_map[classDef.pkey].selector || null;
+            }
+        }
+        return null;
+    }
 }
 
diff --git a/Open-ILS/src/eg2/src/app/core/pcrud.service.ts b/Open-ILS/src/eg2/src/app/core/pcrud.service.ts
index fc79f30d09..f023b6d2f5 100644
--- a/Open-ILS/src/eg2/src/app/core/pcrud.service.ts
+++ b/Open-ILS/src/eg2/src/app/core/pcrud.service.ts
@@ -13,6 +13,10 @@ interface PcrudReqOps {
     anonymous?: boolean;
     idlist?: boolean;
     atomic?: boolean;
+    // If true, link-type fields which link to a class that defines a
+    // selector will be fleshed with the linked value.  This affects
+    // retrieve(), retrieveAll(), and search() calls.
+    fleshSelectors?: boolean;
 }
 
 // For for documentation purposes.
@@ -86,10 +90,42 @@ export class PcrudContext {
         this.session.disconnect();
     }
 
+    // Adds "flesh" logic to retrieve linked values for all fields
+    // that link to a class which defines a selector field.
+    applySelectorFleshing(fmClass: string, pcrudOps: any) {
+        pcrudOps = pcrudOps || {};
+
+        if (!pcrudOps.flesh) {
+            pcrudOps.flesh = 1;
+        }
+
+        if (!pcrudOps.flesh_fields) {
+            pcrudOps.flesh_fields = {};
+        }
+
+        this.idl.classes[fmClass].fields
+        .filter(f => f.datatype === 'link' && !f.virtual)
+        .forEach(field => {
+            const selector = this.idl.getLinkSelector(fmClass, field.name);
+            if (!selector) { return; }
+
+            if (!pcrudOps.flesh_fields[fmClass]) {
+                pcrudOps.flesh_fields[fmClass] = [];
+            }
+
+            if (pcrudOps.flesh_fields[fmClass].indexOf(field.name) < 0) {
+                pcrudOps.flesh_fields[fmClass].push(field.name);
+            }
+        });
+    }
+
     retrieve(fmClass: string, pkey: Number | string,
             pcrudOps?: any, reqOps?: PcrudReqOps): Observable<PcrudResponse> {
         reqOps = reqOps || {};
         this.authoritative = reqOps.authoritative || false;
+        if (reqOps.fleshSelectors) {
+            this.applySelectorFleshing(fmClass, pcrudOps);
+        }
         return this.dispatch(
             `open-ils.pcrud.retrieve.${fmClass}`,
              [this.token(reqOps), pkey, pcrudOps]);
@@ -112,6 +148,10 @@ export class PcrudContext {
 
         if (reqOps.atomic) { method += '.atomic'; }
 
+        if (reqOps.fleshSelectors) {
+            this.applySelectorFleshing(fmClass, pcrudOps);
+        }
+
         return this.dispatch(method, [this.token(reqOps), search, pcrudOps]);
     }
 
diff --git a/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.ts b/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.ts
index 17c0e46dd1..45dd167bb6 100644
--- a/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.ts
+++ b/Open-ILS/src/eg2/src/app/share/fm-editor/fm-editor.component.ts
@@ -273,9 +273,8 @@ export class FmRecordEditorComponent
                     // linked data so we can display the data within the selector
                     // field.  Otherwise, avoid the network lookup and let the
                     // bare value (usually an ID) be displayed.
-                    const idField = this.idl.classes[field.class].pkey;
                     const selector =
-                        this.idl.classes[field.class].field_map[idField].selector;
+                        this.idl.getLinkSelector(this.idlClass, field.name);
 
                     if (selector && selector !== field.name) {
                         promises.push(
diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid.component.ts b/Open-ILS/src/eg2/src/app/share/grid/grid.component.ts
index d48028b938..66686ef2e8 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid.component.ts
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid.component.ts
@@ -80,6 +80,20 @@ export class GridComponent implements OnInit, AfterViewInit, OnDestroy {
     // grid data.
     @Input() pageOffset: number;
 
+    // If true and an idlClass is specificed, the grid assumes
+    // datatype=link fields that link to classes which define a selector
+    // are fleshed with the linked object.  And, instead of displaying
+    // the raw field value, displays the selector value from the linked
+    // object.  The caller is responsible for fleshing the appropriate
+    // fields in the GridDataSource getRows handler.
+    //
+    // This only applies to auto-generated columns.
+    //
+    // For example, idlClass="aou" and field="ou_type", the display
+    // value will be ou_type().name() since "name" is the selector
+    // field on the "aout" class.
+    @Input() showLinkSelectors: boolean;
+
     context: GridContext;
 
     // These events are emitted from our grid-body component.
@@ -112,6 +126,7 @@ export class GridComponent implements OnInit, AfterViewInit, OnDestroy {
         this.context.isMultiSortable = this.multiSortable === true;
         this.context.useLocalSort = this.useLocalSort === true;
         this.context.disableSelect = this.disableSelect === true;
+        this.context.showLinkSelectors = this.showLinkSelectors === true;
         this.context.disableMultiSelect = this.disableMultiSelect === true;
         this.context.rowFlairIsEnabled = this.rowFlairIsEnabled  === true;
         this.context.rowFlairCallback = this.rowFlairCallback;
diff --git a/Open-ILS/src/eg2/src/app/share/grid/grid.ts b/Open-ILS/src/eg2/src/app/share/grid/grid.ts
index dcffc95143..16c5ea1279 100644
--- a/Open-ILS/src/eg2/src/app/share/grid/grid.ts
+++ b/Open-ILS/src/eg2/src/app/share/grid/grid.ts
@@ -437,6 +437,7 @@ export class GridContext {
     defaultVisibleFields: string[];
     defaultHiddenFields: string[];
     overflowCells: boolean;
+    showLinkSelectors: boolean;
 
     // Services injected by our grid component
     idl: IdlService;
@@ -624,12 +625,11 @@ export class GridContext {
 
     getRowColumnValue(row: any, col: GridColumn): string {
         let val;
-        if (col.name in row) {
+
+        if (col.path) {
+            val = this.nestedItemFieldValue(row, col);
+        } else if (col.name in row) {
             val = this.getObjectFieldValue(row, col.name);
-        } else {
-            if (col.path) {
-                val = this.nestedItemFieldValue(row, col);
-            }
         }
 
         return this.format.transform({
@@ -657,7 +657,7 @@ export class GridContext {
         for (let i = 0; i < steps.length; i++) {
             const step = steps[i];
 
-            if (typeof obj !== 'object') {
+            if (obj === null || obj === undefined || typeof obj !== 'object') {
                 // We have run out of data to step through before
                 // reaching the end of the path.  Conclude fleshing via
                 // callback if provided then exit.
@@ -861,6 +861,15 @@ export class GridContext {
             col.datatype = field.datatype;
             col.isIndex = (field.name === pkeyField);
             col.isAuto = true;
+
+            if (this.showLinkSelectors) {
+                const selector = this.idl.getLinkSelector(
+                    this.columnSet.idlClass, field.name);
+                if (selector) {
+                    col.path = field.name + '.' + selector;
+                }
+            }
+
             this.columnSet.add(col);
         });
     }
diff --git a/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.html b/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.html
index 44e407b862..95819f0a0a 100644
--- a/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.html
+++ b/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.html
@@ -49,7 +49,7 @@
 <eg-translate #translator></eg-translate>
 
 <eg-grid #grid idlClass="{{idlClass}}" [dataSource]="dataSource" 
-    [sortable]="true" persistKey="{{persistKey}}">
+    [sortable]="true" persistKey="{{persistKey}}" [showLinkSelectors]="true">
   <eg-grid-toolbar-button [disabled]="!canCreate" 
     label="New {{idlClassDef.label}}" i18n-label [action]="createNew">
   </eg-grid-toolbar-button>
diff --git a/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.ts b/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.ts
index cd6e706660..4561a04c23 100644
--- a/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.ts
+++ b/Open-ILS/src/eg2/src/app/staff/share/admin-page/admin-page.component.ts
@@ -302,11 +302,13 @@ export class AdminPageComponent implements OnInit {
 
                 const search = {};
                 search[this.orgField] = orgs;
-                return this.pcrud.search(this.idlClass, search, searchOps);
+                return this.pcrud.search(
+                    this.idlClass, search, searchOps, {fleshSelectors: true});
             }
 
             // No org filter -- fetch all rows
-            return this.pcrud.retrieveAll(this.idlClass, searchOps);
+            return this.pcrud.retrieveAll(
+                this.idlClass, searchOps, {fleshSelectors: true});
         };
     }
 

-----------------------------------------------------------------------

Summary of changes:
 Open-ILS/examples/fm_IDL.xml                       |  2 +-
 Open-ILS/src/eg2/src/app/core/format.service.ts    | 30 +++++++++++
 Open-ILS/src/eg2/src/app/core/idl.service.ts       | 23 +++++++++
 Open-ILS/src/eg2/src/app/core/pcrud.service.ts     | 60 ++++++++++++++++++++++
 .../src/app/share/fm-editor/fm-editor.component.ts |  3 +-
 .../src/eg2/src/app/share/grid/grid.component.ts   | 15 ++++++
 Open-ILS/src/eg2/src/app/share/grid/grid.ts        | 33 +++++++++---
 .../src/app/staff/sandbox/sandbox.component.html   |  2 +
 .../eg2/src/app/staff/sandbox/sandbox.component.ts | 16 ++++++
 .../share/admin-page/admin-page.component.html     |  2 +-
 .../staff/share/admin-page/admin-page.component.ts |  6 ++-
 Open-ILS/xsl/fm_IDL2js.xsl                         |  2 +-
 12 files changed, 181 insertions(+), 13 deletions(-)


hooks/post-receive
-- 
Evergreen ILS


More information about the open-ils-commits mailing list