isDragTarget: boolean;
isSortable: boolean;
isMultiSortable: boolean;
+ flesher: (obj: any, col: GridColumn, item: any) => any;
getCellContext(row: any) {
return {
isSortable: boolean;
isMultiSortable: boolean;
stockVisible: string[];
+ idl: IdlService;
- constructor(idlClass?: string) {
+ constructor(idl: IdlService, idlClass?: string) {
+ this.idl = idl;
this.columns = [];
this.stockVisible = [];
this.idlClass = idlClass;
}
add(col: GridColumn) {
- // avoid dupes
- if (this.getColByName(col.name)) { return; }
- if (col.isIndex) { this.indexColumn = col; }
- if (!col.flex) { col.flex = 2; }
- if (!col.label) { col.label = col.name; }
- if (!col.align) { col.align = 'left'; }
- if (!col.datatype) { col.datatype = 'text'; }
+ this.applyColumnDefaults(col);
- col.visible = !col.hidden;
+ if (this.getColByName(col.name)) { return; } // avoid dupes
+
+ if (col.isIndex) { this.indexColumn = col; }
// track which fields are visible on page load.
if (col.visible) {
return this.columns.filter(c => c.name === name)[0];
}
+ idlInfoFromDotpath(dotpath: string): any {
+ if (!dotpath) return null;
+
+ let idlParent;
+ let idlField;
+ let idlClass = this.idl.classes[this.idlClass];
+
+ const pathParts = dotpath.split(/\./);
+
+ for (let i = 0; i < pathParts.length; i++) {
+ const part = pathParts[i];
+ idlParent = idlField;
+ idlField = idlClass.field_map[part];
+
+ if (idlField) {
+ if (idlField['class'] && (
+ idlField.datatype === 'link' ||
+ idlField.datatype === 'org_unit')) {
+ idlClass = this.idl.classes[idlField['class']];
+ }
+ } else {
+ return null;
+ }
+ }
+
+ return {
+ idlParent: idlParent,
+ idlField : idlField,
+ idlClass : idlClass
+ };
+ }
+
+
reset() {
this.columns.forEach(col => {
col.flex = 2;
});
}
+ applyColumnDefaults(col: GridColumn) {
+
+ if (!col.idlFieldDef && col.path) {
+ const idlInfo = this.idlInfoFromDotpath(col.path);
+ if (idlInfo) {
+ col.idlFieldDef = idlInfo.idlField;
+ if (!col.label) {
+ col.label = col.idlFieldDef.label || col.idlFieldDef.name;
+ col.datatype = col.idlFieldDef.datatype;
+ }
+ }
+ }
+
+ if (!col.name) { col.name = col.path; }
+ if (!col.flex) { col.flex = 2; }
+ if (!col.align) { col.align = 'left'; }
+ if (!col.label) { col.label = col.name; }
+ if (!col.datatype) { col.datatype = 'text'; }
+
+ col.visible = !col.hidden;
+ }
+
applyColumnSortability(col: GridColumn) {
// column sortability defaults to the sortability of the column set.
if (col.isSortable === undefined && this.isSortable) {
}
init() {
- this.columnSet = new GridColumnSet(this.idlClass);
+ this.columnSet = new GridColumnSet(this.idl, this.idlClass);
this.columnSet.isSortable = this.isSortable === true;
this.columnSet.isMultiSortable = this.isMultiSortable === true;
this.generateColumns();
destroy() {
this.ignorePager();
-
}
+
reload() {
// Give the UI time to settle before reloading grid data.
// This can help when data retrieval depends on a value
getRowColumnValue(row: any, col: GridColumn): string {
let val;
- if (typeof row[col.name] === 'function') {
- val = row[col.name]();
+ if (col.name in row) {
+ val = this.getObjectFieldValue(row, col.name);
} else {
- val = row[col.name];
+ if (col.path) {
+ val = this.nestedItemFieldValue(row, col);
+ }
}
return this.format.transform({value: val, datatype: col.datatype});
}
+ getObjectFieldValue(obj: any, name: string): any {
+ if (typeof obj[name] === 'function') {
+ return obj[name]();
+ } else {
+ return obj[name];
+ }
+ }
+
+ nestedItemFieldValue(obj: any, col: GridColumn): string {
+
+ let idlField;
+ let idlClassDef;
+ const original = obj;
+ const steps = col.path.split('.');
+
+ for (let i = 0; i < steps.length; i++) {
+ const step = steps[i];
+
+ if (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.
+ if (col.flesher && obj !== undefined) {
+ return col.flesher(obj, col, original);
+ }
+ return obj;
+ }
+
+ const class_ = obj.classname;
+ if (class_ && (idlClassDef = this.idl.classes[class_])) {
+ idlField = idlClassDef.field_map[step];
+ }
+
+ obj = this.getObjectFieldValue(obj, step);
+ }
+
+ // We found a nested IDL object which may or may not have
+ // been configured as a top-level column. Flesh the column
+ // metadata with our newly found IDL info.
+ if (idlField) {
+ if (!col.datatype) {
+ col.datatype = idlField.datatype;
+ }
+ if (!col.label) {
+ col.label = idlField.label || idlField.name;
+ }
+ }
+
+ return obj;
+ }
+
+
getColumnTextContent(row: any, col: GridColumn): string {
if (col.cellTemplate) {
// TODO
import {GridDataSource} from '@eg/share/grid/grid';
import {IdlService, IdlObject} from '@eg/core/idl.service';
import {PcrudService} from '@eg/core/pcrud.service';
+import {OrgService} from '@eg/core/org.service';
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';
constructor(
private idl: IdlService,
+ private org: OrgService,
private pcrud: PcrudService,
private strings: StringService,
private toast: ToastService,
{name: 'The Tick', state: 'TX'}
];
- this.btSource.getRows = (pager: Pager) => {
+ this.btSource.getRows = (pager: Pager, sort: any[]) => {
+
+ const orderBy: any = {cbt: 'name'};
+ if (sort.length) {
+ orderBy.cbt = sort[0].name + ' ' + sort[0].dir;
+ }
+
return this.pcrud.retrieveAll('cbt', {
offset: pager.offset,
limit: pager.limit,
- order_by: {cbt: 'name'}
- });
+ order_by: orderBy
+ }).pipe(map(cbt => {
+ // example of inline fleshing
+ cbt.owner(this.org.get(cbt.owner()));
+ return cbt;
+ }));
};
/*