Skip to content

Commit 9911ecb

Browse files
committed
mgr/dashboard: carbonize rgw user and bucket form
Fixes: https://tracker.ceph.com/issues/70119 Signed-off-by: Nizamudeen A <[email protected]>
1 parent 9297329 commit 9911ecb

28 files changed

+1871
-1990
lines changed

src/pybind/mgr/dashboard/frontend/cypress/e2e/rgw/buckets.po.ts

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,9 @@ export class BucketsPageHelper extends PageHelper {
3737
cy.get('#owner').should('have.class', 'ng-valid');
3838

3939
if (isLocking) {
40-
cy.get('#lock_enabled').click({ force: true });
40+
cy.get('#lock_enabled_input').click({ force: true });
4141
// Select lock mode:
4242
this.selectLockMode('Compliance');
43-
cy.get('#lock_mode').should('have.class', 'ng-valid');
4443
cy.get('#lock_retention_period_days').type('3');
4544
}
4645

@@ -61,7 +60,7 @@ export class BucketsPageHelper extends PageHelper {
6160

6261
// If object locking is enabled versioning shouldn't be visible
6362
if (isLocking) {
64-
cy.get('input[id=versioning]').should('be.disabled');
63+
cy.get('input[name=versioning]').should('be.disabled');
6564
cy.contains('button', 'Edit Bucket').click();
6665

6766
this.getTableCell(this.columnIndex.name, name)
@@ -84,9 +83,9 @@ export class BucketsPageHelper extends PageHelper {
8483
return cy.get('@versioningValueCell').should('have.text', this.versioningStateEnabled);
8584
}
8685
// Enable versioning
87-
cy.get('input[id=versioning]').should('not.be.checked');
88-
cy.get('label[for=versioning]').click();
89-
cy.get('input[id=versioning]').should('be.checked');
86+
cy.get('input[name=versioning]').should('not.be.checked');
87+
cy.get('label[for=versioning_input]').click();
88+
cy.get('input[name=versioning]').should('be.checked');
9089
cy.contains('button', 'Edit Bucket').click();
9190

9291
// Check if the owner is updated
@@ -110,8 +109,8 @@ export class BucketsPageHelper extends PageHelper {
110109
// Disable versioning:
111110
this.navigateEdit(name, false, true, null, true);
112111

113-
cy.get('label[for=versioning]').click();
114-
cy.get('input[id=versioning]').should('not.be.checked');
112+
cy.get('label[for=versioning_input]').click();
113+
cy.get('input[name=versioning]').should('not.be.checked');
115114
cy.contains('button', 'Edit Bucket').wait(WAIT_TIMER).click();
116115

117116
// Check versioning suspended:
@@ -136,10 +135,9 @@ export class BucketsPageHelper extends PageHelper {
136135
.and('have.class', 'ng-invalid');
137136

138137
// Check that error message was printed under name input field
139-
cy.get('#bid + .invalid-feedback').should(
140-
'have.text',
141-
'Bucket names must be 3 to 63 characters long.'
142-
);
138+
cy.get('cds-text-label[for=bid]')
139+
.find('span.invalid-feedback')
140+
.should('have.text', 'Bucket names must be 3 to 63 characters long.');
143141

144142
// Test invalid owner input
145143
// select some valid option. The owner drop down error message will not appear unless a valid user was selected at
@@ -152,10 +150,12 @@ export class BucketsPageHelper extends PageHelper {
152150
cy.get('@nameInputField').click();
153151

154152
// Check that owner drop down field was marked invalid in the css
155-
cy.get('#owner').should('have.class', 'ng-invalid');
153+
cy.get('cds-select[id=owner]').should('have.class', 'ng-invalid');
156154

157155
// Check that error message was printed under owner drop down field
158-
cy.get('#owner + .invalid-feedback').should('have.text', 'This field is required.');
156+
cy.get('cds-select[id=owner]')
157+
.find('.invalid-feedback')
158+
.should('have.text', 'This field is required.');
159159

160160
// Clicks the Create Bucket button but the page doesn't move.
161161
// Done by testing for the breadcrumb
@@ -169,7 +169,7 @@ export class BucketsPageHelper extends PageHelper {
169169
testInvalidEdit(name: string) {
170170
this.navigateEdit(name, false, true, null, true);
171171

172-
cy.get('input[id=versioning]').should('exist').and('not.be.checked');
172+
cy.get('input[name=versioning]').should('exist').and('not.be.checked');
173173

174174
// Chooses 'Select a user' rather than a valid owner on Edit Bucket page
175175
// and checks if it's an invalid input
@@ -180,10 +180,12 @@ export class BucketsPageHelper extends PageHelper {
180180
cy.contains('button', 'Edit Bucket').click();
181181

182182
// Check that owner drop down field was marked invalid in the css
183-
cy.get('#owner').should('have.class', 'ng-invalid');
183+
cy.get('cds-select[id=owner]').should('have.class', 'ng-invalid');
184184

185185
// Check that error message was printed under owner drop down field
186-
cy.get('#owner + .invalid-feedback').should('have.text', 'This field is required.');
186+
cy.get('cds-select[id=owner]')
187+
.find('.invalid-feedback')
188+
.should('have.text', 'This field is required.');
187189

188190
this.expectBreadcrumbText('Edit');
189191
}

src/pybind/mgr/dashboard/frontend/cypress/e2e/rgw/users.po.ts

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export class UsersPageHelper extends PageHelper {
1313
// Enter in user_id
1414
cy.get('#user_id').type(user_id);
1515
// Show Tenant
16-
cy.get('#show_tenant').click({ force: true });
16+
cy.get('#show_tenant_input').click({ force: true });
1717
// Enter in tenant
1818
cy.get('#tenant').type(tenant);
1919
// Enter in full name
@@ -24,8 +24,8 @@ export class UsersPageHelper extends PageHelper {
2424

2525
// Enter max buckets
2626
this.selectOption('max_buckets_mode', 'Custom');
27-
cy.get('#max_buckets').should('exist').should('have.value', '1000');
28-
cy.get('#max_buckets').click().clear().type(maxbuckets);
27+
cy.get('input#max_buckets').should('exist').should('have.value', '1000');
28+
cy.get('input#max_buckets').click().clear().type(maxbuckets);
2929

3030
// Click the create button and wait for user to be made
3131
cy.contains('button', 'Create User').click();
@@ -37,14 +37,14 @@ export class UsersPageHelper extends PageHelper {
3737
this.navigateEdit(name, false, true, null, true);
3838

3939
// Change the full name field
40-
cy.get('#display_name').click().clear().type(new_fullname);
40+
cy.get('input#display_name').click().clear({ force: true }).type(new_fullname, { force: true });
4141

4242
// Change the email field
4343
cy.get('#email').click().clear().type(new_email);
4444

4545
// Change the max buckets field
4646
this.selectOption('max_buckets_mode', 'Custom');
47-
cy.get('#max_buckets').click().clear().type(new_maxbuckets);
47+
cy.get('input#max_buckets').click().clear().type(new_maxbuckets);
4848

4949
cy.contains('button', 'Edit User').click();
5050

@@ -71,13 +71,17 @@ export class UsersPageHelper extends PageHelper {
7171
.should('have.class', 'ng-invalid')
7272
// Try to give user already taken name. Should make field invalid.
7373
.type(uname);
74-
cy.get('#show_tenant').click({ force: true });
74+
cy.get('#show_tenant_input').click({ force: true });
7575
cy.get('#tenant').type(tenant).should('have.class', 'ng-invalid');
76-
cy.contains('#tenant + .invalid-feedback', 'The chosen user ID exists in this tenant.');
76+
cy.get('cds-text-label[for=tenant]')
77+
.find('.invalid-feedback')
78+
.should('have.text', 'The chosen user ID exists in this tenant.');
7779

7880
// check that username field is marked invalid if username has been cleared off
7981
cy.get('#user_id').clear().blur().should('have.class', 'ng-invalid');
80-
cy.contains('#user_id + .invalid-feedback', 'This field is required.');
82+
cy.get('cds-text-label[for=user_id]')
83+
.find('.invalid-feedback')
84+
.should('have.text', 'This field is required.');
8185

8286
// Full name
8387
cy.get('#display_name')
@@ -88,16 +92,23 @@ export class UsersPageHelper extends PageHelper {
8892
.clear()
8993
.blur()
9094
.should('have.class', 'ng-invalid');
91-
cy.contains('#display_name + .invalid-feedback', 'This field is required.');
95+
cy.get('cds-text-label[for=display_name]')
96+
.find('.invalid-feedback')
97+
.should('have.text', 'This field is required.');
9298

9399
// put invalid email to make field invalid
94100
cy.get('#email').type('a').blur().should('have.class', 'ng-invalid');
95-
cy.contains('#email + .invalid-feedback', 'This is not a valid email address.');
101+
cy.get('cds-text-label[for=email]')
102+
.find('.invalid-feedback')
103+
.should('have.text', 'This is not a valid email address.');
96104

97105
// put negative max buckets to make field invalid
98106
this.expectSelectOption('max_buckets_mode', 'Custom');
99-
cy.get('#max_buckets').clear().type('-5').blur().should('have.class', 'ng-invalid');
100-
cy.contains('#max_buckets + .invalid-feedback', 'The entered value must be >= 1.');
107+
cy.get('input#max_buckets').clear().type('-5').blur();
108+
cy.get('#max_buckets').should('have.class', 'ng-invalid');
109+
cy.get('cds-number[for=max_buckets]')
110+
.find('.invalid-feedback')
111+
.should('have.text', 'The entered value must be >= 1.');
101112

102113
this.navigateTo();
103114
this.delete(tenant + '$' + uname, null, null, true, true);
@@ -119,19 +130,27 @@ export class UsersPageHelper extends PageHelper {
119130
.blur()
120131
.should('not.have.class', 'ng-pending')
121132
.should('have.class', 'ng-invalid');
122-
cy.contains('#email + .invalid-feedback', 'This is not a valid email address.');
133+
134+
cy.get('cds-text-label[for=email]')
135+
.find('.invalid-feedback')
136+
.should('have.text', 'This is not a valid email address.');
123137

124138
// empty the display name field making it invalid
125-
cy.get('#display_name').clear().blur().should('have.class', 'ng-invalid');
126-
cy.contains('#display_name + .invalid-feedback', 'This field is required.');
139+
cy.get('#display_name').clear({ force: true }).blur().should('have.class', 'ng-invalid');
140+
cy.get('cds-text-label[for=display_name]')
141+
.find('.invalid-feedback')
142+
.should('have.text', 'This field is required.');
127143

128144
// put negative max buckets to make field invalid
129145
this.selectOption('max_buckets_mode', 'Disabled');
130-
cy.get('#max_buckets').should('not.exist');
146+
cy.get('input#max_buckets').should('not.exist');
131147
this.selectOption('max_buckets_mode', 'Custom');
132-
cy.get('#max_buckets').should('exist').should('have.value', '50');
133-
cy.get('#max_buckets').clear().type('-5').blur().should('have.class', 'ng-invalid');
134-
cy.contains('#max_buckets + .invalid-feedback', 'The entered value must be >= 1.');
148+
cy.get('input#max_buckets').should('exist').should('have.value', '50');
149+
cy.get('input#max_buckets').clear().type('-5').blur();
150+
cy.get('#max_buckets').should('have.class', 'ng-invalid');
151+
cy.get('cds-number[for=max_buckets]')
152+
.find('.invalid-feedback')
153+
.should('have.text', 'The entered value must be >= 1.');
135154

136155
this.navigateTo();
137156
this.delete(tenant + '$' + uname, null, null, true, true);
Lines changed: 72 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,75 @@
1-
<cd-modal [modalRef]="activeModal">
2-
<span class="modal-title"
3-
i18n>{{ getMode() }} Tag</span>
1+
<cds-modal size="md"
2+
[open]="open"
3+
[hasScrollingContent]="false"
4+
(overlaySelected)="closeModal()">
45

5-
<ng-container class="modal-content">
6-
<form class="form"
7-
#formDir="ngForm"
8-
[formGroup]="form">
9-
<div class="modal-body">
10-
<!-- Key -->
11-
<div class="form-group row">
12-
<label class="cd-col-form-label required"
13-
for="key"
14-
i18n>Key</label>
15-
<div class="cd-col-form-input">
16-
<input type="text"
17-
class="form-control"
18-
formControlName="key"
19-
id="key">
20-
<span class="invalid-feedback"
21-
*ngIf="form.showError('key', formDir, 'required')"
22-
i18n>This field is required.</span>
23-
<span class="invalid-feedback"
24-
*ngIf="form.showError('key', formDir, 'unique')"
25-
i18n>This key must be unique.</span>
26-
<span class="invalid-feedback"
27-
*ngIf="form.showError('key', formDir, 'maxLength')"
28-
i18n>Length of the key must be maximum of 128 characters</span>
29-
</div>
30-
</div>
6+
<cds-modal-header (closeSelect)="closeModal()">
7+
<h3 cdsModalHeaderHeading
8+
i18n>{{ getMode() }} Tag</h3>
9+
</cds-modal-header>
3110

32-
<!-- Value -->
33-
<div class="form-group row">
34-
<label class="cd-col-form-label required"
35-
for="value"
36-
i18n>Value</label>
37-
<div class="cd-col-form-input">
38-
<input id="value"
39-
class="form-control"
40-
type="text"
41-
formControlName="value">
42-
<span *ngIf="form.showError('value', formDir, 'required')"
43-
class="invalid-feedback"
44-
i18n>This field is required.</span>
45-
<span class="invalid-feedback"
46-
*ngIf="form.showError('value', formDir, 'maxLength')"
47-
i18n>Length of the value must be a maximum of 128 characters</span>
48-
</div>
49-
</div>
50-
</div>
11+
<form class="form"
12+
#formDir="ngForm"
13+
[formGroup]="form">
14+
<div cdsModalContent>
15+
<!-- Key -->
16+
<div class="form-item">
17+
<cds-text-label label="Key"
18+
for="key"
19+
cdRequiredField="Key"
20+
[invalid]="form.controls.key.invalid && form.controls.key.dirty"
21+
[invalidText]="keyError">Key
22+
<input cdsText
23+
type="text"
24+
id="key"
25+
name="key"
26+
formControlName="key"
27+
[invalid]="form.controls.key.invalid && form.controls.key.dirty"
28+
[autofocus]="true"
29+
modal-primary-focus>
30+
</cds-text-label>
31+
<ng-template #keyError>
32+
<span class="invalid-feedback"
33+
*ngIf="form.showError('key', formDir, 'required')"
34+
i18n>This field is required.</span>
35+
<span class="invalid-feedback"
36+
*ngIf="form.showError('key', formDir, 'unique')"
37+
i18n>This key must be unique.</span>
38+
<span class="invalid-feedback"
39+
*ngIf="form.showError('key', formDir, 'maxLength')"
40+
i18n>Length of the key must be maximum of 128 characters</span>
41+
</ng-template>
42+
</div>
5143

52-
<div class="modal-footer">
53-
<cd-form-button-panel (submitActionEvent)="onSubmit()"
54-
[form]="form"
55-
[submitText]="getMode()"></cd-form-button-panel>
56-
</div>
57-
</form>
58-
</ng-container>
59-
</cd-modal>
44+
<!-- Value -->
45+
<div class="form-item">
46+
<cds-text-label label="Value"
47+
for="value"
48+
cdRequiredField="Value"
49+
[invalid]="form.controls.value.invalid && form.controls.value.dirty"
50+
[invalidText]="valueError">Value
51+
<input cdsText
52+
type="text"
53+
id="value"
54+
name="value"
55+
formControlName="value"
56+
[invalid]="form.controls.value.invalid && form.controls.value.dirty">
57+
</cds-text-label>
58+
<ng-template #valueError>
59+
<span class="invalid-feedback"
60+
*ngIf="form.showError('value', formDir, 'required')"
61+
i18n>This field is required.</span>
62+
<span class="invalid-feedback"
63+
*ngIf="form.showError('value', formDir, 'maxLength')"
64+
i18n>Length of the value must be a maximum of 128 characters</span>
65+
</ng-template>
66+
</div>
67+
68+
</div>
69+
70+
<cd-form-button-panel (submitActionEvent)="onSubmit()"
71+
[form]="form"
72+
[submitText]="getMode()"
73+
[modalForm]="true"></cd-form-button-panel>
74+
</form>
75+
</cds-modal>

src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/bucket-tag-modal/bucket-tag-modal.component.ts

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Component, EventEmitter, Output } from '@angular/core';
22
import { Validators } from '@angular/forms';
3-
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
3+
import { BaseModal } from 'carbon-components-angular';
44
import _ from 'lodash';
55
import { ActionLabelsI18n } from '~/app/shared/constants/app.constants';
66
import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
@@ -12,7 +12,7 @@ import { CdValidators } from '~/app/shared/forms/cd-validators';
1212
templateUrl: './bucket-tag-modal.component.html',
1313
styleUrls: ['./bucket-tag-modal.component.scss']
1414
})
15-
export class BucketTagModalComponent {
15+
export class BucketTagModalComponent extends BaseModal {
1616
@Output()
1717
submitAction = new EventEmitter();
1818

@@ -21,11 +21,8 @@ export class BucketTagModalComponent {
2121
currentKeyTags: string[];
2222
storedKey: string;
2323

24-
constructor(
25-
private formBuilder: CdFormBuilder,
26-
public activeModal: NgbActiveModal,
27-
public actionLabels: ActionLabelsI18n
28-
) {
24+
constructor(private formBuilder: CdFormBuilder, public actionLabels: ActionLabelsI18n) {
25+
super();
2926
this.createForm();
3027
}
3128

@@ -62,7 +59,7 @@ export class BucketTagModalComponent {
6259

6360
onSubmit() {
6461
this.submitAction.emit(this.form.value);
65-
this.activeModal.close();
62+
this.closeModal();
6663
}
6764

6865
getMode() {

0 commit comments

Comments
 (0)