1 import {Injectable, Pipe, PipeTransform} 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 linked selector field.
86 this.idl.getLinkSelector(params.idlClass, params.idlField);
88 if (selector && typeof value[selector] === 'function') {
89 const val = value[selector]();
91 if (Array.isArray(val)) {
92 // Typically has_many links will not be fleshed,
93 // but in the off-chance the are, avoid displaying
94 // an array reference value.
105 const orgField = params.orgField || 'shortname';
106 const org = this.org.get(value);
107 return org ? org[orgField]() : '';
110 const date = new Date(value);
111 let fmt = this.dateFormat || 'shortDate';
112 if (params.datePlusTime) {
113 fmt = this.dateTimeFormat || 'short';
115 return this.datePipe.transform(date, fmt);
118 return this.currencyPipe.transform(value);
121 // Slightly better than a bare 't' or 'f'.
122 // Note the caller is better off using an <eg-bool/> for
125 value === 't' || value === 1 ||
126 value === '1' || value === true
136 // Pipe-ify the above formating logic for use in templates
137 @Pipe({name: 'formatValue'})
138 export class FormatValuePipe implements PipeTransform {
139 constructor(private formatter: FormatService) {}
140 // Add other filter params as needed to fill in the FormatParams
141 transform(value: string, datatype: string): string {
142 return this.formatter.transform({value: value, datatype: datatype});