From 6c25635be8c2ec0c2f637c4fe6952f781c1ad12c Mon Sep 17 00:00:00 2001 From: Nizamudeen A Date: Thu, 29 Aug 2024 11:46:58 +0530 Subject: [PATCH] mgr/dashboard: carbon datatable minor bug fixes - fixes empty white spaces in the table - fixes some tables detail component where it didn't had carbon table - fix the multi-site details view table not showing up - fix the nvmeof modals like namespace deletion not getting opened - fix the cached reload button status not showing correctly in rgw table - fix show button in the rgw users detail page broken - fix the multi-cluster list component issue where details component is not following carbon attributes - fixing the configuration page where it does a page reload on form submit. instead doing a table refresh - additionally fixed a validation issue in the service form fixes the test failures Fixes: https://tracker.ceph.com/issues/67788 Fixes: https://tracker.ceph.com/issues/67552 Signed-off-by: Nizamudeen A --- .../frontend/cypress/e2e/block/images.po.ts | 2 +- .../cypress/e2e/cluster/configuration.po.ts | 2 +- .../multi-cluster/multi-cluster.e2e-spec.ts | 5 +++ .../e2e/multi-cluster/multi-cluster.po.ts | 21 ++++++++++ .../frontend/cypress/e2e/page-helper.po.ts | 4 +- .../frontend/cypress/e2e/rgw/buckets.po.ts | 4 +- .../nvmeof-initiators-list.component.ts | 4 +- .../nvmeof-listeners-list.component.ts | 4 +- .../nvmeof-namespaces-list.component.ts | 4 +- .../rbd-details/rbd-details.component.html | 41 ++++++++++--------- .../block/rbd-list/rbd-list.component.html | 8 ++-- .../ceph/block/rbd-list/rbd-list.component.ts | 2 +- .../configuration-details.component.html | 3 +- .../create-cluster-review.component.html | 2 +- .../cluster/monitor/monitor.component.html | 2 +- .../multi-cluster-list.component.html | 16 ++++---- .../service-form/service-form.component.ts | 7 +++- .../rgw-bucket-details.component.html | 13 +++--- .../rgw-config-modal.component.ts | 8 ++-- .../rgw-configuration-page.component.html | 1 + .../rgw-configuration-page.component.ts | 38 +++++++++-------- .../rgw-multisite-details.component.html | 6 +-- .../rgw-user-details.component.html | 38 +++++++---------- .../rgw-user-details.component.spec.ts | 4 +- .../rgw-user-details.component.ts | 13 ++++++ .../shared/classes/list-with-details.class.ts | 2 +- .../classes/table-status-view-cache.spec.ts | 13 +++--- .../shared/classes/table-status-view-cache.ts | 6 +-- .../app/shared/classes/table-status.spec.ts | 2 +- .../src/app/shared/classes/table-status.ts | 5 ++- .../crud-table/crud-table.component.html | 2 +- .../table-actions.component.html | 35 ++++++++++++++++ .../table-actions.component.scss | 11 +++++ .../table-actions/table-actions.component.ts | 2 + .../datatable/table/table.component.html | 21 +++++----- 35 files changed, 226 insertions(+), 125 deletions(-) diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/block/images.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/e2e/block/images.po.ts index 2e2a9d545d2..7bac7d12bed 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/block/images.po.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/block/images.po.ts @@ -38,7 +38,7 @@ export class ImagesPageHelper extends PageHelper { cy.get('[data-cy=submitBtn]').click(); this.getExpandCollapseElement(newName).click(); - cy.get('.table.table-striped.table-bordered').contains('td', newSize); + cy.get('[data-testid=rbd-details-table]').contains('td', newSize); } // Selects RBD image and moves it to the trash, diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/cluster/configuration.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/e2e/cluster/configuration.po.ts index e55e9aa588d..82e79a676ec 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/cluster/configuration.po.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/cluster/configuration.po.ts @@ -75,7 +75,7 @@ export class ConfigurationPageHelper extends PageHelper { values.forEach((value) => { // iterates through list of values and // checks if the value appears in details with the correct number attatched - cy.contains('.table.table-striped.table-bordered', `${value[0]}\: ${value[1]}`); + cy.contains('[data-testid=config-details-table]', `${value[0]}\: ${value[1]}`); }); } } diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/multi-cluster/multi-cluster.e2e-spec.ts b/src/pybind/mgr/dashboard/frontend/cypress/e2e/multi-cluster/multi-cluster.e2e-spec.ts index 74f26df8e56..8d7bbd3bbe3 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/multi-cluster/multi-cluster.e2e-spec.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/multi-cluster/multi-cluster.e2e-spec.ts @@ -21,9 +21,11 @@ describe('Muti-cluster management page', () => { it('should authenticate the second cluster', () => { multiCluster.auth(url, alias, username, password); multiCluster.existTableCell(alias); + multiCluster.checkConnectionStatus(alias, 'CONNECTED'); }); it('should switch to the second cluster and back to hub', () => { + multiCluster.checkConnectionStatus(alias, 'CONNECTED'); dashboard.navigateTo(); cy.get('[data-testid="selected-cluster"]').click(); cy.get('[data-testid="select-a-cluster"]').contains(alias).click(); @@ -38,16 +40,19 @@ describe('Muti-cluster management page', () => { }); it('should reconnect the second cluster', () => { + multiCluster.checkConnectionStatus(alias, 'CONNECTED'); multiCluster.reconnect(alias, password); multiCluster.existTableCell(alias); }); it('should edit the second cluster', () => { + multiCluster.checkConnectionStatus(alias, 'CONNECTED'); multiCluster.edit(alias, editedAlias); multiCluster.existTableCell(editedAlias); }); it('should disconnect the second cluster', () => { + multiCluster.checkConnectionStatus(editedAlias, 'CONNECTED'); multiCluster.disconnect(editedAlias); multiCluster.existTableCell(editedAlias, false); }); diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/multi-cluster/multi-cluster.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/e2e/multi-cluster/multi-cluster.po.ts index b7e109fbbf4..5c683a947a6 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/multi-cluster/multi-cluster.po.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/multi-cluster/multi-cluster.po.ts @@ -10,6 +10,11 @@ const WAIT_TIMER = 1000; export class MultiClusterPageHelper extends PageHelper { pages = pages; + columnIndex = { + alias: 2, + connection: 3 + }; + auth(url: string, alias: string, username: string, password: string) { cy.contains('button', 'Connect').click(); cy.get('cd-multi-cluster-form').should('exist'); @@ -49,4 +54,20 @@ export class MultiClusterPageHelper extends PageHelper { }); cy.wait(WAIT_TIMER); } + + checkConnectionStatus(alias: string, expectedStatus = 'CONNECTED', shouldReload = true) { + let aliasIndex = this.columnIndex.alias; + let statusIndex = this.columnIndex.connection; + if (shouldReload) { + cy.reload(true, { log: true, timeout: 5 * 1000 }); + } + + this.getTableCell(aliasIndex, alias) + .parent() + .find(`[cdstabledata]:nth-child(${statusIndex}) .badge`) + .should(($ele) => { + const status = $ele.toArray().map((v) => v.innerText); + expect(status).to.include(expectedStatus); + }); + } } 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 af9f0d3e209..78c360f974d 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 @@ -251,7 +251,9 @@ export abstract class PageHelper { * Grabs striped tables */ getStatusTables() { - return cy.get('.table.table-striped'); + return cy.get( + '.cds--data-table--sort.cds--data-table--no-border.cds--data-table.cds--data-table--md' + ); } filterTable(name: string, option: string) { diff --git a/src/pybind/mgr/dashboard/frontend/cypress/e2e/rgw/buckets.po.ts b/src/pybind/mgr/dashboard/frontend/cypress/e2e/rgw/buckets.po.ts index 28c30e2f02f..9a44051f7b8 100644 --- a/src/pybind/mgr/dashboard/frontend/cypress/e2e/rgw/buckets.po.ts +++ b/src/pybind/mgr/dashboard/frontend/cypress/e2e/rgw/buckets.po.ts @@ -76,7 +76,7 @@ export class BucketsPageHelper extends PageHelper { this.getExpandCollapseElement(name).click(); // check its details table for edited owner field - cy.get('.table.table-striped.table-bordered').first().as('bucketDataTable'); + cy.get('[data-testid="rgw-bucket-details"]').first().as('bucketDataTable'); // Check versioning enabled: cy.get('@bucketDataTable').find('tr').its(0).find('td').last().as('versioningValueCell'); @@ -102,7 +102,7 @@ export class BucketsPageHelper extends PageHelper { this.getExpandCollapseElement(name).click(); // Check versioning enabled: - cy.get('.table.table-striped.table-bordered').first().as('bucketDataTable'); + cy.get('[data-testid="rgw-bucket-details"]').first().as('bucketDataTable'); cy.get('@bucketDataTable').find('tr').its(0).find('td').last().as('versioningValueCell'); cy.get('@versioningValueCell').should('have.text', this.versioningStateEnabled); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-list/nvmeof-initiators-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-list/nvmeof-initiators-list.component.ts index 2491ccc0cb8..fff38e6985a 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-list/nvmeof-initiators-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-initiators-list/nvmeof-initiators-list.component.ts @@ -10,7 +10,7 @@ import { FinishedTask } from '~/app/shared/models/finished-task'; import { NvmeofSubsystemInitiator } from '~/app/shared/models/nvmeof'; import { Permission } from '~/app/shared/models/permissions'; import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; -import { ModalService } from '~/app/shared/services/modal.service'; +import { ModalCdsService } from '~/app/shared/services/modal-cds.service'; import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service'; const BASE_URL = 'block/nvmeof/subsystems'; @@ -37,7 +37,7 @@ export class NvmeofInitiatorsListComponent implements OnInit, OnChanges { public actionLabels: ActionLabelsI18n, private authStorageService: AuthStorageService, private nvmeofService: NvmeofService, - private modalService: ModalService, + private modalService: ModalCdsService, private router: Router, private taskWrapper: TaskWrapperService ) { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-listeners-list/nvmeof-listeners-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-listeners-list/nvmeof-listeners-list.component.ts index 26b48d8aad9..3ece51f350d 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-listeners-list/nvmeof-listeners-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-listeners-list/nvmeof-listeners-list.component.ts @@ -11,7 +11,7 @@ import { FinishedTask } from '~/app/shared/models/finished-task'; import { NvmeofListener } from '~/app/shared/models/nvmeof'; import { Permission } from '~/app/shared/models/permissions'; import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; -import { ModalService } from '~/app/shared/services/modal.service'; +import { ModalCdsService } from '~/app/shared/services/modal-cds.service'; import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service'; const BASE_URL = 'block/nvmeof/subsystems'; @@ -33,7 +33,7 @@ export class NvmeofListenersListComponent implements OnInit, OnChanges { constructor( public actionLabels: ActionLabelsI18n, - private modalService: ModalService, + private modalService: ModalCdsService, private authStorageService: AuthStorageService, private taskWrapper: TaskWrapperService, private nvmeofService: NvmeofService, diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-namespaces-list/nvmeof-namespaces-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-namespaces-list/nvmeof-namespaces-list.component.ts index cbf963995dd..c40b538c820 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-namespaces-list/nvmeof-namespaces-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-namespaces-list/nvmeof-namespaces-list.component.ts @@ -13,7 +13,7 @@ import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe'; import { IopsPipe } from '~/app/shared/pipes/iops.pipe'; import { MbpersecondPipe } from '~/app/shared/pipes/mbpersecond.pipe'; import { AuthStorageService } from '~/app/shared/services/auth-storage.service'; -import { ModalService } from '~/app/shared/services/modal.service'; +import { ModalCdsService } from '~/app/shared/services/modal-cds.service'; import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service'; const BASE_URL = 'block/nvmeof/subsystems'; @@ -36,7 +36,7 @@ export class NvmeofNamespacesListComponent implements OnInit, OnChanges { constructor( public actionLabels: ActionLabelsI18n, private router: Router, - private modalService: ModalService, + private modalService: ModalCdsService, private authStorageService: AuthStorageService, private taskWrapper: TaskWrapperService, private nvmeofService: NvmeofService, diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.html index 7c175d0713e..fc2fbdff63e 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-details/rbd-details.component.html @@ -11,44 +11,47 @@ Details - +
- + + class="bold w-25" + cdstabledata>Name - + + class="bold" + cdstabledata>Pool - + - + - + - + - + - + - + - + - + - + - + - + - + - + diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.html index d72d2ad8e8c..8f15dfddf1e 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.html @@ -37,14 +37,14 @@ - {{ value[0] }}  - {{ value[1] }}  - primary - secondary diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.ts index 86d0978c163..1a4bb4e0cf8 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.ts @@ -77,7 +77,7 @@ export class RbdListComponent extends ListWithDetails implements OnInit { images: any; columns: CdTableColumn[]; retries: number; - tableStatus = new TableStatus('light'); + tableStatus = new TableStatus('ghost'); selection = new CdTableSelection(); icons = Icons; count = 0; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html index 13bb16c9cea..8bcb15fb1d9 100755 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/configuration/configuration-details/configuration-details.component.html @@ -1,5 +1,6 @@ -
Name {{ selection.name }}
Pool {{ selection.pool_name }}
Data Pool {{ selection.data_pool | empty }}
Created {{ selection.timestamp | cdDate }}
Size {{ selection.size | dimlessBinary }}
Objects {{ selection.num_objs | dimless }}
Object size {{ selection.obj_size | dimlessBinary }}
Features @@ -57,7 +60,7 @@
Provisioned @@ -72,7 +75,7 @@
Total provisioned @@ -87,17 +90,17 @@
Striping unit {{ selection.stripe_unit | dimlessBinary }}
Striping count {{ selection.stripe_count }}
Parent @@ -106,17 +109,17 @@ -
Block name prefix {{ selection.block_name_prefix }}
Order {{ selection.order }}
Format Version {{ selection.image_format }}
+
Cluster Resources - +
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.html index c9dbf9cc599..9a92cfe04ee 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/monitor/monitor.component.html @@ -3,7 +3,7 @@
Status -
Hosts
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.html index 6ee60716bd8..a9961f72ff6 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/multi-cluster/multi-cluster-list/multi-cluster-list.component.html @@ -38,15 +38,13 @@ (setExpandedRow)="setExpandedRow($event)" [maxLimit]="25" (updateSelection)="updateSelection($event)"> -
- - -
- + + diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.ts index a37cca34014..9602c856aed 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.ts @@ -195,7 +195,12 @@ export class ServiceFormComponent extends CdForm implements OnInit { }) ] ], - group: [null, Validators.required], + group: [ + null, + CdValidators.requiredIf({ + service_type: 'nvmeof' + }) + ], // RGW rgw_frontend_port: [null, [CdValidators.number(false)]], realm_name: [null], diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html index 74b3e953b52..31c54e59ebf 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-bucket-details/rgw-bucket-details.component.html @@ -8,7 +8,8 @@ i18n>Details -
+
Bucket quota - +
Locking - +
Tags - +
Policies
- +
{ this.activeModal.close(); - this.router.routeReuseStrategy.shouldReuseRoute = () => false; - this.router.onSameUrlNavigation = 'reload'; - this.router.navigate([this.router.url]); + this.table?.refreshBtn(); } }); } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-configuration-page/rgw-configuration-page.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-configuration-page/rgw-configuration-page.component.html index 1a740f3461c..a6b3e3287c5 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-configuration-page/rgw-configuration-page.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-configuration-page/rgw-configuration-page.component.html @@ -8,6 +8,7 @@ { - this.allEncryptionValues = data; - const allowedBackends = rgwBucketEncryptionModel.kmsProviders; - - const kmsBackends = this.getBackend(data, 'SSE_KMS'); - const s3Backends = this.getBackend(data, 'SSE_S3'); - - const allKmsBackendsPresent = this.areAllAllowedBackendsPresent(allowedBackends, kmsBackends); - const allS3BackendsPresent = this.areAllAllowedBackendsPresent(allowedBackends, s3Backends); - - this.disableCreate = allKmsBackendsPresent && allS3BackendsPresent; - this.encryptionConfigValues = Object.values(data).flat(); - }); - this.excludeProps = this.columns.map((column) => column.prop); this.excludeProps.push('unique_id'); } @@ -122,7 +111,8 @@ export class RgwConfigurationPageComponent extends ListWithDetails implements On const initialState = { action: 'edit', editing: true, - selectedEncryptionConfigValues: this.selection.first() + selectedEncryptionConfigValues: this.selection.first(), + table: this.table }; this.bsModalRef = this.modalService.show(RgwConfigModalComponent, initialState, { size: 'lg' @@ -145,4 +135,20 @@ export class RgwConfigurationPageComponent extends ListWithDetails implements On setExpandedRow(expandedRow: any) { super.setExpandedRow(expandedRow); } + + fetchData() { + this.rgwBucketService.getEncryptionConfig().subscribe((data: any) => { + this.allEncryptionValues = data; + const allowedBackends = rgwBucketEncryptionModel.kmsProviders; + + const kmsBackends = this.getBackend(data, 'SSE_KMS'); + const s3Backends = this.getBackend(data, 'SSE_S3'); + + const allKmsBackendsPresent = this.areAllAllowedBackendsPresent(allowedBackends, kmsBackends); + const allS3BackendsPresent = this.areAllAllowedBackendsPresent(allowedBackends, s3Backends); + + this.disableCreate = allKmsBackendsPresent && allS3BackendsPresent; + this.encryptionConfigValues = Object.values(data).flat(); + }); + } } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-multisite-details/rgw-multisite-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-multisite-details/rgw-multisite-details.component.html index d0b2c2105d1..9476368f3e7 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-multisite-details/rgw-multisite-details.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-multisite-details/rgw-multisite-details.component.html @@ -21,7 +21,8 @@ + [tableActions]="createTableActions" + [primaryDropDown]="true"> @@ -114,8 +115,7 @@ *ngIf="metadata"> {{ metadataTitle }}
- +
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html index 49aff08e387..a66b6354db0 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.html @@ -2,31 +2,21 @@
Keys -
- -
-
- -
-
-
-
+ + +
Details - +
User quota - +
Bucket quota - +
{ fixture.detectChanges(); const detailsTab = fixture.debugElement.nativeElement.querySelectorAll( - '.table.table-striped.table-bordered tr td' + '.cds--data-table--sort.cds--data-table--no-border tr td' ); expect(detailsTab[10].textContent).toEqual('System user'); expect(detailsTab[11].textContent).toEqual('Yes'); @@ -61,7 +61,7 @@ describe('RgwUserDetailsComponent', () => { fixture.detectChanges(); const detailsTab = fixture.debugElement.nativeElement.querySelectorAll( - '.table.table-striped.table-bordered tr td' + '.cds--data-table--sort.cds--data-table--no-border tr td' ); expect(detailsTab[14].textContent).toEqual('MFAs(Id)'); expect(detailsTab[15].textContent).toEqual('testMFA1, testMFA2'); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts index 2c4a926120b..acb85a1a43a 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/rgw/rgw-user-details/rgw-user-details.component.ts @@ -11,6 +11,8 @@ import { RgwUserS3Key } from '../models/rgw-user-s3-key'; import { RgwUserSwiftKey } from '../models/rgw-user-swift-key'; import { RgwUserS3KeyModalComponent } from '../rgw-user-s3-key-modal/rgw-user-s3-key-modal.component'; import { RgwUserSwiftKeyModalComponent } from '../rgw-user-swift-key-modal/rgw-user-swift-key-modal.component'; +import { CdTableAction } from '~/app/shared/models/cd-table-action'; +import { Permissions } from '~/app/shared/models/permissions'; @Component({ selector: 'cd-rgw-user-details', @@ -34,6 +36,8 @@ export class RgwUserDetailsComponent implements OnChanges, OnInit { keys: any = []; keysColumns: CdTableColumn[] = []; keysSelection: CdTableSelection = new CdTableSelection(); + tableAction: CdTableAction[] = []; + permissions: Permissions; icons = Icons; @@ -59,6 +63,15 @@ export class RgwUserDetailsComponent implements OnChanges, OnInit { } ngOnChanges() { + this.tableAction = [ + { + name: $localize`Show`, + permission: 'read', + click: () => this.showKeyModal(), + icon: Icons.show + } + ]; + if (this.selection) { this.user = this.selection; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/list-with-details.class.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/list-with-details.class.ts index 2eaeeb35eec..b546a75b74e 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/list-with-details.class.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/list-with-details.class.ts @@ -19,7 +19,7 @@ export class ListWithDetails { this.staleTimeout = window.setTimeout(() => { this.ngZone.run(() => { this.tableStatus = new TableStatus( - 'warning', + 'secondary', $localize`The user list data might be stale. If needed, you can manually reload it.` ); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status-view-cache.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status-view-cache.spec.ts index cff2ec33a02..1dc089199a0 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status-view-cache.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status-view-cache.spec.ts @@ -5,23 +5,26 @@ describe('TableStatusViewCache', () => { it('should create an instance', () => { const ts = new TableStatusViewCache(); expect(ts).toBeTruthy(); - expect(ts).toEqual({ msg: '', type: 'light' }); + expect(ts).toEqual({ msg: '', type: 'ghost' }); }); it('should create a ValueStale instance', () => { let ts = new TableStatusViewCache(ViewCacheStatus.ValueStale); - expect(ts).toEqual({ type: 'warning', msg: 'Displaying previously cached data.' }); + expect(ts).toEqual({ type: 'secondary', msg: 'Displaying previously cached data.' }); ts = new TableStatusViewCache(ViewCacheStatus.ValueStale, 'foo bar'); - expect(ts).toEqual({ type: 'warning', msg: 'Displaying previously cached data for foo bar.' }); + expect(ts).toEqual({ + type: 'secondary', + msg: 'Displaying previously cached data for foo bar.' + }); }); it('should create a ValueNone instance', () => { let ts = new TableStatusViewCache(ViewCacheStatus.ValueNone); - expect(ts).toEqual({ type: 'info', msg: 'Retrieving data. Please wait...' }); + expect(ts).toEqual({ type: 'primary', msg: 'Retrieving data. Please wait...' }); ts = new TableStatusViewCache(ViewCacheStatus.ValueNone, 'foo bar'); - expect(ts).toEqual({ type: 'info', msg: 'Retrieving data for foo bar. Please wait...' }); + expect(ts).toEqual({ type: 'primary', msg: 'Retrieving data for foo bar. Please wait...' }); }); it('should create a ValueException instance', () => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status-view-cache.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status-view-cache.ts index 91c53a0aa06..e296b974785 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status-view-cache.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status-view-cache.ts @@ -7,18 +7,18 @@ export class TableStatusViewCache extends TableStatus { switch (status) { case ViewCacheStatus.ValueOk: - this.type = 'light'; + this.type = 'ghost'; this.msg = ''; break; case ViewCacheStatus.ValueNone: - this.type = 'info'; + this.type = 'primary'; this.msg = (statusFor ? $localize`Retrieving data for ${statusFor}.` : $localize`Retrieving data.`) + ' ' + $localize`Please wait...`; break; case ViewCacheStatus.ValueStale: - this.type = 'warning'; + this.type = 'secondary'; this.msg = statusFor ? $localize`Displaying previously cached data for ${statusFor}.` : $localize`Displaying previously cached data.`; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status.spec.ts index 7fa7ba1a4ad..77deb54f25d 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status.spec.ts @@ -4,7 +4,7 @@ describe('TableStatus', () => { it('should create an instance', () => { const ts = new TableStatus(); expect(ts).toBeTruthy(); - expect(ts).toEqual({ msg: '', type: 'light' }); + expect(ts).toEqual({ msg: '', type: 'ghost' }); }); it('should create with parameters', () => { diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status.ts index fa9be80fef7..982453d2a33 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/table-status.ts @@ -1,3 +1,6 @@ export class TableStatus { - constructor(public type: 'info' | 'warning' | 'danger' | 'light' = 'light', public msg = '') {} + constructor( + public type: 'primary' | 'secondary' | 'danger' | 'ghost' = 'ghost', + public msg = '' + ) {} } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/crud-table/crud-table.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/crud-table/crud-table.component.html index 73e4a307cfc..e5401c70d15 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/crud-table/crud-table.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/crud-table/crud-table.component.html @@ -31,7 +31,7 @@ + class="cds--data-table--sort cds--data-table--no-border cds--data-table cds--data-table--md"> - - - -
+ + + + + + {{ action.name }} + + + + + + + - +
+ + [attr.colspan]="selectionType === 'single' ? visibleColumns.length + 1 : visibleColumns.length + 2"> No data to display
+