Skip to content

Commit d6fd344

Browse files
authored
Merge pull request ceph#62926 from ankitk18/add/size-input
mgr/dashboard:Added a dropdown menu for all size inputs. Reviewed-by: Afreen Misbah <[email protected]>
2 parents b71625d + 7c487c3 commit d6fd344

File tree

3 files changed

+142
-78
lines changed

3 files changed

+142
-78
lines changed

src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.html

Lines changed: 48 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
i18n>Name</label>
1717
<div class="cd-col-form-input">
1818
<input id="name"
19-
name="name"
2019
type="text"
2120
class="form-control"
2221
placeholder="Name..."
@@ -47,8 +46,7 @@
4746
<div class="cd-col-form-input">
4847
<select class="form-select"
4948
id="poolType"
50-
formControlName="poolType"
51-
name="poolType">
49+
formControlName="poolType">
5250
<option ngValue=""
5351
i18n>-- Select a pool type --</option>
5452
<option *ngFor="let poolType of data.poolTypes"
@@ -71,7 +69,6 @@
7169
<div class="cd-col-form-input">
7270
<select class="form-select"
7371
id="pgAutoscaleMode"
74-
name="pgAutoscaleMode"
7572
formControlName="pgAutoscaleMode">
7673
<option *ngFor="let mode of pgAutoscaleModes"
7774
[value]="mode">
@@ -90,7 +87,6 @@
9087
<div class="cd-col-form-input">
9188
<input class="form-control"
9289
id="pgNum"
93-
name="pgNum"
9490
formControlName="pgNum"
9591
min="1"
9692
type="number"
@@ -129,7 +125,6 @@
129125
id="size"
130126
[max]="getMaxSize()"
131127
[min]="getMinSize()"
132-
name="size"
133128
type="number"
134129
formControlName="size">
135130
<span class="invalid-feedback"
@@ -180,7 +175,6 @@
180175
</label>
181176
<div class="cd-col-form-input">
182177
<cd-select-badges id="applications"
183-
name="applications"
184178
[customBadges]="true"
185179
[customBadgeValidators]="data.applications.validators"
186180
[messages]="data.applications.messages"
@@ -206,7 +200,6 @@
206200
<div class="custom-control custom-checkbox">
207201
<input class="custom-control-input"
208202
id="rbdMirroring"
209-
name="rbdMirroring"
210203
type="checkbox"
211204
formControlName="rbdMirroring">
212205
<label class="custom-control-label"
@@ -233,7 +226,6 @@
233226
<div class="input-group mb-1">
234227
<select class="form-select"
235228
id="erasureProfile"
236-
name="erasureProfile"
237229
formControlName="erasureProfile"
238230
(change)="erasureProfileChange()">
239231
<option *ngIf="!ecProfiles"
@@ -347,8 +339,7 @@
347339
<div class="input-group">
348340
<select class="form-select"
349341
id="crushRule"
350-
formControlName="crushRule"
351-
name="crushSet">
342+
formControlName="crushRule">
352343
<option [ngValue]="null"
353344
i18n>-- Select a crush rule --</option>
354345
<option *ngFor="let rule of current.rules"
@@ -462,7 +453,6 @@
462453
<div class="cd-col-form-input">
463454
<select class="form-select"
464455
id="mode"
465-
name="mode"
466456
formControlName="mode">
467457
<option *ngFor="let mode of info.compression_modes"
468458
[value]="mode">
@@ -482,7 +472,6 @@
482472
<div class="cd-col-form-input">
483473
<select class="form-select"
484474
id="algorithm"
485-
name="algorithm"
486475
formControlName="algorithm">
487476
<option *ngIf="!info.compression_algorithms"
488477
ngValue=""
@@ -508,16 +497,23 @@
508497
<ng-container i18n>Minimum blob size</ng-container>
509498
</label>
510499
<div class="cd-col-form-input">
511-
<input id="minBlobSize"
512-
name="minBlobSize"
513-
formControlName="minBlobSize"
514-
type="text"
515-
min="0"
516-
class="form-control"
517-
i18n-placeholder
518-
placeholder="e.g., 128KiB"
519-
defaultUnit="KiB"
520-
cdDimlessBinary>
500+
<div class="input-group mb-1">
501+
<input id="minBlobSize"
502+
formControlName="minBlobSize"
503+
type="text"
504+
min="0"
505+
class="form-control"
506+
i18n-placeholder
507+
placeholder="e.g., 128">
508+
<select id="minUnit"
509+
class="form-input form-select"
510+
formControlName="minBlobSizeUnit">
511+
<option *ngFor="let u of blobUnits"
512+
[value]="u">
513+
{{ u }}
514+
</option>
515+
</select>
516+
</div>
521517
<cd-help-text>
522518
<span i18n>Chunks smaller than Minimum blob size are never compressed</span>
523519
</cd-help-text>
@@ -540,15 +536,21 @@
540536
<ng-container i18n>Maximum blob size</ng-container>
541537
</label>
542538
<div class="cd-col-form-input">
543-
<input id="maxBlobSize"
544-
type="text"
545-
min="0"
546-
formControlName="maxBlobSize"
547-
class="form-control"
548-
i18n-placeholder
549-
placeholder="e.g., 512KiB"
550-
defaultUnit="KiB"
551-
cdDimlessBinary>
539+
<div class="input-group mb-1">
540+
<input id="maxBlobSize"
541+
type="text"
542+
min="0"
543+
formControlName="maxBlobSize"
544+
class="form-control">
545+
<select id="minUnit"
546+
class="form-input form-select"
547+
formControlName="maxBlobSizeUnit">
548+
<option *ngFor="let u of blobUnits"
549+
[value]="u">
550+
{{ u }}
551+
</option>
552+
</select>
553+
</div>
552554
<cd-help-text>
553555
<span i18n>Chunks larger than `Maximum Blob Size` are broken into smaller blobs of size mentioned before being compressed.</span>
554556
</cd-help-text>
@@ -572,7 +574,6 @@
572574
</label>
573575
<div class="cd-col-form-input">
574576
<input id="ratio"
575-
name="ratio"
576577
formControlName="ratio"
577578
type="number"
578579
min="0"
@@ -602,15 +603,20 @@
602603
<ng-container i18n>Max bytes</ng-container>
603604
</label>
604605
<div class="cd-col-form-input">
605-
<input class="form-control"
606-
id="max_bytes"
607-
name="max_bytes"
608-
type="text"
609-
formControlName="max_bytes"
610-
i18n-placeholder
611-
placeholder="e.g., 10GiB"
612-
defaultUnit="GiB"
613-
cdDimlessBinary>
606+
<div class="input-group mb-1">
607+
<input class="form-control"
608+
id="max_bytes"
609+
type="text"
610+
formControlName="max_bytes">
611+
<select id="unit"
612+
class="form-input form-select"
613+
formControlName="maxBytesUnit">
614+
<option *ngFor="let u of maxBytesUnits"
615+
[value]="u">
616+
{{ u }}
617+
</option>
618+
</select>
619+
</div>
614620
<cd-help-text>
615621
<span i18n>Leave it blank or specify 0 to disable this quota.</span>
616622
<br>
@@ -632,7 +638,6 @@
632638
<input class="form-control"
633639
id="max_objects"
634640
min="0"
635-
name="max_objects"
636641
type="number"
637642
formControlName="max_objects">
638643
<cd-help-text>

