]> git.proxmox.com Git - ceph.git/blame - ceph/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary-per-second.directive.ts
import 15.2.0 Octopus source
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / shared / directives / dimless-binary-per-second.directive.ts
CommitLineData
11fdf7f2
TL
1import {
2 Directive,
3 ElementRef,
4 EventEmitter,
5 HostListener,
6 Input,
7 OnInit,
8 Output
9} from '@angular/core';
10import { NgControl } from '@angular/forms';
11
12import * as _ from 'lodash';
13
14import { DimlessBinaryPerSecondPipe } from '../pipes/dimless-binary-per-second.pipe';
15import { FormatterService } from '../services/formatter.service';
16
17@Directive({
18 selector: '[cdDimlessBinaryPerSecond]'
19})
20export 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}