19690: metadata and portabledatahash columns up
[arvados-workbench2.git] / src / common / formatters.ts
1 // Copyright (C) The Arvados Authors. All rights reserved.
2 //
3 // SPDX-License-Identifier: AGPL-3.0
4
5 import { PropertyValue } from 'models/search-bar';
6 import {
7   Vocabulary,
8   getTagKeyLabel,
9   getTagValueLabel,
10 } from 'models/vocabulary';
11
12 export const formatDate = (isoDate?: string | null, utc: boolean = false) => {
13   if (isoDate) {
14     const date = new Date(isoDate);
15     let text: string;
16     if (utc) {
17       text = date.toUTCString();
18     } else {
19       text = date.toLocaleString();
20     }
21     return text === 'Invalid Date' ? '(none)' : text;
22   }
23   return '(none)';
24 };
25
26 export const formatFileSize = (size?: number | string) => {
27   if (typeof size === 'number') {
28     if (size === 0) {
29       return '0 B';
30     }
31
32     for (const { base, unit } of FILE_SIZES) {
33       if (size >= base) {
34         return `${(size / base).toFixed()} ${unit}`;
35       }
36     }
37   }
38   if ((typeof size === 'string' && size === '') || size === undefined) {
39     return '';
40   }
41   return '0 B';
42 };
43
44 export const formatTime = (time: number, seconds?: boolean) => {
45   const minutes = Math.floor((time / (1000 * 60)) % 60).toFixed(0);
46   const hours = Math.floor(time / (1000 * 60 * 60)).toFixed(0);
47
48   if (seconds) {
49     const seconds = Math.floor((time / 1000) % 60).toFixed(0);
50     return hours + 'h ' + minutes + 'm ' + seconds + 's';
51   }
52
53   return hours + 'h ' + minutes + 'm';
54 };
55
56 export const getTimeDiff = (endTime: string, startTime: string) => {
57   return new Date(endTime).getTime() - new Date(startTime).getTime();
58 };
59
60 export const formatProgress = (loaded: number, total: number) => {
61   const progress = loaded >= 0 && total > 0 ? (loaded * 100) / total : 0;
62   return `${progress.toFixed(2)}%`;
63 };
64
65 export function formatUploadSpeed(
66   prevLoaded: number,
67   loaded: number,
68   prevTime: number,
69   currentTime: number
70 ) {
71   const speed =
72     loaded > prevLoaded && currentTime > prevTime
73       ? (loaded - prevLoaded) / (currentTime - prevTime)
74       : 0;
75
76   return `${(speed / 1000).toFixed(2)} MB/s`;
77 }
78
79 const FILE_SIZES = [
80   {
81     base: 1099511627776,
82     unit: 'TB',
83   },
84   {
85     base: 1073741824,
86     unit: 'GB',
87   },
88   {
89     base: 1048576,
90     unit: 'MB',
91   },
92   {
93     base: 1024,
94     unit: 'KB',
95   },
96   {
97     base: 1,
98     unit: 'B',
99   },
100 ];
101
102 export const formatPropertyValue = (
103   pv: PropertyValue,
104   vocabulary?: Vocabulary
105 ) => {
106   if (vocabulary && pv.keyID && pv.valueID) {
107     return `${getTagKeyLabel(pv.keyID, vocabulary)}: ${getTagValueLabel(
108       pv.keyID,
109       pv.valueID!,
110       vocabulary
111     )}`;
112   }
113   if (pv.key) {
114     return pv.value ? `${pv.key}: ${pv.value}` : pv.key;
115   }
116   return '';
117 };
118
119 export const formatContainerCost = (cost: number): string => {
120   const decimalPlaces = 3;
121
122   const factor = Math.pow(10, decimalPlaces);
123   const rounded = Math.round(cost * factor) / factor;
124   if (cost > 0 && rounded === 0) {
125     // Display min value of 0.001
126     return `$${1 / factor}`;
127   } else {
128     // Otherwise use rounded value to proper decimal places
129     return `$${rounded}`;
130   }
131 };
132
133 export const formatObjectProperties = (untypedObj: Object) => {
134   type kVPair = [string, string];
135   let formattedObject: Array<kVPair> = [];
136   for (const key in untypedObj) {
137     formattedObject.push([key, untypedObj[key]]);
138   }
139   return formattedObject;
140 };