summaryrefslogtreecommitdiffstats
path: root/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary-per-second.directive.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary-per-second.directive.ts')
-rw-r--r--src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary-per-second.directive.ts132
1 files changed, 132 insertions, 0 deletions
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary-per-second.directive.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary-per-second.directive.ts
new file mode 100644
index 000000000..a90e2b8f8
--- /dev/null
+++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/directives/dimless-binary-per-second.directive.ts
@@ -0,0 +1,132 @@
+import {
+ Directive,
+ ElementRef,
+ EventEmitter,
+ HostListener,
+ Input,
+ OnInit,
+ Output
+} from '@angular/core';
+import { NgControl } from '@angular/forms';
+
+import _ from 'lodash';
+
+import { DimlessBinaryPerSecondPipe } from '../pipes/dimless-binary-per-second.pipe';
+import { FormatterService } from '../services/formatter.service';
+
+@Directive({
+ selector: '[cdDimlessBinaryPerSecond]'
+})
+export class DimlessBinaryPerSecondDirective implements OnInit {
+ @Output()
+ ngModelChange: EventEmitter<any> = new EventEmitter();
+
+ /**
+ * Event emitter for letting this directive know that the data has (asynchronously) been loaded
+ * and the value needs to be adapted by this directive.
+ */
+ @Input()
+ ngDataReady: EventEmitter<any>;
+
+ /**
+ * 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 dimlessBinaryPerSecondPipe: DimlessBinaryPerSecondPipe,
+ private formatter: FormatterService
+ ) {
+ this.el = this.elementRef.nativeElement;
+ }
+
+ ngOnInit() {
+ this.setValue(this.el.value);
+ if (this.ngDataReady) {
+ this.ngDataReady.subscribe(() => this.setValue(this.el.value));
+ }
+ }
+
+ setValue(value: string) {
+ if (/^[\d.]+$/.test(value)) {
+ value += this.defaultUnit || 'm';
+ }
+ const size = this.formatter.toBytes(value, 0);
+ const roundedSize = this.round(size);
+ this.el.value = this.dimlessBinaryPerSecondPipe.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: number) {
+ if (size !== null && size !== 0) {
+ if (!_.isUndefined(this.minBytes) && size < this.minBytes) {
+ return this.minBytes;
+ }
+ if (!_.isUndefined(this.maxBytes) && size > this.maxBytes) {
+ return this.maxBytes;
+ }
+ if (!_.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: string) {
+ this.setValue(value);
+ }
+}