conductor

CI task system
git clone git://git.finwo.net/app/conductor
Log | Files | Refs | README | LICENSE

format.ts (2033B)


      1 // web/src/util/format.ts - timestamps, durations and sizes
      2 
      3 const UNITS: [number, string][] = [
      4   [60, 'second'],
      5   [60, 'minute'],
      6   [24, 'hour'],
      7   [7, 'day'],
      8   [4.348, 'week'],
      9   [12, 'month'],
     10 ];
     11 
     12 // Rendered from the clock at draw time rather than baked in, so a page left
     13 // open does not keep insisting something happened two seconds ago.
     14 export function ago(at: number | null | undefined, now = Date.now()): string {
     15   if (!at) return '';
     16   let value = (now - at) / 1000;
     17   if (value < 45) return 'just now';
     18 
     19   for (const [step, unit] of UNITS) {
     20     if (Math.abs(value) < step) {
     21       const n = Math.round(value);
     22       return `${n} ${unit}${n === 1 ? '' : 's'} ago`;
     23     }
     24     value /= step;
     25   }
     26   const years = Math.round(value);
     27   return `${years} year${years === 1 ? '' : 's'} ago`;
     28 }
     29 
     30 export function duration(from: number | null | undefined, to: number | null | undefined): string {
     31   if (!from) return '';
     32   const ms = (to ?? Date.now()) - from;
     33   if (ms < 0) return '';
     34 
     35   const seconds = Math.floor(ms / 1000);
     36   if (seconds < 60) return `${seconds}s`;
     37 
     38   const minutes = Math.floor(seconds / 60);
     39   if (minutes < 60) return `${minutes}m ${seconds % 60}s`;
     40 
     41   return `${Math.floor(minutes / 60)}h ${minutes % 60}m`;
     42 }
     43 
     44 export function bytes(size: number | null | undefined): string {
     45   if (size === null || size === undefined) return '';
     46   if (size < 1024) return `${size} B`;
     47 
     48   const units = ['KiB', 'MiB', 'GiB', 'TiB'];
     49   let value = size / 1024;
     50   let unit = 0;
     51   while (value >= 1024 && unit < units.length - 1) {
     52     value /= 1024;
     53     unit += 1;
     54   }
     55   return `${value.toFixed(value < 10 ? 1 : 0)} ${units[unit]}`;
     56 }
     57 
     58 export function stamp(at: number | null | undefined): string {
     59   return at ? new Date(at).toLocaleString() : '';
     60 }
     61 
     62 export function shortSha(sha: string | null | undefined): string {
     63   return sha ? sha.slice(0, 8) : '';
     64 }
     65 
     66 const TERMINAL = ['success', 'failed', 'cancelled', 'skipped', 'timeout'];
     67 
     68 export function settled(state: string): boolean {
     69   return TERMINAL.includes(state);
     70 }