1 import {Injectable} from '@angular/core';
2 import {DatePipe, CurrencyPipe} from '@angular/common';
3 import {IdlService, IdlObject} from '@eg/core/idl.service';
4 import {OrgService} from '@eg/core/org.service';
7 * Format IDL vield values for display.
12 export interface FormatParams {
17 orgField?: string; // 'shortname' || 'name'
18 datePlusTime?: boolean;
21 @Injectable({providedIn: 'root'})
22 export class FormatService {
24 dateFormat = 'shortDate';
25 dateTimeFormat = 'short';
26 wsOrgTimezone: string = OpenSRF.tz;
29 private datePipe: DatePipe,
30 private currencyPipe: CurrencyPipe,
31 private idl: IdlService,
32 private org: OrgService
35 // Create an inilne polyfill for Number.isNaN, which is
36 // not available in PhantomJS for unit testing.
37 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN
39 // "The following works because NaN is the only value
40 // in javascript which is not equal to itself."
41 Number.isNaN = (value: any) => {
42 return value !== value;
48 * Create a human-friendly display version of any field type.
50 transform(params: FormatParams): string {
51 const value = params.value;
53 if ( value === undefined
56 || Number.isNaN(value)) {
60 let datatype = params.datatype;
63 if (params.idlClass && params.idlField) {
64 datatype = this.idl.classes[params.idlClass]
65 .field_map[params.idlField].datatype;
67 // Assume it's a primitive value
75 if (typeof value !== 'object') {
76 return value + ''; // no fleshed value here
79 if (!params.idlClass || !params.idlField) {
80 // Without a full accounting of the field data,
81 // we can't determine the display value.
85 const localClass = this.idl.classes[params.idlClass];
88 console.warn(`No such IDL class ${params.idlClass}`);
92 if (!localClass.field_map[params.idlField]) {
93 console.warn(`IDL class ${params.idlClass} ` +
94 `has no field named "${params.idlField}"`);
98 const linkType = localClass.field_map[params.idlField]['reltype'];
99 if (linkType !== 'has_a') {
100 return value + ''; // eh?
103 const localField = localClass.field_map[params.idlField];
104 const remoteKey = localField['key'];
106 const remoteClass = this.idl.classes[localField['class']];
107 const remoteField = remoteClass.field_map[remoteKey];
108 const remoteSelector = remoteField.selector || remoteField.name;
110 return value[remoteSelector]() + '';
113 const orgField = params.orgField || 'shortname';
114 const org = this.org.get(value);
115 return org ? org[orgField]() : '';
118 const date = new Date(value);
119 let fmt = this.dateFormat || 'shortDate';
120 if (params.datePlusTime) {
121 fmt = this.dateTimeFormat || 'short';
123 return this.datePipe.transform(date, fmt);
126 return this.currencyPipe.transform(value);
129 // Slightly better than a bare 't' or 'f'.
130 // Should probably add a global true/false string.
132 value === 't' || value === 1 ||
133 value === '1' || value === true