All files / src/app/shared/directives dimless-binary.directive.ts

88.89% Statements 40/45
72.5% Branches 29/40
83.33% Functions 5/6
88.1% Lines 37/42

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 12398x                 98x   98x   98x 98x         98x   98x                         98x                         98x                   98x                     98x         39x 39x 39x 39x   39x     98x 29x     98x 29x 2x   29x 29x 29x 29x 18x 18x   11x 11x       98x 29x 18x     18x     18x         29x       196x     98x  
import {
  Directive,
  ElementRef,
  EventEmitter,
  HostListener,
  Input,
  OnInit,
  Output
} from '@angular/core';
import { NgControl } from '@angular/forms';
 
import * as _ from 'lodash';
 
import { DimlessBinaryPipe } from '../pipes/dimless-binary.pipe';
import { FormatterService } from '../services/formatter.service';
 
@Directive({
  selector: '[cdDimlessBinary]'
})
export class DimlessBinaryDirective implements OnInit {
  @Output()
  ngModelChange: EventEmitter<any> = new EventEmitter();
 
  /**
   * Minimum size in bytes.
   * If user enter a value lower than <minBytes>,
   * the model will automatically be update to <minBytes>.
   *
   * If <roundPower> is used, this value should be a power of <roundPower>.
   *
   * Example:
   *   Given minBytes=4096 (4KiB), if user type 1KiB, then model will be updated to 4KiB
   */
  @Input()
  minBytes: number;
 
  /**
   * Maximum size in bytes.
   * If user enter a value greater than <maxBytes>,
   * the model will automatically be update to <maxBytes>.
   *
   * If <roundPower> is used, this value should be a power of <roundPower>.
   *
   * Example:
   *   Given maxBytes=3145728 (3MiB), if user type 4MiB, then model will be updated to 3MiB
   */
  @Input()
  maxBytes: number;
 
  /**
   * Value will be rounded up the nearest power of <roundPower>
   *
   * Example:
   *   Given roundPower=2, if user type 7KiB, then model will be updated to 8KiB
   *   Given roundPower=2, if user type 5KiB, then model will be updated to 4KiB
   */
  @Input()
  roundPower: number;
 
  /**
   * Default unit that should be used when user do not type a unit.
   * By default, "MiB" will be used.
   *
   * Example:
   *   Given defaultUnit=null, if user type 7, then model will be updated to 7MiB
   *   Given defaultUnit=k, if user type 7, then model will be updated to 7KiB
   */
  @Input()
  defaultUnit: string;
 
  private el: HTMLInputElement;
 
  constructor(
    private elementRef: ElementRef,
    private control: NgControl,
    private dimlessBinaryPipe: DimlessBinaryPipe,
    private formatter: FormatterService
  ) {
    this.el = this.elementRef.nativeElement;
  }
 
  ngOnInit() {
    this.setValue(this.el.value);
  }
 
  setValue(value) {
    if (/^[\d.]+$/.test(value)) {
      value += this.defaultUnit || 'm';
    }
    const size = this.formatter.toBytes(value);
    const roundedSize = this.round(size);
    this.el.value = this.dimlessBinaryPipe.transform(roundedSize);
    if (size !== null) {
      this.ngModelChange.emit(this.el.value);
      this.control.control.setValue(this.el.value);
    } else {
      this.ngModelChange.emit(null);
      this.control.control.setValue(null);
    }
  }
 
  round(size) {
    if (size !== null && size !== 0) {
      Iif (!_.isUndefined(this.minBytes) && size < this.minBytes) {
        return this.minBytes;
      }
      Iif (!_.isUndefined(this.maxBytes) && size > this.maxBytes) {
        return this.maxBytes;
      }
      Iif (!_.isUndefined(this.roundPower)) {
        const power = Math.round(Math.log(size) / Math.log(this.roundPower));
        return Math.pow(this.roundPower, power);
      }
    }
    return size;
  }
 
  @HostListener('blur', ['$event.target.value'])
  onBlur(value) {
    this.setValue(value);
  }
}