From 1091a9d516e3dbe044f0df012378d117ace52bc8 Mon Sep 17 00:00:00 2001 From: Nizamudeen A Date: Tue, 9 Jul 2024 14:48:21 +0530 Subject: [PATCH] mgr/dashboard: carbonize cephfs forms This commit also covers the nfs form Fixes: https://tracker.ceph.com/issues/67663 Signed-off-by: Nizamudeen A --- .../cypress/e2e/cluster/services.po.ts | 1 + .../e2e/common/forms-helper.feature.po.ts | 15 +- .../filesystems/snapshots.e2e-spec.feature | 6 +- .../subvolume-groups.e2e-spec.feature | 4 +- .../filesystems/subvolumes.e2e-spec.feature | 4 +- .../workflow/nfs/nfs-export.po.ts | 4 +- .../frontend/cypress/e2e/page-helper.po.ts | 1 + .../bootstrap-import-modal.component.html | 8 +- .../pool-edit-mode-modal.component.html | 2 +- .../pool-edit-peer-modal.component.html | 16 +- .../rbd-configuration-form.component.html | 8 +- .../block/rbd-form/rbd-form.component.html | 23 +- .../rbd-namespace-form-modal.component.html | 7 +- .../rbd-snapshot-form-modal.component.html | 4 +- .../rbd-trash-move-modal.component.html | 5 +- .../cephfs-auth-modal.component.html | 280 +++--- .../cephfs-auth-modal.component.spec.ts | 11 +- .../cephfs-auth-modal.component.ts | 42 +- .../cephfs-clients.component.ts | 10 +- .../cephfs-directories.component.spec.ts | 8 +- .../cephfs-directories.component.ts | 14 +- .../cephfs-form/cephfs-form.component.html | 176 ++-- .../cephfs-form/cephfs-form.component.spec.ts | 7 +- .../cephfs-form/cephfs-form.component.ts | 72 +- .../cephfs-list/cephfs-list.component.ts | 15 +- .../cephfs-mount-details.component.html | 69 +- .../cephfs-mount-details.component.ts | 19 +- ...ephfs-snapshotschedule-form.component.html | 288 +++--- ...ephfs-snapshotschedule-form.component.scss | 3 + ...fs-snapshotschedule-form.component.spec.ts | 35 +- .../cephfs-snapshotschedule-form.component.ts | 74 +- ...ephfs-snapshotschedule-list.component.html | 8 +- .../cephfs-snapshotschedule-list.component.ts | 28 +- .../cephfs-subvolume-form.component.html | 230 +++-- .../cephfs-subvolume-form.component.spec.ts | 9 +- .../cephfs-subvolume-form.component.ts | 22 +- .../cephfs-subvolume-group.component.ts | 19 +- .../cephfs-subvolume-list.component.ts | 28 +- ...fs-subvolume-snapshots-form.component.html | 125 ++- ...subvolume-snapshots-form.component.spec.ts | 7 +- ...phfs-subvolume-snapshots-form.component.ts | 18 +- ...phfs-subvolume-snapshots-list.component.ts | 28 +- .../cephfs-subvolumegroup-form.component.html | 182 ++-- ...phfs-subvolumegroup-form.component.spec.ts | 7 +- .../cephfs-subvolumegroup-form.component.ts | 20 +- .../src/app/ceph/cephfs/cephfs.module.ts | 43 +- .../app/ceph/cluster/hosts/hosts.component.ts | 4 +- .../nfs-form-client.component.html | 135 +-- .../ceph/nfs/nfs-form/nfs-form.component.html | 866 +++++++++--------- .../ceph/nfs/nfs-form/nfs-form.component.ts | 6 + .../frontend/src/app/ceph/nfs/nfs.module.ts | 27 +- .../alert-panel/alert-panel.component.html | 2 +- .../shared/components/components.module.ts | 12 +- ...critical-confirmation-modal.component.html | 2 + ...tical-confirmation-modal.component.spec.ts | 1 - .../critical-confirmation-modal.component.ts | 2 +- .../date-time-picker.component.html | 10 +- .../date-time-picker.component.ts | 11 +- .../form-button-panel.component.html | 38 +- .../form-modal/form-modal.component.html | 170 ++-- .../form-modal/form-modal.component.spec.ts | 48 +- .../form-modal/form-modal.component.ts | 41 +- .../submit-button.component.html | 4 +- .../submit-button.component.scss | 3 + .../directives/required-field.directive.ts | 2 + .../frontend/src/app/shared/forms/cd-form.ts | 8 +- .../app/shared/models/snapshot-schedule.ts | 4 +- .../frontend/src/styles/_carbon-defaults.scss | 8 +- .../src/styles/bootstrap-extends.scss | 7 - .../src/styles/ceph-custom/_basics.scss | 9 +- .../src/styles/ceph-custom/_forms.scss | 6 + .../frontend/src/styles/themes/_content.scss | 3 +- .../frontend/src/styles/themes/_default.scss | 1 + 73 files changed, 1752 insertions(+), 1683 deletions(-) diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/cluster/services.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/e2e/cluster/services.po.ts index 5965e6402ee84..4cb5223d46ac2 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/cluster/services.po.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/cluster/services.po.ts @@ -107,6 +107,7 @@ export class ServicesPageHelper extends PageHelper { : cy.get('#count').clear().type(String(count)); break; } + cy.wait(1000); if (serviceType === 'snmp-gateway') { cy.get('cd-submit-button').dblclick(); } else { diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/common/forms-helper.feature.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/e2e/common/forms-helper.feature.po.ts index ce09614c99e0f..a43a304c680d4 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/common/forms-helper.feature.po.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/common/forms-helper.feature.po.ts @@ -6,9 +6,7 @@ import { And, Then } from 'cypress-cucumber-preprocessor/steps'; * @param value Value that should be filled in the field. */ And('enter {string} {string}', (field: string, value: string) => { - cy.get('.cd-col-form').within(() => { - cy.get(`input[id=${field}]`).clear().type(value); - }); + cy.get(`input[id=${field}]`).clear().type(value); }); /** @@ -22,6 +20,17 @@ And('enter {string} {string} in the modal', (field: string, value: string) => { }); }); +/** + * Fills in the given field using the value provided in carbon modal + * @param field ID of the field that needs to be filled out. + * @param value Value that should be filled in the field. + */ +And('enter {string} {string} in the carbon modal', (field: string, value: string) => { + cy.get('cds-modal').within(() => { + cy.get(`input[id=${field}]`).clear().type(value); + }); +}); + And('select options {string}', (labels: string) => { if (labels) { cy.get('a[data-testid=select-menu-edit]').click(); diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/filesystems/snapshots.e2e-spec.feature b/src/pybind/mgr/dashboard/frontend/cypress/e2e/filesystems/snapshots.e2e-spec.feature index 4f523bda4ef78..67f0e10cb0020 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/filesystems/snapshots.e2e-spec.feature +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/filesystems/snapshots.e2e-spec.feature @@ -23,7 +23,7 @@ Feature: CephFS Snapshot Management When I expand the row "test_cephfs" And I go to the "Subvolumes" tab And I click on "Create" button from the expanded row - And enter "subvolumeName" "test_subvolume" in the modal + And enter "subvolumeName" "test_subvolume" in the carbon modal And I click on "Create Subvolume" button Then I should see a row with "test_subvolume" in the expanded row @@ -38,7 +38,7 @@ Feature: CephFS Snapshot Management When I expand the row "test_cephfs" And I go to the "Snapshots" tab And I click on "Create" button from the expanded row - And enter "snapshotName" "test_snapshot" in the modal + And enter "snapshotName" "test_snapshot" in the carbon modal And I click on "Create Snapshot" button Then I should see a row with "test_snapshot" in the expanded row @@ -48,7 +48,7 @@ Feature: CephFS Snapshot Management And I go to the "Snapshots" tab And I select a row "test_snapshot" in the expanded row And I click on "Clone" button from the table actions in the expanded row - And enter "cloneName" "test_clone" in the modal + And enter "cloneName" "test_clone" in the carbon modal And I click on "Create Clone" button Then I wait for "5" seconds And I go to the "Subvolumes" tab diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/filesystems/subvolume-groups.e2e-spec.feature b/src/pybind/mgr/dashboard/frontend/cypress/e2e/filesystems/subvolume-groups.e2e-spec.feature index 6b3f119c87f71..cc0835146b7b2 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/filesystems/subvolume-groups.e2e-spec.feature +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/filesystems/subvolume-groups.e2e-spec.feature @@ -17,7 +17,7 @@ Feature: CephFS Subvolume Group management When I expand the row "test_cephfs" And I go to the "Subvolume groups" tab And I click on "Create" button from the expanded row - And enter "subvolumegroupName" "test_subvolume_group" in the modal + And enter "subvolumegroupName" "test_subvolume_group" in the carbon modal And I click on "Create Subvolume group" button Then I should see a row with "test_subvolume_group" in the expanded row @@ -27,7 +27,7 @@ Feature: CephFS Subvolume Group management And I go to the "Subvolume groups" tab When I select a row "test_subvolume_group" in the expanded row And I click on "Edit" button from the table actions in the expanded row - And enter "size" "1" in the modal + And enter "size" "1" in the carbon modal And I click on "Edit Subvolume group" button Then I should see row "test_subvolume_group" of the expanded row to have a usage bar diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/filesystems/subvolumes.e2e-spec.feature b/src/pybind/mgr/dashboard/frontend/cypress/e2e/filesystems/subvolumes.e2e-spec.feature index 42e30c3b7e4a4..cf3df6e3f3069 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/filesystems/subvolumes.e2e-spec.feature +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/filesystems/subvolumes.e2e-spec.feature @@ -17,7 +17,7 @@ Feature: CephFS Subvolume management When I expand the row "test_cephfs" And I go to the "Subvolumes" tab And I click on "Create" button from the expanded row - And enter "subvolumeName" "test_subvolume" in the modal + And enter "subvolumeName" "test_subvolume" in the carbon modal And I click on "Create Subvolume" button Then I should see a row with "test_subvolume" in the expanded row @@ -27,7 +27,7 @@ Feature: CephFS Subvolume management And I go to the "Subvolumes" tab When I select a row "test_subvolume" in the expanded row And I click on "Edit" button from the table actions in the expanded row - And enter "size" "1" in the modal + And enter "size" "1" in the carbon modal And I click on "Edit Subvolume" button Then I should see row "test_subvolume" of the expanded row to have a usage bar diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/nfs/nfs-export.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/nfs/nfs-export.po.ts index e13d34d00d4e3..4fd9feecd12c9 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/nfs/nfs-export.po.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/orchestrator/workflow/nfs/nfs-export.po.ts @@ -17,7 +17,7 @@ export class NFSPageHelper extends PageHelper { this.selectOption('fs_name', 'myfs'); cy.get('#security_label').click({ force: true }); } else { - cy.get('input[data-testid=rgw_path]').type(rgwPath); + cy.get('input[id=path]').type(rgwPath); } cy.get('input[name=pseudo]').type(pseudo); @@ -28,7 +28,7 @@ export class NFSPageHelper extends PageHelper { cy.get('input[name=addresses]').type(client['addresses']); // Check if we can remove clients and add it again - cy.get('span[name=remove_client]').click({ force: true }); + cy.get('[data-testid=remove_client]').click({ force: true }); cy.get('button[name=add_client]').click({ force: true }); cy.get('input[name=addresses]').type(client['addresses']); diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/page-helper.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/e2e/page-helper.po.ts index af9f0d3e20946..d8eca28f25ba5 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/page-helper.po.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/page-helper.po.ts @@ -311,6 +311,7 @@ export abstract class PageHelper { .parent('[cdstablerow]') .find('[cdstabledata] [data-testid="table-action-btn"]') .click({ force: true }); + cy.wait(waitTime); cy.get(`button.${action}`).click({ force: true }); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html index 8ba67c5312f6f..07b0bebe951a1 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/bootstrap-import-modal/bootstrap-import-modal.component.html @@ -24,7 +24,7 @@ Site Name @@ -76,7 +76,7 @@
Token @@ -87,7 +87,7 @@ formControlName="token" cols="200" rows="5" - [invalid]="importBootstrapForm.controls['token'].invalid && (importBootstrapForm.controls['token'].dirty || importBootstrapForm.controls['token'].touched)"> + [invalid]="importBootstrapForm.controls['token'].invalid && (importBootstrapForm.controls['token'].dirty)"> diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html index bd0151b2f009b..8c25db391862d 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-mode-modal/pool-edit-mode-modal.component.html @@ -24,7 +24,7 @@ formControlName="mirrorMode" name="mirrorMode" id="mirrorMode" - [invalid]="editModeForm.controls['mirrorMode'].invalid && (editModeForm.controls['mirrorMode'].dirty || editModeForm.controls['mirrorMode'].touched)" + [invalid]="editModeForm.controls['mirrorMode'].invalid && (editModeForm.controls['mirrorMode'].dirty)" [invalidText]="mirrorModeError" cdRequiredField="Mode" i18n> diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html index 8999510a4ff9a..9bbc298dd96ac 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/mirroring/pool-edit-peer-modal/pool-edit-peer-modal.component.html @@ -23,7 +23,7 @@
Cluster Name @@ -34,7 +34,7 @@ id="clusterName" name="clusterName" formControlName="clusterName" - [invalid]="editPeerForm.controls['clusterName'].invalid && (editPeerForm.controls['clusterName'].dirty || editPeerForm.controls['clusterName'].touched)" + [invalid]="editPeerForm.controls['clusterName'].invalid && (editPeerForm.controls['clusterName'].dirty)" autofocus> @@ -49,7 +49,7 @@
CephX ID @@ -60,7 +60,7 @@ id="clientID" name="clientID" formControlName="clientID" - [invalid]="editPeerForm.controls['clientID'].invalid && (editPeerForm.controls['clientID'].dirty || editPeerForm.controls['clientID'].touched)"> + [invalid]="editPeerForm.controls['clientID'].invalid && (editPeerForm.controls['clientID'].dirty)"> Monitor Addresses + [invalid]="editPeerForm.controls['monAddr'].invalid && (editPeerForm.controls['monAddr'].dirty)"> CephX Key + [invalid]="editPeerForm.controls['key'].invalid && (editPeerForm.controls['key'].dirty)">
{{ option.displayName }} @@ -28,7 +28,7 @@
type="text" cdsText [ngDataReady]="ngDataReady" - [invalid]="form.get('configuration').controls[option.name].invalid && (form.get('configuration').controls[option.name].dirty || form.get('configuration').controls[option.name].touched)" + [invalid]="form.get('configuration').controls[option.name].invalid && (form.get('configuration').controls[option.name].dirty)" cdMilliseconds> @@ -39,7 +39,7 @@
cdsText defaultUnit="b" [ngDataReady]="ngDataReady" - [invalid]="form.get('configuration').controls[option.name].invalid && (form.get('configuration').controls[option.name].dirty || form.get('configuration').controls[option.name].touched)" + [invalid]="form.get('configuration').controls[option.name].invalid && (form.get('configuration').controls[option.name].dirty)" cdDimlessBinaryPerSecond> @@ -49,7 +49,7 @@
type="text" cdsText [ngDataReady]="ngDataReady" - [invalid]="form.get('configuration').controls[option.name].invalid && (form.get('configuration').controls[option.name].dirty || form.get('configuration').controls[option.name].touched)" + [invalid]="form.get('configuration').controls[option.name].invalid && (form.get('configuration').controls[option.name].dirty)" cdIops> diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.html index bb36941f7a70a..67192f5d338ca 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.html @@ -25,7 +25,7 @@
- @@ -68,7 +68,7 @@ id="pool" formControlName="pool" cdRequiredField="Pool" - [invalid]="!rbdForm.controls['pool'].valid && (rbdForm.controls['pool'].dirty || rbdForm.controls['pool'].touched)" + [invalid]="!rbdForm.controls['pool'].valid && (rbdForm.controls['pool'].dirty)" [invalidText]="poolError" *ngIf="mode !== 'editing' && poolPermission.read">
- + - {{ action | titlecase }} {{ resource | upperFirst }} - -
-
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-form/cephfs-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-form/cephfs-form.component.spec.ts index 3bcedd1cd6693..9b817795354b8 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-form/cephfs-form.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-form/cephfs-form.component.spec.ts @@ -10,6 +10,7 @@ import { ReactiveFormsModule } from '@angular/forms'; import { By } from '@angular/platform-browser'; import { OrchestratorService } from '~/app/shared/api/orchestrator.service'; import { of } from 'rxjs'; +import { ComboBoxModule, GridModule, InputModule, SelectModule } from 'carbon-components-angular'; describe('CephfsVolumeFormComponent', () => { let component: CephfsVolumeFormComponent; @@ -24,7 +25,11 @@ describe('CephfsVolumeFormComponent', () => { HttpClientTestingModule, RouterTestingModule, ReactiveFormsModule, - ToastrModule.forRoot() + ToastrModule.forRoot(), + GridModule, + InputModule, + SelectModule, + ComboBoxModule ], declarations: [CephfsVolumeFormComponent] }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-form/cephfs-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-form/cephfs-form.component.ts index 0506c4c77341f..3b99541418afc 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-form/cephfs-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-form/cephfs-form.component.ts @@ -4,14 +4,12 @@ import { ActivatedRoute, Router } from '@angular/router'; import _ from 'lodash'; import { NgbNav, NgbTooltip, NgbTypeahead } from '@ng-bootstrap/ng-bootstrap'; -import { merge, Observable, Subject } from 'rxjs'; -import { debounceTime, distinctUntilChanged, filter, map } from 'rxjs/operators'; +import { forkJoin, Observable, Subject } from 'rxjs'; +import { map } from 'rxjs/operators'; import { CephfsService } from '~/app/shared/api/cephfs.service'; import { HostService } from '~/app/shared/api/host.service'; import { OrchestratorService } from '~/app/shared/api/orchestrator.service'; -import { SelectMessages } from '~/app/shared/components/select/select-messages.model'; -import { SelectOption } from '~/app/shared/components/select/select-option.model'; import { ActionLabelsI18n, URLVerbs } from '~/app/shared/constants/app.constants'; import { Icons } from '~/app/shared/enum/icons.enum'; import { CdForm } from '~/app/shared/forms/cd-form'; @@ -48,15 +46,19 @@ export class CephfsVolumeFormComponent extends CdForm implements OnInit { editing: boolean; icons = Icons; hosts: any; - labels: string[]; + labels: any; hasOrchestrator: boolean; currentVolumeName: string; fsId: number; disableRename: boolean = true; + hostsAndLabels$: Observable<{ hosts: any[]; labels: any[] }>; fsFailCmd: string; fsSetCmd: string; + selectedLabels: string[] = []; + selectedHosts: string[] = []; + constructor( private router: Router, private taskWrapperService: TaskWrapperService, @@ -71,20 +73,10 @@ export class CephfsVolumeFormComponent extends CdForm implements OnInit { this.editing = this.router.url.startsWith(`/cephfs/fs/${URLVerbs.EDIT}`); this.action = this.editing ? this.actionLabels.EDIT : this.actionLabels.CREATE; this.resource = $localize`File System`; - this.hosts = { - options: [], - messages: new SelectMessages({ - empty: $localize`There are no hosts.`, - filter: $localize`Filter hosts` - }) - }; this.createForm(); } private createForm() { - this.orchService.status().subscribe((status) => { - this.hasOrchestrator = status.available; - }); this.form = this.formBuilder.group({ name: new FormControl('', { validators: [ @@ -92,7 +84,7 @@ export class CephfsVolumeFormComponent extends CdForm implements OnInit { Validators.required ] }), - placement: ['hosts'], + placement: [''], hosts: [[]], label: [ null, @@ -105,6 +97,10 @@ export class CephfsVolumeFormComponent extends CdForm implements OnInit { ], unmanaged: [false] }); + this.orchService.status().subscribe((status) => { + this.hasOrchestrator = status.available; + this.form.get('placement').setValue(this.hasOrchestrator ? 'hosts' : ''); + }); } ngOnInit() { @@ -128,36 +124,24 @@ export class CephfsVolumeFormComponent extends CdForm implements OnInit { }); } else { const hostContext = new CdTableFetchDataContext(() => undefined); - this.hostService.list(hostContext.toParams(), 'false').subscribe((resp: object[]) => { - const options: SelectOption[] = []; - _.forEach(resp, (host: object) => { - if (_.get(host, 'sources.orchestrator', false)) { - const option = new SelectOption(false, _.get(host, 'hostname'), ''); - options.push(option); - } - }); - this.hosts.options = [...options]; - }); - this.hostService.getLabels().subscribe((resp: string[]) => { - this.labels = resp; - }); + this.hostsAndLabels$ = forkJoin({ + hosts: this.hostService.list(hostContext.toParams(), 'false'), + labels: this.hostService.getLabels() + }).pipe( + map(({ hosts, labels }) => ({ + hosts: hosts.map((host: any) => ({ content: host['hostname'] })), + labels: labels.map((label: string) => ({ content: label })) + })) + ); } this.orchStatus$ = this.orchService.status(); + this.loadingReady(); } - searchLabels = (text$: Observable) => { - return merge( - text$.pipe(debounceTime(200), distinctUntilChanged()), - this.labelFocus, - this.labelClick.pipe(filter(() => !this.typeahead.isPopupOpen())) - ).pipe( - map((value) => - this.labels - .filter((label: string) => label.toLowerCase().indexOf(value.toLowerCase()) > -1) - .slice(0, 10) - ) - ); - }; + multiSelector(event: any, field: 'label' | 'hosts') { + if (field === 'label') this.selectedLabels = event.map((label: any) => label.content); + else this.selectedHosts = event.map((host: any) => host.content); + } submit() { const volumeName = this.form.get('name').value; @@ -188,11 +172,11 @@ export class CephfsVolumeFormComponent extends CdForm implements OnInit { switch (values['placement']) { case 'hosts': if (values['hosts'].length > 0) { - serviceSpec['placement']['hosts'] = values['hosts']; + serviceSpec['placement']['hosts'] = this.selectedHosts; } break; case 'label': - serviceSpec['placement']['label'] = values['label']; + serviceSpec['placement']['label'] = this.selectedLabels; break; } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts index 10a522db7d16e..41c1ff76fe416 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-list/cephfs-list.component.ts @@ -17,7 +17,6 @@ import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data import { CdTableSelection } from '~/app/shared/models/cd-table-selection'; import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; import { URLBuilderService } from '~/app/shared/services/url-builder.service'; -import { ModalService } from '~/app/shared/services/modal.service'; import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service'; import { FinishedTask } from '~/app/shared/models/finished-task'; import { NotificationService } from '~/app/shared/services/notification.service'; @@ -53,7 +52,7 @@ export class CephfsListComponent extends ListWithDetails implements OnInit { private router: Router, private urlBuilder: URLBuilderService, private configurationService: ConfigurationService, - private modalService: ModalService, + private modalService: ModalCdsService, private taskWrapper: TaskWrapperService, public notificationService: NotificationService, private healthService: HealthService, @@ -199,13 +198,9 @@ export class CephfsListComponent extends ListWithDetails implements OnInit { authorizeModal() { const selectedFileSystem = this.selection?.selected?.[0]; - this.modalService.show( - CephfsAuthModalComponent, - { - fsName: selectedFileSystem.mdsmap['fs_name'], - id: selectedFileSystem.id - }, - { size: 'lg' } - ); + this.modalService.show(CephfsAuthModalComponent, { + fsName: selectedFileSystem.mdsmap['fs_name'], + id: selectedFileSystem.id + }); } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-mount-details/cephfs-mount-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-mount-details/cephfs-mount-details.component.html index a8c30afb1ebae..de9ed376fc453 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-mount-details/cephfs-mount-details.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-mount-details/cephfs-mount-details.component.html @@ -1,38 +1,37 @@ - - - Attach commands - - - - - - + + +

+ Attach commands +

+
+
+
+ Using Mount command +
+ +
+ Using FUSE command +
+ +
+ Using NFS Command +
+ +
+ +
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-mount-details/cephfs-mount-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-mount-details/cephfs-mount-details.component.ts index 843b000b2fa12..94c263de10d8d 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-mount-details/cephfs-mount-details.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-mount-details/cephfs-mount-details.component.ts @@ -1,19 +1,21 @@ -import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild } from '@angular/core'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; +import { BaseModal } from 'carbon-components-angular'; @Component({ selector: 'cd-cephfs-mount-details', templateUrl: './cephfs-mount-details.component.html', styleUrls: ['./cephfs-mount-details.component.scss'] }) -export class CephfsMountDetailsComponent implements OnInit, OnDestroy { +export class CephfsMountDetailsComponent extends BaseModal implements OnInit { @ViewChild('mountDetailsTpl', { static: true }) mountDetailsTpl: any; onCancel?: Function; - private canceled = false; private MOUNT_DIRECTORY = ''; mountData!: Record; - constructor(public activeModal: NgbActiveModal) {} + constructor(public activeModal: NgbActiveModal) { + super(); + } mount!: string; fuse!: string; nfs!: string; @@ -24,14 +26,7 @@ export class CephfsMountDetailsComponent implements OnInit, OnDestroy { this.nfs = `sudo mount -t nfs -o port= : ${this.MOUNT_DIRECTORY}`; } - ngOnDestroy(): void { - if (this.onCancel && this.canceled) { - this.onCancel(); - } - } - cancel() { - this.canceled = true; - this.activeModal.close(); + this.closeModal(); } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-snapshotschedule-form/cephfs-snapshotschedule-form.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-snapshotschedule-form/cephfs-snapshotschedule-form.component.html index a67293e1138b5..1a611dc18d789 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-snapshotschedule-form/cephfs-snapshotschedule-form.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cephfs/cephfs-snapshotschedule-form/cephfs-snapshotschedule-form.component.html @@ -1,179 +1,165 @@ - - {{ action | titlecase }} {{ resource | upperFirst }} - -
-