src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/pool-form/pool-form.component.spec.ts

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -336,30 +336,35 @@ describe('PoolFormComponent', () => {
336336
it('validates minBlobSize to be only valid between 0 and maxBlobSize', () => {
337337
formHelper.expectErrorChange('minBlobSize', -1, 'min');
338338
formHelper.expectValidChange('minBlobSize', 0);
339-
formHelper.setValue('maxBlobSize', '2 KiB');
340-
formHelper.expectErrorChange('minBlobSize', '3 KiB', 'maximum');
341-
formHelper.expectValidChange('minBlobSize', '1.9 KiB');
339+
formHelper.setValue('minBlobSizeUnit', 'KiB');
340+
formHelper.setValue('maxBlobSize', '2');
341+
formHelper.setValue('maxBlobSizeUnit', 'KiB');
342+
formHelper.expectErrorChange('minBlobSize', '3', 'maximum');
343+
formHelper.expectValidChange('minBlobSize', '1.9');
342344
});
343345

344346
it('validates minBlobSize converts numbers', () => {
345347
const control = formHelper.setValue('minBlobSize', '1');
348+
const controlUnit = formHelper.setValue('minBlobSizeUnit', 'KiB');
346349
fixture.detectChanges();
347350
formHelper.expectValid(control);
348-
expect(control.value).toBe('1 KiB');
351+
expect(control.value).toBe('1');
352+
expect(controlUnit.value).toBe('KiB');
349353
});
350354

351355
it('validates maxBlobSize to be only valid bigger than minBlobSize', () => {
352356
formHelper.expectErrorChange('maxBlobSize', -1, 'min');
353-
formHelper.setValue('minBlobSize', '1 KiB');
354-
formHelper.expectErrorChange('maxBlobSize', '0.5 KiB', 'minimum');
355-
formHelper.expectValidChange('maxBlobSize', '1.5 KiB');
357+
formHelper.setValue('minBlobSize', '1');
358+
formHelper.setValue('minBlobSizeUnit', 'MiB');
359+
formHelper.expectErrorChange('maxBlobSize', '0.5', 'minimum');
360+
formHelper.expectValidChange('maxBlobSize', '1.5');
356361
});
357362

358363
it('s valid to only use one blob size', () => {
359-
formHelper.expectValid(formHelper.setValue('minBlobSize', '1 KiB'));
364+
formHelper.expectValid(formHelper.setValue('minBlobSize', '1'));
360365
formHelper.expectValid(formHelper.setValue('maxBlobSize', ''));
361366
formHelper.expectValid(formHelper.setValue('minBlobSize', ''));
362-
formHelper.expectValid(formHelper.setValue('maxBlobSize', '1 KiB'));
367+
formHelper.expectValid(formHelper.setValue('maxBlobSize', '1'));
363368
});
364369

365370
it('dismisses any size error if one of the blob sizes is changed into a valid state', () => {
@@ -378,19 +383,22 @@ describe('PoolFormComponent', () => {
378383

379384
it('validates maxBlobSize converts numbers', () => {
380385
const control = formHelper.setValue('maxBlobSize', '2');
386+
const controlUnit = formHelper.setValue('maxBlobSizeUnit', 'KiB');
381387
fixture.detectChanges();
382-
expect(control.value).toBe('2 KiB');
388+
expect(control.value).toBe('2');
389+
expect(controlUnit.value).toBe('KiB');
383390
});
384391

385392
it('validates that odd size validator works as expected', () => {
386-
const odd = (min: string, max: string) => component['oddBlobSize'](min, max);
387-
expect(odd('10', '8')).toBe(true);
388-
expect(odd('8', '-')).toBe(false);
389-
expect(odd('8', '10')).toBe(false);
390-
expect(odd(null, '8')).toBe(false);
391-
expect(odd('10', '')).toBe(false);
392-
expect(odd('10', null)).toBe(false);
393-
expect(odd(null, null)).toBe(false);
393+
const odd = (min: string, minUnit: string, max: string, maxUnit: string) =>
394+
component['oddBlobSize'](min, minUnit, max, maxUnit);
395+
expect(odd('10', 'KiB', '8', 'KiB')).toBe(true);
396+
expect(odd('8', 'KiB', '-', 'KiB')).toBe(false);
397+
expect(odd('8', 'KiB', '10', 'KiB')).toBe(false);
398+
expect(odd(null, 'KiB', '8', 'KiB')).toBe(false);
399+
expect(odd('10', 'KiB', '', 'KiB')).toBe(false);
400+
expect(odd('10', 'KiB', null, 'KiB')).toBe(false);
401+
expect(odd(null, 'KiB', null, 'KiB')).toBe(false);
394402
});
395403

396404
it('validates ratio to be only valid between 0 and 1', () => {
@@ -1149,10 +1157,13 @@ describe('PoolFormComponent', () => {
11491157
setMultipleValues({
11501158
mode: 'passive',
11511159
algorithm: 'lz4',
1152-
minBlobSize: '4 K',
1153-
maxBlobSize: '4 M',
1160+
minBlobSize: '4',
1161+
minBlobSizeUnit: 'KiB',
1162+
maxBlobSize: '4',
1163+
maxBlobSizeUnit: 'MiB',
11541164
ratio: 0.7
11551165
});
1166+
fixture.detectChanges();
11561167
expectEcSubmit({
11571168
compression_mode: 'passive',
11581169
compression_algorithm: 'lz4',
@@ -1237,7 +1248,8 @@ describe('PoolFormComponent', () => {
12371248

12381249
it('creates a pool with quotas', () => {
12391250
setMultipleValues({
1240-
max_bytes: 1024 * 1024,
1251+
max_bytes: 1,
1252+
maxBytesUnit: 'MiB',
12411253
max_objects: 3000
12421254
});
12431255
component.data.applications.selected = ['cephfs', 'rgw'];
@@ -1343,10 +1355,13 @@ describe('PoolFormComponent', () => {
13431355
expect(form.getValue('pgNum')).toBe(pool.pg_num);
13441356
expect(form.getValue('mode')).toBe(pool.options.compression_mode);
13451357
expect(form.getValue('algorithm')).toBe(pool.options.compression_algorithm);
1346-
expect(form.getValue('minBlobSize')).toBe('512 KiB');
1347-
expect(form.getValue('maxBlobSize')).toBe('1 MiB');
1358+
expect(form.getValue('minBlobSize')).toBe('512');
1359+
expect(form.getValue('minBlobSizeUnit')).toBe('KiB');
1360+
expect(form.getValue('maxBlobSize')).toBe('1');
1361+
expect(form.getValue('maxBlobSizeUnit')).toBe('MiB');
13481362
expect(form.getValue('ratio')).toBe(pool.options.compression_required_ratio);
1349-
expect(form.getValue('max_bytes')).toBe('1 GiB');
1363+
expect(form.getValue('max_bytes')).toBe('1');
1364+
expect(form.getValue('maxBytesUnit')).toBe('GiB');
13501365
expect(form.getValue('max_objects')).toBe(pool.quota_max_objects);
13511366
});
13521367

0 commit comments

Comments
 (0)