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