Skip to content

Commit 68c9f16

Browse files
author
Dnyaneshwari
committed
mgr/dashboard: carbonize Cluster > Hosts form
Fixes: https://tracker.ceph.com/issues/68264 Signed-off-by: Dnyaneshwari Talwekar <[email protected]>
1 parent 7fb2819 commit 68c9f16

File tree

5 files changed

+128
-124
lines changed

5 files changed

+128
-124
lines changed

src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/cluster.module.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import {
99
CheckboxModule,
1010
ButtonModule,
1111
GridModule,
12-
ProgressIndicatorModule
12+
ProgressIndicatorModule,
13+
InputModule,
14+
ModalModule
1315
} from 'carbon-components-angular';
1416

1517
import { TreeModule } from '@circlon/angular-tree-component';
@@ -102,7 +104,9 @@ import { MultiClusterDetailsComponent } from './multi-cluster/multi-cluster-deta
102104
CheckboxModule,
103105
GridModule,
104106
ProgressIndicatorModule,
105-
ButtonModule
107+
ButtonModule,
108+
InputModule,
109+
ModalModule
106110
],
107111
declarations: [
108112
HostsComponent,
Lines changed: 103 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,104 @@
1-
<cd-modal [pageURL]="pageURL"
2-
[modalRef]="activeModal">
3-
<span class="modal-title"
4-
i18n>{{ action | titlecase }} {{ resource | upperFirst }}</span>
5-
6-
<ng-container class="modal-content">
7-
8-
<div *cdFormLoading="loading">
9-
<form name="hostForm"
10-
#formDir="ngForm"
11-
[formGroup]="hostForm"
12-
novalidate>
13-
14-
<div class="modal-body">
15-
16-
<!-- Hostname -->
17-
<div class="form-group row">
18-
<label class="cd-col-form-label required"
19-
for="hostname">
20-
<ng-container i18n>Hostname</ng-container>
21-
<cd-helper>
22-
<p i18n>To add multiple hosts at once, you can enter:</p>
23-
<ul>
24-
<li i18n>a comma-separated list of hostnames <samp>(e.g.: example-01,example-02,example-03)</samp>,</li>
25-
<li i18n>a range expression <samp>(e.g.: example-[01-03].ceph)</samp>,</li>
26-
<li i18n>a comma separated range expression <samp>(e.g.: example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)</samp></li>
27-
</ul>
28-
</cd-helper>
29-
</label>
30-
<div class="cd-col-form-input">
31-
<input class="form-control"
32-
type="text"
33-
placeholder="mon-123"
34-
id="hostname"
35-
name="hostname"
36-
formControlName="hostname"
37-
autofocus
38-
(keyup)="checkHostNameValue()">
39-
<span class="invalid-feedback"
40-
*ngIf="hostForm.showError('hostname', formDir, 'required')"
41-
i18n>This field is required.</span>
42-
<span class="invalid-feedback"
43-
*ngIf="hostForm.showError('hostname', formDir, 'uniqueName')"
44-
i18n>The chosen hostname is already in use.</span>
45-
</div>
46-
</div>
47-
48-
<!-- Address -->
49-
<div class="form-group row"
50-
*ngIf="!hostPattern">
51-
<label class="cd-col-form-label"
52-
for="addr"
53-
i18n>Network address</label>
54-
<div class="cd-col-form-input">
55-
<input class="form-control"
56-
type="text"
57-
placeholder="192.168.0.1"
58-
id="addr"
59-
name="addr"
60-
formControlName="addr">
61-
<span class="invalid-feedback"
62-
*ngIf="hostForm.showError('addr', formDir, 'pattern')"
63-
i18n>The value is not a valid IP address.</span>
64-
</div>
65-
</div>
66-
67-
<!-- Labels -->
68-
<div class="form-group row">
69-
<label i18n
70-
for="labels"
71-
class="cd-col-form-label">Labels</label>
72-
<div class="cd-col-form-input">
73-
<cd-select-badges id="labels"
74-
[data]="hostForm.controls.labels.value"
75-
[options]="labelsOption"
76-
[customBadges]="true"
77-
[messages]="messages">
78-
</cd-select-badges>
79-
</div>
80-
</div>
81-
82-
<!-- Maintenance Mode -->
83-
<div class="form-group row"
84-
*ngIf="!hideMaintenance">
85-
<div class="cd-col-form-offset">
86-
<div class="custom-control custom-checkbox">
87-
<input class="custom-control-input"
88-
id="maintenance"
89-
type="checkbox"
90-
formControlName="maintenance">
91-
<label class="custom-control-label"
92-
for="maintenance"
93-
i18n>Maintenance Mode</label>
94-
</div>
95-
</div>
96-
</div>
97-
</div>
98-
99-
<div class="modal-footer">
100-
<cd-form-button-panel (submitActionEvent)="submit()"
101-
[form]="hostForm"
102-
[submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"
103-
wrappingClass="text-right"></cd-form-button-panel>
104-
</div>
105-
</form>
1+
<cds-modal size="md"
2+
[open]="open"
3+
[hasScrollingContent]="true"
4+
(overlaySelected)="closeModal()">
5+
<cds-modal-header (closeSelect)="closeModal()">
6+
<h3 cdsModalHeaderHeading
7+
i18n>{{ action | titlecase }} {{ resource | upperFirst }}</h3>
8+
</cds-modal-header>
9+
<ng-container *cdFormLoading="loading">
10+
<form name="hostForm"
11+
#formDir="ngForm"
12+
[formGroup]="hostForm"
13+
novalidate>
14+
<div cdsModalContent>
15+
<!-- Hostname -->
16+
<div class="form-item">
17+
<cds-text-label label="Hostname"
18+
for="hostname"
19+
cdRequiredField="Hostname"
20+
[invalid]="!hostForm.controls.hostname.valid && hostForm.controls.hostname.dirty"
21+
[invalidText]="hostnameError"
22+
i18n>Hostname
23+
<input cdsText
24+
type="text"
25+
placeholder="mon-123"
26+
id="hostname"
27+
name="hostname"
28+
formControlName="hostname"
29+
autofocus
30+
(keyup)="checkHostNameValue()">
31+
</cds-text-label>
32+
<ng-template #hostnameError>
33+
<span *ngIf="hostForm.showError('hostname', formDir, 'required')"
34+
class="invalid-feedback">
35+
<ng-container i18n> This field is required. </ng-container>
36+
</span>
37+
<span *ngIf="hostForm.showError('hostname', formDir, 'uniqueName')"
38+
class="invalid-feedback">
39+
<ng-container i18n> The chosen hostname is already in use. </ng-container>
40+
</span>
41+
</ng-template>
42+
<cd-help-text>
43+
To add multiple hosts at once, you can enter:
44+
<ul>
45+
<li>a comma-separated list of hostnames <samp>(e.g.: example-01,example-02,example-03)</samp>,</li>
46+
<li>a range expression <samp>(e.g.: example-[01-03].ceph)</samp>,</li>
47+
<li>a comma separated range expression <samp>(e.g.: example-[01-05].lab.com,example2-[1-4].lab.com,example3-[001-006].lab.com)</samp></li>
48+
</ul>
49+
</cd-help-text>
50+
</div>
51+
<!-- Address -->
52+
<div class="form-item"
53+
*ngIf="!hostPattern">
54+
<cds-text-label label="Network address"
55+
for="addr"
56+
i18n>Network address
57+
<input cdsText
58+
type="text"
59+
placeholder="192.168.0.1"
60+
id="addr"
61+
name="addr"
62+
formControlName="addr"/>
63+
</cds-text-label>
64+
<ng-template #hostaddrError>
65+
<span *ngIf="hostForm.showError('addr', formDir, 'pattern')">
66+
<ng-container i18n> The value is not a valid IP address. </ng-container>
67+
</span>
68+
</ng-template>
69+
</div>
70+
<!-- Labels -->
71+
<div class="form-item">
72+
<cds-combo-box label="Labels"
73+
type="multi"
74+
selectionFeedback="top-after-reopen"
75+
for="labels"
76+
name="labels"
77+
formControlName="labels"
78+
placeholder="Select Labels..."
79+
i18n-placeholder
80+
[appendInline]="true"
81+
[items]="labelsOption"
82+
itemValueKey="value"
83+
id="labels"
84+
i18n>
85+
<cds-dropdown-list></cds-dropdown-list>
86+
</cds-combo-box>
87+
</div>
88+
<!-- Maintenance Mode -->
89+
<div *ngIf="!hideMaintenance">
90+
<cds-checkbox id="maintenance"
91+
type="checkbox"
92+
formControlName="maintenance"
93+
i18n>Maintenance Mode
94+
</cds-checkbox>
95+
</div>
10696
</div>
107-
</ng-container>
108-
</cd-modal>
97+
<cd-form-button-panel (submitActionEvent)="submit()"
98+
[form]="hostForm"
99+
[submitText]="(action | titlecase) + ' ' + (resource | upperFirst)"
100+
[modalForm]="true">
101+
</cd-form-button-panel>
102+
</form>
103+
</ng-container>
104+
</cds-modal>

src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-form/host-form.component.spec.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { LoadingPanelComponent } from '~/app/shared/components/loading-panel/loa
1010
import { SharedModule } from '~/app/shared/shared.module';
1111
import { configureTestBed, FormHelper } from '~/testing/unit-test-helper';
1212
import { HostFormComponent } from './host-form.component';
13+
import { InputModule, ModalModule } from 'carbon-components-angular';
1314

1415
describe('HostFormComponent', () => {
1516
let component: HostFormComponent;
@@ -23,7 +24,9 @@ describe('HostFormComponent', () => {
2324
HttpClientTestingModule,
2425
RouterTestingModule,
2526
ReactiveFormsModule,
26-
ToastrModule.forRoot()
27+
ToastrModule.forRoot(),
28+
InputModule,
29+
ModalModule
2730
],
2831
declarations: [HostFormComponent],
2932
providers: [NgbActiveModal]
@@ -45,7 +48,7 @@ describe('HostFormComponent', () => {
4548

4649
it('should open the form in a modal', () => {
4750
const nativeEl = fixture.debugElement.nativeElement;
48-
expect(nativeEl.querySelector('cd-modal')).not.toBe(null);
51+
expect(nativeEl.querySelector('cds-modal')).not.toBe(null);
4952
});
5053

5154
it('should validate the network address is valid', fakeAsync(() => {

src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/host-form/host-form.component.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import { Component, OnInit } from '@angular/core';
22
import { UntypedFormControl, Validators } from '@angular/forms';
3-
import { Router } from '@angular/router';
4-
5-
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
3+
import { ActivatedRoute, Router } from '@angular/router';
64
import expand from 'brace-expansion';
75

86
import { HostService } from '~/app/shared/api/host.service';
@@ -15,13 +13,15 @@ import { CdValidators } from '~/app/shared/forms/cd-validators';
1513
import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
1614
import { FinishedTask } from '~/app/shared/models/finished-task';
1715
import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
16+
import { Location } from '@angular/common';
1817

1918
@Component({
2019
selector: 'cd-host-form',
2120
templateUrl: './host-form.component.html',
2221
styleUrls: ['./host-form.component.scss']
2322
})
2423
export class HostFormComponent extends CdForm implements OnInit {
24+
open: boolean = false;
2525
hostForm: CdFormGroup;
2626
action: string;
2727
resource: string;
@@ -46,17 +46,16 @@ export class HostFormComponent extends CdForm implements OnInit {
4646
private actionLabels: ActionLabelsI18n,
4747
private hostService: HostService,
4848
private taskWrapper: TaskWrapperService,
49-
public activeModal: NgbActiveModal
49+
private route: ActivatedRoute,
50+
private location: Location
5051
) {
5152
super();
5253
this.resource = $localize`host`;
5354
this.action = this.actionLabels.ADD;
5455
}
5556

5657
ngOnInit() {
57-
if (this.router.url.includes('hosts')) {
58-
this.pageURL = 'hosts';
59-
}
58+
this.open = this.route.outlet === 'modal';
6059
this.createForm();
6160
const hostContext = new CdTableFetchDataContext(() => undefined);
6261
this.hostService.list(hostContext.toParams(), 'false').subscribe((resp: any[]) => {
@@ -69,7 +68,7 @@ export class HostFormComponent extends CdForm implements OnInit {
6968
this.hostService.getLabels().subscribe((resp: string[]) => {
7069
const uniqueLabels = new Set(resp.concat(this.hostService.predefinedLabels));
7170
this.labelsOption = Array.from(uniqueLabels).map((label) => {
72-
return { enabled: true, name: label, selected: false, description: null };
71+
return { enabled: true, name: label, content: label, selected: false, description: null };
7372
});
7473
});
7574
}
@@ -94,7 +93,7 @@ export class HostFormComponent extends CdForm implements OnInit {
9493
validators: [CdValidators.ip()]
9594
}),
9695
labels: new UntypedFormControl([]),
97-
maintenance: new UntypedFormControl(false)
96+
maintenance: new UntypedFormControl()
9897
});
9998
}
10099

@@ -166,9 +165,13 @@ export class HostFormComponent extends CdForm implements OnInit {
166165
complete: () => {
167166
this.pageURL === 'hosts'
168167
? this.router.navigate([this.pageURL, { outlets: { modal: null } }])
169-
: this.activeModal.close();
168+
: this.location.back();
170169
}
171170
});
172171
});
173172
}
173+
174+
closeModal(): void {
175+
this.location.back();
176+
}
174177
}

src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/hosts/hosts.component.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import { Permissions } from '~/app/shared/models/permissions';
2929
import { EmptyPipe } from '~/app/shared/pipes/empty.pipe';
3030
import { AuthStorageService } from '~/app/shared/services/auth-storage.service';
3131
import { CdTableServerSideService } from '~/app/shared/services/cd-table-server-side.service';
32-
import { ModalService } from '~/app/shared/services/modal.service';
3332
import { NotificationService } from '~/app/shared/services/notification.service';
3433
import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service';
3534
import { URLBuilderService } from '~/app/shared/services/url-builder.service';
@@ -125,7 +124,6 @@ export class HostsComponent extends ListWithDetails implements OnDestroy, OnInit
125124
private emptyPipe: EmptyPipe,
126125
private hostService: HostService,
127126
private actionLabels: ActionLabelsI18n,
128-
private modalService: ModalService,
129127
private taskWrapper: TaskWrapperService,
130128
private router: Router,
131129
private notificationService: NotificationService,
@@ -153,7 +151,7 @@ export class HostsComponent extends ListWithDetails implements OnDestroy, OnInit
153151
click: () =>
154152
this.router.url.includes('/hosts')
155153
? this.router.navigate([BASE_URL, { outlets: { modal: [URLVerbs.ADD] } }])
156-
: (this.bsModalRef = this.modalService.show(HostFormComponent, {
154+
: (this.bsModalRef = this.cdsModalService.show(HostFormComponent, {
157155
hideMaintenance: this.hideMaintenance
158156
})),
159157
disable: (selection: CdTableSelection) => this.getDisable('add', selection)

0 commit comments

Comments
 (0)